def connect(self): try: connection = self.makesocket() if self.spoof_source_address: try: # 19 is `IP_TRANSPARENT`, which is only available on Python 3.3+ on some OSes if not connection.getsockopt(socket.SOL_IP, 19): connection.setsockopt(socket.SOL_IP, 19, 1) except socket.error as e: raise exceptions.TcpException( "Failed to spoof the source address: " + e.strerror ) if self.source_address: connection.bind(self.source_address()) connection.connect(self.address()) self.source_address = Address(connection.getsockname()) except (socket.error, IOError) as err: raise exceptions.TcpException( 'Error connecting to "%s": %s' % (self.address.host, err) ) self.connection = connection self.ip_address = Address(connection.getpeername()) self._makefile() return ConnectionCloser(self)
def connect(self): try: connection = self.create_connection() except (socket.error, IOError) as err: raise exceptions.TcpException('Error connecting to "%s": %s' % (self.address[0], err)) self.connection = connection self.source_address = connection.getsockname() self.ip_address = connection.getpeername() self._makefile() return ConnectionCloser(self)
def create_connection(self, timeout=None): # Based on the official socket.create_connection implementation of Python 3.6. # https://github.com/python/cpython/blob/3cc5817cfaf5663645f4ee447eaed603d2ad290a/Lib/socket.py err = None idle_timeout = self.connection_idle_seconds if idle_timeout != -1: timeout = idle_timeout for res in socket.getaddrinfo(self.address[0], self.address[1], 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res sock = None try: sock = self.makesocket(af, socktype, proto) if timeout: sock.settimeout(timeout) if self.source_address: sock.bind(self.source_address) if self.spoof_source_address: try: if not sock.getsockopt(socket.SOL_IP, socket.IP_TRANSPARENT): sock.setsockopt( socket.SOL_IP, socket.IP_TRANSPARENT, 1 ) # pragma: windows no cover pragma: osx no cover except Exception as e: # socket.IP_TRANSPARENT might not be available on every OS and Python version if sock is not None: sock.close() raise exceptions.TcpException( "Failed to spoof the source address: " + str(e)) sock.connect(sa) return sock except socket.error as _: err = _ self.ip_address = sa if sock is not None: sock.close() if err is not None: raise err else: raise socket.error( "getaddrinfo returns an empty list") # pragma: no cover
def connect(self, flow=None): try: if self.channel is not None and flow is not None: self.channel.ask("tcp_resolving_server_address_started", flow) connection = self.create_connection() if self.dns_resolving_delay_ms > 0: time.sleep(self.dns_resolving_delay_ms / 1000) except (socket.error, IOError) as err: raise exceptions.TcpException('Error connecting to "%s": %s' % (self.address[0], err)) from err finally: if self.channel is not None and flow is not None: self.channel.ask("tcp_resolving_server_address_finished", flow) self.connection = connection self.source_address = connection.getsockname() self.ip_address = connection.getpeername() self._makefile() return ConnectionCloser(self)
def create_connection(self, timeout=None): # Based on the official socket.create_connection implementation of Python 3.6. # https://github.com/python/cpython/blob/3cc5817cfaf5663645f4ee447eaed603d2ad290a/Lib/socket.py err = None for res in socket.getaddrinfo(self.address[0], self.address[1], 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res host = sa[0] if not ip_address(host).is_global: raise exceptions.NonGlobalAddressException("The address %s is not a global address" % host) try: sock = self.makesocket(af, socktype, proto) if timeout: sock.settimeout(timeout) if self.source_address: sock.bind(self.source_address) if self.spoof_source_address: try: if not sock.getsockopt(socket.SOL_IP, socket.IP_TRANSPARENT): sock.setsockopt(socket.SOL_IP, socket.IP_TRANSPARENT, 1) except Exception as e: # socket.IP_TRANSPARENT might not be available on every OS and Python version raise exceptions.TcpException( "Failed to spoof the source address: " + e.strerror ) sock.connect(sa) return sock except socket.error as _: err = _ if sock is not None: sock.close() if err is not None: raise err else: raise socket.error("getaddrinfo returns an empty list")
def peek(self, length): """ Tries to peek into the underlying file object. Returns: Up to the next N bytes if peeking is successful. Raises: exceptions.TcpException if there was an error with the socket TlsException if there was an error with pyOpenSSL. NotImplementedError if the underlying file object is not a [pyOpenSSL] socket """ if isinstance(self.o, socket_fileobject): try: return self.o._sock.recv(length, socket.MSG_PEEK) except socket.error as e: raise exceptions.TcpException(repr(e)) elif isinstance(self.o, SSL.Connection): try: return self.o.recv(length, socket.MSG_PEEK) except SSL.Error as e: raise exceptions.TlsException(str(e)) else: raise NotImplementedError("Can only peek into (pyOpenSSL) sockets")