【问题标题】:twisted handle connection lost扭曲的手柄连接丢失
【发布时间】:2020-10-20 07:40:49
【问题描述】:

我尝试使用ldaptor proxybase 和Twisted 创建一个ldap 代理应用程序。 代理应用程序处理来自客户端(C) -> 代理(P) -> LDAPserver(S)的连接请求

我的问题是一旦 P -> S 之间的连接关闭,而 C -> P 之间的连接仍然打开,如果客户端发送 ldap 请求,代理返回错误。

所以我尝试在P -> S中处理连接丢失事件,并触发一个方法并关闭C -> P之间的连接

这是我的代码

#! /usr/bin/env python

class LoggingProxy(ProxyBase):
    """
    A simple example of using `ProxyBase` to log requests and responses.
    """
    def handleProxiedResponse(self, response, request, controls):
        """
        Log the representation of the responses received.
        """
        log.msg("Request => " + repr(request))
        log.msg("Response => " + repr(response))
        return defer.succeed(response)
        
    def connectionLost(self, reason):
        if self.client is not None and self.client.connected:
            if not self.unbound:
                self.client.unbind()
                self.unbound = True
            else:
                self.client.transport.loseConnection()
        self.client = None
        ldapserver.BaseLDAPServer.connectionLost(self, reason)
        log.msg("C -> P CONN LOST: {} {}".format(
            *tcp_lost_conn_repr(self.transport)))
    def connectionClose(self):
        log.msg("C -> P CONN LOST: {} {}".format(
            *tcp_lost_conn_repr(self.transport)))
        self.transport.loseConnection()
    
class MyLDAPClient(LDAPClient):
    """An LDAP client that connect to the proxied server."""
    def connectionLost(self, reason=protocol.connectionDone):
        """Called when TCP connection has been lost"""
        self.connected = 0
        log.msg("P -> S CONN LOST: {} {}".format(
            *tcp_lost_conn_repr(self.transport)))
        while self.onwire:
            k, v = self.onwire.popitem()
            d, _, _, _ = v
            d.errback(reason)
        # Terminate C -> P connection
        LoggingProxy.connectionClose(self)

class LoggingProxyService(Service):
    endpointStr = "tcp:port=10389"
    proxiedEndpointStr = 'tcp:host=localhost:port=389'
    debug = True
    
    def startService(self):
        factory = protocol.ServerFactory()
        use_tls = False
 
        #proxiedEndpointStr = 'tcp:host=localhost:port=389'
        clientConnector = partial(
            connectToLDAPEndpoint,
            reactor,
            self.proxiedEndpointStr,
            MyLDAPClient)

        def buildProtocol():
            proto = LoggingProxy()
            proto.clientConnector = clientConnector
            proto.use_tls = use_tls
            return proto

        factory.protocol = buildProtocol
        ep = serverFromString(reactor, self.endpointStr)
        d = ep.listen(factory)
        d.addCallback(self.setListeningPort)
        d.addErrback(log.err)
        
    def setListeningPort(self, port):
        self.port_ = port

    def stopService(self):
        # If there are asynchronous cleanup tasks that need to
        # be performed, add deferreds for them to `async_tasks`.
        async_tasks = []
        if self.port_ is not None:
            async_tasks.append(self.port_.stopListening())
        if len(async_tasks) > 0:
            return defer.DeferredList(async_tasks, consumeErrors=True)


application = Application("Logging LDAP Proxy")
service = LoggingProxyService()
service.setServiceParent(application)

问题是LoggingProxy.connectionClose(self) 没有引用启动连接的原始实例。

如何指向原始的LoggingProxy() 实例并关闭连接?

【问题讨论】:

    标签: python twisted


    【解决方案1】:

    在您的LoggingProxy.connectionLost 中,您并不总是关闭C -> P 连接:

        def connectionLost(self, reason):
            if self.client is not None and self.client.connected:
                if not self.unbound:
                    self.client.unbind()
                    self.unbound = True
                else:
                    self.client.transport.loseConnection()
            self.client = None
            ldapserver.BaseLDAPServer.connectionLost(self, reason)
            log.msg("C -> P CONN LOST: {} {}".format(
                *tcp_lost_conn_repr(self.transport)))
    

    如果 not self.unbound 则永远不会调用 self.client.transport.loseConnection。相反,self.client 被丢弃,因此永远无法调用。

    努力始终致电loseConnection 以响应connectionLost

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 2014-06-09
      • 2013-01-11
      相关资源
      最近更新 更多