Exemplo n.º 1
0
def create_listening_port_from_config(config, cbdir, factory, reactor, log):
    """
    Create a Twisted listening port from a Crossbar.io transport configuration.

    See: https://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.IListeningPort.html

    :param config: The transport configuration.
    :type config: dict
    :param factory: The transport factory to use (a provider of IProtocolFactory).
    :type factory: obj
    :param cbdir: Crossbar.io node directory (we need this for TLS key/certificates).
    :type cbdir: str
    :param reactor: The reactor to use for endpoint creation.
    :type reactor: obj

    :returns obj -- A Deferred that results in an IListeningPort or an CannotListenError
    """

    if 'portrange' in config:
        # first free port in given range
        config['port'] = first_free_tcp_port(host=config.get('interface', ''),
                                             portrange=config['portrange'])
    else:
        if 'port' not in config or config['port'] is None:
            # random free port
            config['port'] = get_free_tcp_port(
                host=config.get('interface', ''))

    if config['type'] == 'tcp' and config.get('shared', False):

        # the TCP protocol version (v4 or v6)
        #
        version = int(config.get('version', 4))

        # the listening interface
        #
        interface = str(config.get('interface', '').strip())

        # the listening port
        #
        port = int(config['port'])

        # the TCP accept queue depth
        #
        backlog = int(config.get('backlog', 50))

        # the TCP socket sharing option
        #
        shared = config.get('shared', False)

        # create a listening port
        #
        if 'tls' in config:
            if _HAS_TLS:
                # TLS server context
                context = _create_tls_server_context(config['tls'], cbdir, log)

                if version == 4:
                    listening_port = SharedTLSPort(port,
                                                   factory,
                                                   context,
                                                   backlog,
                                                   interface,
                                                   reactor,
                                                   shared=shared)
                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:
            listening_port = SharedPort(port,
                                        factory,
                                        backlog,
                                        interface,
                                        reactor,
                                        shared=shared)

        try:
            listening_port.startListening()
            return defer.succeed(listening_port)
        except Exception as e:
            return defer.fail(e)

    else:
        try:
            endpoint = create_listening_endpoint_from_config(
                config, cbdir, reactor, log)
            return endpoint.listen(factory)
        except Exception:
            return defer.fail()
Exemplo n.º 2
0
def create_listening_port_from_config(config, cbdir, factory, reactor, log):
    """
    Create a Twisted listening port from a Crossbar.io transport configuration.

    See: https://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.IListeningPort.html

    :param config: The transport configuration.
    :type config: dict
    :param factory: The transport factory to use (a provider of IProtocolFactory).
    :type factory: obj
    :param cbdir: Crossbar.io node directory (we need this for TLS key/certificates).
    :type cbdir: str
    :param reactor: The reactor to use for endpoint creation.
    :type reactor: obj

    :returns obj -- A Deferred that results in an IListeningPort or an CannotListenError
    """
    if config['type'] == 'tcp' and config.get('shared', False):

        # the TCP protocol version (v4 or v6)
        #
        version = int(config.get('version', 4))

        # the listening port
        #
        port = int(config['port'])

        # the listening interface
        #
        interface = str(config.get('interface', '').strip())

        # the TCP accept queue depth
        #
        backlog = int(config.get('backlog', 50))

        # the TCP socket sharing option
        #
        shared = config.get('shared', False)

        # create a listening port
        #
        if 'tls' in config:
            if _HAS_TLS:
                # TLS server context
                context = _create_tls_server_context(config['tls'], cbdir, log)

                if version == 4:
                    listening_port = SharedTLSPort(port, factory, context, backlog, interface, reactor, shared=shared)
                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:
            listening_port = SharedPort(port, factory, backlog, interface, reactor, shared=shared)

        try:
            listening_port.startListening()
            return defer.succeed(listening_port)
        except Exception as e:
            return defer.fail(e)

    else:
        try:
            endpoint = create_listening_endpoint_from_config(config, cbdir, reactor, log)
            return endpoint.listen(factory)
        except Exception:
            return defer.fail()