def __try_to_connect_to_address(self, connect_info: TCPConnectInfo): address = connect_info.socket_addresses[0].address port = connect_info.socket_addresses[0].port logger.debug("Connection to host %r: %r", address, port) use_ipv6 = connect_info.socket_addresses[0].ipv6 use_hostname = connect_info.socket_addresses[0].hostname if use_ipv6: endpoint = TCP6ClientEndpoint(self.reactor, address, port, self.timeout) elif use_hostname: endpoint = HostnameEndpoint(self.reactor, address, port, self.timeout) else: endpoint = TCP4ClientEndpoint(self.reactor, address, port, self.timeout) defer = endpoint.connect(self.outgoing_protocol_factory) defer.addCallback(self.__connection_established, self.__connection_to_address_established, connect_info) defer.addErrback(self.__connection_failure, self.__connection_to_address_failure, connect_info)
def _getEndpoint(self, uri): try: return super(Agent6, self)._getEndpoint(uri) except SchemeNotSupported: if uri.scheme == 'http6': return TCP6ClientEndpoint(self._reactor, uri.host, uri.port) else: raise
def __try_to_connect_to_address(self, address, port, established_callback, failure_callback, **kwargs): logger.debug("Connection to host {}: {}".format(address, port)) use_ipv6 = False try: ip = ip_address(address.decode()) use_ipv6 = ip.version == 6 except ValueError: logger.warning("{} address is invalid".format(address)) if use_ipv6: endpoint = TCP6ClientEndpoint(self.reactor, address, port, self.timeout) else: endpoint = TCP4ClientEndpoint(self.reactor, address, port, self.timeout) defer = endpoint.connect(self.protocol_factory) defer.addCallback(self.__connection_established, established_callback, **kwargs) defer.addErrback(self.__connection_failure, failure_callback, **kwargs)
def endpoint_from_hint_obj(hint, tor, reactor): if tor: if isinstance(hint, (DirectTCPV1Hint, TorTCPV1Hint)): # this Tor object will throw ValueError for non-public IPv4 # addresses and any IPv6 address try: return tor.stream_via(hint.hostname, hint.port) except ValueError: return None return None if isinstance(hint, DirectTCPV1Hint): # avoid DNS lookup unless necessary if isIPAddress(hint.hostname): return TCP4ClientEndpoint(reactor, hint.hostname, hint.port) if isIPv6Address(hint.hostname): return TCP6ClientEndpoint(reactor, hint.hostname, hint.port) return HostnameEndpoint(reactor, hint.hostname, hint.port) return None
def __init__( self, host: str, port: int, maximum_buffer: int = 1000, level=logging.NOTSET, _reactor=None, ): super().__init__(level=level) self.host = host self.port = port self.maximum_buffer = maximum_buffer self._buffer = deque() # type: Deque[logging.LogRecord] self._connection_waiter = None # type: Optional[Deferred] self._producer = None # type: Optional[LogProducer] # Connect without DNS lookups if it's a direct IP. if _reactor is None: from twisted.internet import reactor _reactor = reactor try: ip = ip_address(self.host) if isinstance(ip, IPv4Address): endpoint = TCP4ClientEndpoint( _reactor, self.host, self.port) # type: IStreamClientEndpoint elif isinstance(ip, IPv6Address): endpoint = TCP6ClientEndpoint(_reactor, self.host, self.port) else: raise ValueError("Unknown IP address provided: %s" % (self.host, )) except ValueError: endpoint = HostnameEndpoint(_reactor, self.host, self.port) factory = Factory.forProtocol(Protocol) self._service = ClientService(endpoint, factory, clock=_reactor) self._service.startService() self._stopping = False self._connect()
def start(self) -> None: # Connect without DNS lookups if it's a direct IP. try: ip = ip_address(self.host) if isinstance(ip, IPv4Address): endpoint = TCP4ClientEndpoint( self.hs.get_reactor(), self.host, self.port ) elif isinstance(ip, IPv6Address): endpoint = TCP6ClientEndpoint( self.hs.get_reactor(), self.host, self.port ) except ValueError: endpoint = HostnameEndpoint(self.hs.get_reactor(), self.host, self.port) factory = Factory.forProtocol(Protocol) self._service = ClientService(endpoint, factory, clock=self.hs.get_reactor()) self._service.startService() self._connect()
def check(virtual, real, global_config): port = virtual.checkport if virtual.checkport else real.port if isinstance(virtual, Virtual4): point = TCP4ClientEndpoint(reactor, real.ip.exploded, port, timeout=virtual.checktimeout) elif isinstance(virtual, Virtual6): point = TCP6ClientEndpoint(reactor, real.ip.exploded, port, timeout=virtual.checktimeout) else: global_config.log.critical( "Not a valid Virtual4/Virtual6 service. This should not happen!") sys.exit(1) d = point.connect(_DummyFactory()) d.addCallback(__cb_connection_established) return d
def _create_transport_endpoint(reactor, endpoint_config): """ Create a Twisted client endpoint for a WAMP-over-XXX transport. """ if IStreamClientEndpoint.providedBy(endpoint_config): endpoint = IStreamClientEndpoint(endpoint_config) else: # create a connecting TCP socket if endpoint_config['type'] == 'tcp': version = int(endpoint_config.get('version', 4)) host = str(endpoint_config['host']) port = int(endpoint_config['port']) timeout = int(endpoint_config.get('timeout', 10)) # in seconds tls = endpoint_config.get('tls', None) # create a TLS enabled connecting TCP socket if tls: if not _TLS: raise RuntimeError( 'TLS configured in transport, but TLS support is not installed (eg OpenSSL?)' ) # FIXME: create TLS context from configuration if IOpenSSLClientConnectionCreator.providedBy(tls): # eg created from twisted.internet.ssl.optionsForClientTLS() context = IOpenSSLClientConnectionCreator(tls) elif isinstance(tls, CertificateOptions): context = tls elif tls is True: context = optionsForClientTLS(host) else: raise RuntimeError( 'unknown type {} for "tls" configuration in transport'. format(type(tls))) if version == 4: endpoint = SSL4ClientEndpoint(reactor, host, port, context, timeout=timeout) elif version == 6: # there is no SSL6ClientEndpoint! raise RuntimeError('TLS on IPv6 not implemented') else: assert (False), 'should not arrive here' # create a non-TLS connecting TCP socket else: if version == 4: endpoint = TCP4ClientEndpoint(reactor, host, port, timeout=timeout) elif version == 6: try: from twisted.internet.endpoints import TCP6ClientEndpoint except ImportError: raise RuntimeError( 'IPv6 is not supported (please upgrade Twisted)') endpoint = TCP6ClientEndpoint(reactor, host, port, timeout=timeout) else: assert (False), 'should not arrive here' # create a connecting Unix domain socket elif endpoint_config['type'] == 'unix': path = endpoint_config['path'] timeout = int(endpoint_config.get('timeout', 10)) # in seconds endpoint = UNIXClientEndpoint(reactor, path, timeout=timeout) else: assert (False), 'should not arrive here' return endpoint
def create_connecting_endpoint_from_config(config, cbdir, reactor, log): """ Create a Twisted stream client endpoint from a Crossbar.io transport configuration. See: https://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.IStreamClientEndpoint.html :param config: The transport configuration. :type config: dict :param cbdir: Crossbar.io node directory (we need this for Unix domain socket paths and TLS key/certificates). :type cbdir: str :param reactor: The reactor to use for endpoint creation. :type reactor: obj :returns obj -- An instance implementing IStreamClientEndpoint """ endpoint = None # a TCP endpoint # if config['type'] == 'tcp': # the TCP protocol version (v4 or v6) # version = int(config.get('version', 4)) # the host to connect to # host = str(config['host']) # the port to connect to # port = int(config['port']) # connection timeout in seconds # timeout = int(config.get('timeout', 10)) if 'tls' in config: # create a TLS client endpoint # if _HAS_TLS: # TLS client context context = _create_tls_client_context(config['tls'], cbdir, log) if version == 4: endpoint = SSL4ClientEndpoint( reactor, host, port, context, timeout=timeout, ) elif version == 6: raise Exception("TLS on IPv6 not implemented") else: raise Exception( "invalid TCP protocol version {}".format(version)) else: raise Exception( "TLS transport requested, but TLS packages not available:\n{}" .format(_LACKS_TLS_MSG)) else: # create a non-TLS client endpoint # if version == 4: endpoint = TCP4ClientEndpoint(reactor, host, port, timeout=timeout) elif version == 6: endpoint = TCP6ClientEndpoint(reactor, host, port, timeout=timeout) else: raise Exception( "invalid TCP protocol version {}".format(version)) # a Unix Domain Socket endpoint # elif config['type'] == 'unix': # the path # path = abspath(join(cbdir, config['path'])) # connection timeout in seconds # timeout = int(config.get('timeout', 10)) # create the endpoint # endpoint = UNIXClientEndpoint(reactor, path, timeout=timeout) elif config['type'] == 'twisted': endpoint = clientFromString(reactor, config['client_string']) elif config['type'] == 'tor': host = config['host'] port = config['port'] socks_port = config['tor_socks_port'] tls = config.get('tls', False) if not tls and not host.endswith('.onion'): log.warn( "Non-TLS connection traversing Tor network; end-to-end encryption advised" ) socks_endpoint = TCP4ClientEndpoint( reactor, "127.0.0.1", socks_port, ) endpoint = txtorcon.TorClientEndpoint( host, port, socks_endpoint=socks_endpoint, reactor=reactor, use_tls=tls, ) else: raise Exception("invalid endpoint type '{}'".format(config['type'])) return endpoint
def _create_transport_endpoint(reactor, endpoint_config): """ Create a Twisted client endpoint for a WAMP-over-XXX transport. """ if IStreamClientEndpoint.providedBy(endpoint_config): endpoint = IStreamClientEndpoint(endpoint_config) else: # create a connecting TCP socket if endpoint_config[u'type'] == u'tcp': version = endpoint_config.get(u'version', 4) if version not in [4, 6]: raise ValueError( 'invalid IP version {} in client endpoint configuration'. format(version)) host = endpoint_config[u'host'] if type(host) != six.text_type: raise ValueError( 'invalid type {} for host in client endpoint configuration' .format(type(host))) port = endpoint_config[u'port'] if type(port) not in six.integer_types: raise ValueError( 'invalid type {} for port in client endpoint configuration' .format(type(port))) timeout = endpoint_config.get(u'timeout', 10) # in seconds if type(timeout) not in six.integer_types: raise ValueError( 'invalid type {} for timeout in client endpoint configuration' .format(type(timeout))) tls = endpoint_config.get(u'tls', None) # create a TLS enabled connecting TCP socket if tls: if not _TLS: raise RuntimeError( 'TLS configured in transport, but TLS support is not installed (eg OpenSSL?)' ) # FIXME: create TLS context from configuration if IOpenSSLClientConnectionCreator.providedBy(tls): # eg created from twisted.internet.ssl.optionsForClientTLS() context = IOpenSSLClientConnectionCreator(tls) elif isinstance(tls, dict): for k in tls.keys(): if k not in [u"hostname", u"trust_root"]: raise ValueError( "Invalid key '{}' in 'tls' config".format(k)) hostname = tls.get(u'hostname', host) if type(hostname) != six.text_type: raise ValueError( 'invalid type {} for hostname in TLS client endpoint configuration' .format(hostname)) trust_root = None cert_fname = tls.get(u"trust_root", None) if cert_fname is not None: trust_root = Certificate.loadPEM( six.u(open(cert_fname, 'r').read())) context = optionsForClientTLS(hostname, trustRoot=trust_root) elif isinstance(tls, CertificateOptions): context = tls elif tls is True: context = optionsForClientTLS(host) else: raise RuntimeError( 'unknown type {} for "tls" configuration in transport'. format(type(tls))) if version == 4: endpoint = SSL4ClientEndpoint(reactor, host, port, context, timeout=timeout) elif version == 6: # there is no SSL6ClientEndpoint! raise RuntimeError('TLS on IPv6 not implemented') else: assert (False), 'should not arrive here' # create a non-TLS connecting TCP socket else: if version == 4: endpoint = TCP4ClientEndpoint(reactor, host, port, timeout=timeout) elif version == 6: try: from twisted.internet.endpoints import TCP6ClientEndpoint except ImportError: raise RuntimeError( 'IPv6 is not supported (please upgrade Twisted)') endpoint = TCP6ClientEndpoint(reactor, host, port, timeout=timeout) else: assert (False), 'should not arrive here' # create a connecting Unix domain socket elif endpoint_config[u'type'] == u'unix': path = endpoint_config[u'path'] timeout = int(endpoint_config.get(u'timeout', 10)) # in seconds endpoint = UNIXClientEndpoint(reactor, path, timeout=timeout) else: assert (False), 'should not arrive here' return endpoint
def create_connecting_endpoint_from_config(config, cbdir, reactor): """ Create a Twisted stream client endpoint from a Crossbar.io transport configuration. See: https://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.IStreamClientEndpoint.html :param config: The transport configuration. :type config: dict :param cbdir: Crossbar.io node directory (we need this for Unix domain socket paths and TLS key/certificates). :type cbdir: str :param reactor: The reactor to use for endpoint creation. :type reactor: obj :returns obj -- An instance implementing IStreamClientEndpoint """ endpoint = None # a TCP endpoint # if config['type'] == 'tcp': # the TCP protocol version (v4 or v6) # version = int(config.get('version', 4)) # the host to connect to # host = str(config['host']) # the port to connect to # port = int(config['port']) # connection timeout in seconds # timeout = int(config.get('timeout', 10)) if 'tls' in config: if _HAS_TLS: ctx = TlsClientContextFactory() # create a TLS client endpoint # if version == 4: endpoint = SSL4ClientEndpoint(reactor, host, port, ctx, timeout=timeout) elif version == 6: raise Exception("TLS on IPv6 not implemented") else: raise Exception( "invalid TCP protocol version {}".format(version)) else: raise Exception( "TLS transport requested, but TLS packages not available") else: # create a non-TLS client endpoint # if version == 4: endpoint = TCP4ClientEndpoint(reactor, host, port, timeout=timeout) elif version == 6: endpoint = TCP6ClientEndpoint(reactor, host, port, timeout=timeout) else: raise Exception( "invalid TCP protocol version {}".format(version)) # a Unix Domain Socket endpoint # elif config['type'] == 'unix': # the path # path = os.path.abspath(os.path.join(cbdir, config['path'])) # connection timeout in seconds # timeout = int(config.get('timeout', 10)) # create the endpoint # endpoint = UNIXClientEndpoint(reactor, path, timeout=timeout) else: raise Exception("invalid endpoint type '{}'".format(config['type'])) return endpoint
def create_connecting_endpoint_from_config(config, cbdir, reactor): """ Create a Twisted stream client endpoint from a Crossbar.io transport configuration. See: https://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.IStreamClientEndpoint.html :param config: The transport configuration. :type config: dict :param cbdir: Crossbar.io node directory (we need this for Unix domain socket paths and TLS key/certificates). :type cbdir: str :param reactor: The reactor to use for endpoint creation. :type reactor: obj :returns obj -- An instance implementing IStreamClientEndpoint """ endpoint = None log = make_logger() # a TCP endpoint # if config['type'] == 'tcp': # the TCP protocol version (v4 or v6) # version = int(config.get('version', 4)) # the host to connect to # host = str(config['host']) # the port to connect to # port = int(config['port']) # connection timeout in seconds # timeout = int(config.get('timeout', 10)) if 'tls' in config: if _HAS_TLS: # if the config specified any CA certificates, we use those (only!) if 'ca_certificates' in config['tls']: ca_certs = [] for cert_fname in config['tls']['ca_certificates']: cert = crypto.load_certificate( crypto.FILETYPE_PEM, six.u(open(cert_fname, 'r').read())) log.info("Loaded CA certificate '{fname}'", fname=cert_fname) ca_certs.append(cert) client_cert = None if 'key' in config['tls']: with open(config['tls']['certificate'], 'r') as f: cert = Certificate.loadPEM(f.read(), ) log.info( "{fname}: CN={subj.CN}, sha={sha}", fname=config['tls']['certificate'], subj=cert.getSubject(), sha=cert.digest('sha'), ) with open(config['tls']['key'], 'r') as f: private_key = KeyPair.load( f.read(), format=crypto.FILETYPE_PEM, ) log.info( "{fname}: {key}", fname=config['tls']['key'], key=private_key.inspect(), ) client_cert = PrivateCertificate.fromCertificateAndKeyPair( cert, private_key) # XXX OpenSSLCertificateAuthorities is a "private" # class, in _sslverify, so we shouldn't really be # using it. However, while you can pass a single # Certificate as trustRoot= there's no way to pass # multiple ones. # XXX ...but maybe the config should only allow # the user to configure a single cert to trust # here anyway? options = optionsForClientTLS( config['tls']['hostname'], trustRoot=OpenSSLCertificateAuthorities(ca_certs), clientCertificate=client_cert, ) else: options = optionsForClientTLS(config['tls']['hostname']) # create a TLS client endpoint # if version == 4: endpoint = SSL4ClientEndpoint( reactor, host, port, options, timeout=timeout, ) elif version == 6: raise Exception("TLS on IPv6 not implemented") else: raise Exception( "invalid TCP protocol version {}".format(version)) else: raise Exception( "TLS transport requested, but TLS packages not available:\n{}" .format(_LACKS_TLS_MSG)) else: # create a non-TLS client endpoint # if version == 4: endpoint = TCP4ClientEndpoint(reactor, host, port, timeout=timeout) elif version == 6: endpoint = TCP6ClientEndpoint(reactor, host, port, timeout=timeout) else: raise Exception( "invalid TCP protocol version {}".format(version)) # a Unix Domain Socket endpoint # elif config['type'] == 'unix': # the path # path = abspath(join(cbdir, config['path'])) # connection timeout in seconds # timeout = int(config.get('timeout', 10)) # create the endpoint # endpoint = UNIXClientEndpoint(reactor, path, timeout=timeout) else: raise Exception("invalid endpoint type '{}'".format(config['type'])) return endpoint