def __init__( self, mName, main_mng ): super( CommunicationMng, self ).__init__( mName, main_mng ) logging.info( "Communication Manager started..." ) self.sslClientOnly=myPubaddr[5] self.isSSL=myPubaddr[4] if self.sslClientOnly==False: self.tcpSSockServ = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) self.tcp_server = threading.Thread( target=tcp_serverthread, name="tcp_serverthread", args=( self.main_mng, self.tcpSSockServ) ) self.tcp_server.daemon = True self.tcp_server.start() self.udpSSockServ = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) self.udpSSock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) self.udp_server = threading.Thread( target=udp_serverthread, name="udp_serverthread", args=( self.main_mng, self.udpSSockServ ) ) self.udp_server.daemon = True self.udp_server.start() self.i = 0 if self.isSSL==1:#@Ali: start the ssl server in a seperate thread try: testSocket=socket.socket() self.sslComModule=SSLCommunicationWrapper(self.main_mng,False) #Test if the port is already in use testSocket.bind(('',self.sslComModule.hostSSLport)) testSocket.close() self.ssl_server = threading.Thread( target=self.sslComModule.sslServer, name="ssl_serverthread", args=('startserver',) ) self.ssl_server.daemon = True self.ssl_server.start() except: #Cannot bind to SSL Port print 'SSL Port Already in Use' self.isSSL=0 else: print 'Initializing the SSL Comunication Module' self.sslComModule=SSLCommunicationWrapper(self.main_mng,True) f = open('conf'+os.sep+'ipmap.dat', "r") for line in f.readlines(): pubIP, tcp_port, udp_port, priIP= line.split() ipMap[(pubIP, tcp_port, udp_port)]=priIP f.close()
class CommunicationMng( Manager.Manager ): "Communication manager" def __init__( self, mName, main_mng ): super( CommunicationMng, self ).__init__( mName, main_mng ) logging.info( "Communication Manager started..." ) self.sslClientOnly=myPubaddr[5] self.isSSL=myPubaddr[4] if self.sslClientOnly==False: self.tcpSSockServ = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) self.tcp_server = threading.Thread( target=tcp_serverthread, name="tcp_serverthread", args=( self.main_mng, self.tcpSSockServ) ) self.tcp_server.daemon = True self.tcp_server.start() self.udpSSockServ = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) self.udpSSock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) self.udp_server = threading.Thread( target=udp_serverthread, name="udp_serverthread", args=( self.main_mng, self.udpSSockServ ) ) self.udp_server.daemon = True self.udp_server.start() self.i = 0 if self.isSSL==1:#@Ali: start the ssl server in a seperate thread try: testSocket=socket.socket() self.sslComModule=SSLCommunicationWrapper(self.main_mng,False) #Test if the port is already in use testSocket.bind(('',self.sslComModule.hostSSLport)) testSocket.close() self.ssl_server = threading.Thread( target=self.sslComModule.sslServer, name="ssl_serverthread", args=('startserver',) ) self.ssl_server.daemon = True self.ssl_server.start() except: #Cannot bind to SSL Port print 'SSL Port Already in Use' self.isSSL=0 else: print 'Initializing the SSL Comunication Module' self.sslComModule=SSLCommunicationWrapper(self.main_mng,True) f = open('conf'+os.sep+'ipmap.dat', "r") for line in f.readlines(): pubIP, tcp_port, udp_port, priIP= line.split() ipMap[(pubIP, tcp_port, udp_port)]=priIP f.close() def do_work( self, item ): if self.sslClientOnly==True: if item.type.startswith( "S_P2P" ): trafic_type='UDP' sendtoip=item.addr[0] else: trafic_type='TCP' sendtoip=item.to_ip[0] self.sslComModule.sendOnSSL(item, trafic_type, sendtoip) elif item.type.startswith( "S_P2P" ): #@Ali if self.isSSL==1: if int(item.addr[2])==self.sslComModule.hostSSLport: trafic_type='UDP' sendtoip=item.addr[0] self.sslComModule.sendOnSSL(item, trafic_type, sendtoip) return send_to=( item.addr[0], int(item.addr[2])) if ipMap.has_key(item.addr) or item.addr[0]==myPubaddr[0]: #@Ali same network, chk ipmap for mapping or requeue the msg and wait for relay response if ipMap.has_key(item.addr): send_to=( ipMap[item.addr], int(item.addr[2]))#@Ali send on local/private address else:#@Ali Requeue the item self.main_mng.add(item) return try: key = item.pkey except: print "unable to obtain public key for p2p traffic" #print item.data #print item.addr[0] data = pickle.dumps( item.data, pickle.HIGHEST_PROTOCOL ) #print key data = crypto.encrypt(key, data) #p2p message encryption try: self.udpSSock.sendto( data, send_to ) #@Ali Transmit the data on random port except: self.main_mng.add(item) print 'udp socket error' print traceback.print_exc() # else: #@Ali if self.isSSL==1: if int(item.to_ip[1])==self.sslComModule.hostSSLport: trafic_type='TCP' sendtoip=item.to_ip[0] self.sslComModule.sendOnSSL(item, trafic_type, sendtoip) return send_to=(item.to_ip[0],int(item.to_ip[1])) if ipMap.has_key(item.to_ip) or item.to_ip[0]==myPubaddr[0]: #@Ali same network, chk ipmap for mapping or requeue the msg and wait for relay response if ipMap.has_key(item.to_ip): send_to=( ipMap[item.to_ip], int(item.to_ip[1]))#@Ali send on local/private address else:#@Ali Requeue the item self.main_mng.add(item) return # pkey = item.pkey item.pkey = None logging.info( "Communication manager is sending {0.type} to {1}".format( item, send_to ) ) try: sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) sock.connect( send_to ) #item.myIP=(myPubaddr[0],myPubaddr[1],myPubaddr[2]) SizeStruct = struct.Struct( "!I" ) data = pickle.dumps( item, pickle.HIGHEST_PROTOCOL ) en_data = crypto.encrypt( pkey, data ) sock.sendall(struct.pack("!I",len(en_data))) start=0 end=5000# Sending 1 MB size=len(en_data) while True: if end < size: sock.sendall(en_data[start:end]) start=end end=end+5000 else: sock.sendall(en_data[start:]) break sock.close() except socket.error as er: logging.info( "Socket error: {0}".format( er ) ) print 'Socket Error' print item.type print send_to print item.to_ip # print ipMap print traceback.print_exc() # print 'Item added to the Queue for re-attempt' # item.pkey=pkey # self.main_mng.add(item) sock.close() return except: # item.pkey=pkey # self.main_mng.add(item) print traceback.print_exc() # print 'Item added to the Queue for re-attempt' sock.close() return def close( self ): logging.info( "Shutting down Communication Manager..." ) #self.udpSSock.close() #self.udp_server.close() if self.sslClientOnly==True: try: self.sslComModule.close() except: pass else: # Remove Port Forwording Mappings if upnpFlag==True: try: upnp.removePortMaping(int(myPubaddr[1]), 'TCP') upnp.removePortMaping(int(myPubaddr[2]), 'UDP') if self.isSSL: upnp.removePortMaping(443, 'TCP') except: pass try: self.udpSSockServ.close() self.udp_server.join(1) except: pass try: self.tcpSSockServ.close() self.tcp_server.join(1) except: pass #The following line store the ipMap to file, if useful for reducing the Replay request msgs, but if the users private ips are assigned through DHCP in this case it will not work. So decomment the lines if you are sure the network is has fixed Ips # f=open('conf'+os.sep+'ipmap.dat') # for map in ipMap.items(): # k,v=map # s=str(k[0])+' '+str(k[1])+' '+str(k[2])+' '+str(v)+'\n' # f.write(s) # f.close() super( CommunicationMng, self ).close()