def select_autoconnect_names(args): want_v4 = args.af.index(socket.AF_INET) if socket.AF_INET in args.af else -1 want_v6 = args.af.index(socket.AF_INET6) if socket.AF_INET6 in args.af else -1 if want_v4 >= 0: if want_v6 == -1: filter_ = lambda addrinfo_list: [addrinfo for addrinfo in addrinfo_list if addrinfo[0] == socket.AF_INET] filter_name = "IPv4" # both -4 and -6 specified: sort list based on preference (we assume that the option specified first has higher priority) elif want_v4 < want_v6: filter_ = lambda addrinfo_list: sorted(addrinfo_list, key=lambda addrinfo: addrinfo[0] == socket.AF_INET6) else: filter_ = lambda addrinfo_list: sorted(addrinfo_list, key=lambda addrinfo: addrinfo[0] == socket.AF_INET) else: filter_ = lambda addrinfo_list: [addrinfo for addrinfo in addrinfo_list if addrinfo[0] == socket.AF_INET6] filter_name = "IPv6" error = False result = [] for host, addrinfo_list in args.autoConnect or (): addrinfo_list[:] = filter_(addrinfo_list) if not addrinfo_list: log("cannot connect to %s with %s" % (host, filter_name)) error = True else: ai = addrinfo_list[0] if want_v6 >= 0 and ai[0] == socket.AF_INET: # we'll be using an IPv6 socket to contact an IPv4 host, embed IPv4 in v6 address with ::ffff:/96 prefix result.append(addrtuple_to_name(socket.AF_INET6, ("::ffff:" + ai[4][0], ai[4][1], 0, 0))) else: result.append(addrtuple_to_name(ai[0], ai[4])) if error: raise SystemExit(1) return result
def recvmmsg(events, s, dsock, fd=s.fileno(), mmsg=MMsgHdr()): n = mmsg.recv(fd) if n > 0: for i in range(n): dsock.recvmsg(mmsg.iov[i].iov_base, mmsg.msgvec[i].msg_len, mmsg.name + i, mmsg.msgvec[i].msg_hdr.msg_namelen) mmsg.reinit(n) elif n < 0: log("RECVMMSG(%d, %r, 0) = %d" % (fd, n)) else: raise ValueError("EOF")
def recvmmsg(events, dsock, fd, mmsg): n = mmsg.recv(fd) if n > 0: for i in range(n): #print("RECVMSG %r" % (mmsg.msgvec[i].msg_len,)) dsock.recvmsg(mmsg.iov[i].iov_base, mmsg.msgvec[i].msg_len, mmsg.name + i, mmsg.msgvec[i].msg_hdr.msg_namelen) mmsg.reinit(n) elif n < 0: log("RECVMMSG(%d, %r, 0) = %d" % (fd, n)) else: raise Exception("EOF")
def read(events, dsock, tap, connections): n = tap.read() if not n: raise Exception("read 0 from tap") try: connections[0].send(tap.buf, n) except (NotConnected, HandshakeInProgress, IndexError): log("discarding message - not connected") except GNUTLSError as e: if e.errno in (GNUTLS_E_LARGE_PACKET, GNUTLS_E_MEMORY_ERROR): # TODO: should maybe fragment packet or return ICMP? pass else: raise
def select_autoconnect_names(args): want_v4 = args.af.index( socket.AF_INET) if socket.AF_INET in args.af else -1 want_v6 = args.af.index( socket.AF_INET6) if socket.AF_INET6 in args.af else -1 if want_v4 >= 0: if want_v6 == -1: filter_ = lambda addrinfo_list: [ addrinfo for addrinfo in addrinfo_list if addrinfo[0] == socket.AF_INET ] filter_name = "IPv4" # both -4 and -6 specified: sort list based on preference (we assume that the option specified first has higher priority) elif want_v4 < want_v6: filter_ = lambda addrinfo_list: sorted( addrinfo_list, key=lambda addrinfo: addrinfo[0] == socket.AF_INET6) else: filter_ = lambda addrinfo_list: sorted( addrinfo_list, key=lambda addrinfo: addrinfo[0] == socket.AF_INET) else: filter_ = lambda addrinfo_list: [ addrinfo for addrinfo in addrinfo_list if addrinfo[0] == socket.AF_INET6 ] filter_name = "IPv6" error = False result = [] for host, addrinfo_list in args.autoConnect or (): addrinfo_list[:] = filter_(addrinfo_list) if not addrinfo_list: log("cannot connect to %s with %s" % (host, filter_name)) error = True else: ai = addrinfo_list[0] if want_v6 >= 0 and ai[0] == socket.AF_INET: # we'll be using an IPv6 socket to contact an IPv4 host, embed IPv4 in v6 address with ::ffff:/96 prefix result.append( addrtuple_to_name(socket.AF_INET6, ("::ffff:" + ai[4][0], ai[4][1], 0, 0))) else: result.append(addrtuple_to_name(ai[0], ai[4])) if error: raise SystemExit(1) return result
def up(args, tap): if not args.up: return connect = [] for name in args.autoConnect: addr = name_to_addrtuple(name) if addr[0].startswith("::ffff:"): connect.append(addr[0][7:]) else: connect.append(addr[0]) connect.append(str(addr[1])) rc = subprocess.Popen([args.up] + connect, env={"DEVICE_NAME": tap.name}).wait() if rc: log("error invoking up script: %d" % (rc,))
def up(args, tap): if not args.up: return connect = [] for name in args.autoConnect: addr = name_to_addrtuple(name) if addr[0].startswith("::ffff:"): connect.append(addr[0][7:]) else: connect.append(addr[0]) connect.append(str(addr[1])) rc = subprocess.Popen([args.up] + connect, env={ "DEVICE_NAME": tap.name }).wait() if rc: log("error invoking up script: %d" % (rc, ))
def ping(_, name): global last try: if clock() >= stat[2] + 1: log("%r; %.3f kB/s sent, %.3f kB/s recv" % (stat, (stat[0]-last[0])/1000.0, (stat[1]-last[1])/1000.0)) stat[2] += 1 last = list(stat) for _ in range(100): dsock.sendto(PAYLOAD_BUFFER, PAYLOAD_SIZE, name) stat[0] += PAYLOAD_SIZE reactor.deferIdle(ping, None, name) except HandshakeInProgress: log("handshake in progress") reactor.scheduleMonotonic(clock() + INTERVAL, ping, name) except NotConnected: log("not connected - connecting") dsock.connect(name) reactor.scheduleMonotonic(clock() + INTERVAL, ping, name)
def sendmsg(fd, msg): #print("SENDMSG %r(%r) to %r" % (msg, msg.msg_iov[0].iov_len, name_to_addrtuple(ffi.buffer(msg.msg_name, msg.msg_namelen)[:]))) res = lib.sendmsg(fd, msg, 0) if res < 0: log("SENDMSG(%d, %r, 0) = %d" % (fd, msg, res)) return res
def gone(self, conn): log("gone: %r" % (conn, )) if conn in self.connections: self.connections.remove(conn) if conn.name in self.autoConnect: conn.sock.connect(conn.name)
def connected(self, conn): log("connected: %r" % (conn, )) if conn not in self.connections: self.connections.append(conn)
def handshake(self, conn): log("handshake: %r" % (conn, )) if conn in self.connections: self.connections.remove(conn)
def gone(self, conn): log("gone: %r" % (conn,)) if conn in self.connections: self.connections.remove(conn) if conn.name in self.autoConnect: conn.sock.connect(conn.name)
def connected(self, conn): log("connected: %r" % (conn,)) if conn not in self.connections: self.connections.append(conn)
def gone(self, conn): log("gone: %r" % (conn,))
def connected(self, conn): log("connected: %r" % (conn,))
def handshake(self, conn): log("handshake: %r" % (conn,))
def handshake(self, conn): log("handshake: %r" % (conn,)) if conn in self.connections: self.connections.remove(conn)
def sendmsg(msg, fd=s.fileno()): res = lib.sendmsg(fd, msg, 0) if res < 0: log("SENDMSG(%d, %r, 0) = %d" % (fd, msg, res)) return res