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