示例#1
0
    def dataReceived(self, new_data):
        """
        Deal with a message coming from a client.
        """

        self._read_buffer += new_data

        # Read a CCPMessage from the client socket.  If the attempt fails, or
        # the resulting message is a CLOSE, then kill the corresponding
        # connection.
        #
        # Otherwise, perform the requested action.
        try:
            (msgs, self._read_buffer) = CCPMessage.recv(self._read_buffer)
        except Exception as inst:
            log_error("Exception reading %d bytes of new_data" % len(new_data))
            log_error("%s" % inst)
            raise

        for msg in msgs:
            msg_type = msg.get_msg_type()
            connid = msg.get_conn_id()
            if ((msg_type == CCPMessage.OPEN_SOCKS5_CONN)
                    or (msg_type == CCPMessage.OPEN_CVPN_CONN)):
                # open a new connection

                # FIXME / TODO - open a connection to the service.
                # If we can't open a connection to the service, then
                # there's nothing we can do.  (we might need a separate
                # way to signal an error before we even get underway)
                dstFactory = Factory()
                dstFactory.protocol = DstProtocol
                dstFactory.socks5_addr = self._socks5_addr
                dstFactory.cvpn_addr = self._cvpn_addr
                dstFactory.src_protocol = self
                dstFactory.connid = connid

                if msg_type == CCPMessage.OPEN_SOCKS5_CONN:
                    dst_addr = self._socks5_addr
                elif msg_type == CCPMessage.OPEN_CVPN_CONN:
                    dst_addr = self._cvpn_addr
                else:
                    # TODO: whoops!
                    pass

                endpoint = endpoints.TCP4ClientEndpoint(
                    reactor, dst_addr[0], dst_addr[1])

                d = endpoint.connect(dstFactory)
                d.addErrback(self.con_error)

            elif msg_type == CCPMessage.CLOSE_CONNECTION:
                # shut down a connection
                dst_protocol = self._connid2dst_protocol.pop(connid)
                dst_protocol.transport.loseConnection()

            elif msg_type == CCPMessage.DATA_SEND:

                # Drop chaff.
                #
                if connid == CCPMessage.CHAFF_CONN_ID:
                    # print 'Dropping chaff len %d' % len(msg.get_data())
                    continue

                data = msg.get_data()

                # Figure out which service socket corresponds to the connid
                if not connid in self._connid2dst_protocol:
                    # Drop unexpected data
                    print "CCP: unexpected data"
                    return
                else:
                    dst_protocol = self._connid2dst_protocol[connid]
                    dst_protocol.transport.write(data)
                    #print "CCP: writing data"
            else:
                # TODO whoops!
                pass