.
This commit is contained in:
		
							parent
							
								
									e2ae47d056
								
							
						
					
					
						commit
						586e69552b
					
				
							
								
								
									
										82
									
								
								mods/utcp.py
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								mods/utcp.py
									
									
									
									
									
								
							@ -30,8 +30,15 @@ class Connection:
 | 
				
			|||||||
    HIGHEST_STARTING_SEQ = 4294967295
 | 
					    HIGHEST_STARTING_SEQ = 4294967295
 | 
				
			||||||
    def __init__(self, remote, encrypted=False):
 | 
					    def __init__(self, remote, encrypted=False):
 | 
				
			||||||
        self.peer_addr = remote
 | 
					        self.peer_addr = remote
 | 
				
			||||||
 | 
					        self.ack = 0
 | 
				
			||||||
        self.seq = Connection.gen_starting_seq_num()
 | 
					        self.seq = Connection.gen_starting_seq_num()
 | 
				
			||||||
        self.my_key
 | 
					        self.my_key = None
 | 
				
			||||||
 | 
					        if encrypted:
 | 
				
			||||||
 | 
					            self.my_key = KeyPair(simplecrypto.RsaKeypair())
 | 
				
			||||||
 | 
					            self.pubkey = self.my_key.publickey.serialize()
 | 
				
			||||||
 | 
					        self.peer_pub = None
 | 
				
			||||||
 | 
					        self.recv_lock = threading.Lock()
 | 
				
			||||||
 | 
					        self.send_lock = threading.Lock()
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def gen_starting_seq_num():
 | 
					    def gen_starting_seq_num():
 | 
				
			||||||
        return random.randint(Connection.SMALLEST_STARTING_SEQ, Connection.HIGHEST_STARTING_SEQ)
 | 
					        return random.randint(Connection.SMALLEST_STARTING_SEQ, Connection.HIGHEST_STARTING_SEQ)
 | 
				
			||||||
@ -86,6 +93,9 @@ class TCPPacket(object):
 | 
				
			|||||||
            self.flag_fin = 1
 | 
					            self.flag_fin = 1
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.flag_fin = 0
 | 
					            self.flag_fin = 0
 | 
				
			||||||
 | 
					    def set_data(self, data):
 | 
				
			||||||
 | 
					        self.checksum = TCP.checksum(data)
 | 
				
			||||||
 | 
					        self.data = data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -145,7 +155,6 @@ class TCP(object):
 | 
				
			|||||||
        self.settimeout()
 | 
					        self.settimeout()
 | 
				
			||||||
        self.connection_lock = threading.Lock()
 | 
					        self.connection_lock = threading.Lock()
 | 
				
			||||||
        self.queue_lock = threading.Lock()
 | 
					        self.queue_lock = threading.Lock()
 | 
				
			||||||
        self.peer_keypair = {}
 | 
					 | 
				
			||||||
        self.connections = {}
 | 
					        self.connections = {}
 | 
				
			||||||
        self.connection_queue = []
 | 
					        self.connection_queue = []
 | 
				
			||||||
        self.packets_received = {'SYN': {}, 'ACK': {}, 'SYN-ACK': {}, 'DATA or FIN': {}, 'FIN-ACK': {}}
 | 
					        self.packets_received = {'SYN': {}, 'ACK': {}, 'SYN-ACK': {}, 'DATA or FIN': {}, 'FIN-ACK': {}}
 | 
				
			||||||
@ -254,15 +263,14 @@ class TCP(object):
 | 
				
			|||||||
                    answer, address = self.find_correct_packet('SYN')
 | 
					                    answer, address = self.find_correct_packet('SYN')
 | 
				
			||||||
                    with self.queue_lock:
 | 
					                    with self.queue_lock:
 | 
				
			||||||
                        if len(self.connection_queue) < max_connections:
 | 
					                        if len(self.connection_queue) < max_connections:
 | 
				
			||||||
 | 
					                            conn = Connection(address, self.encrypted)
 | 
				
			||||||
                            if self.encrypted:
 | 
					                            if self.encrypted:
 | 
				
			||||||
                                try:
 | 
					                                try:
 | 
				
			||||||
                                    peer_pub = answer.data
 | 
					                                    conn.peer_pub = answer.data
 | 
				
			||||||
                                    self.peer_keypair[address] = KeyPair(simplecrypto.RsaKeypair()) # FIXME: for some reason slowly creates a key (~5 sec)
 | 
					 | 
				
			||||||
                                    self.peer_keypair[address].peer_pub = simplecrypto.RsaPublicKey(peer_pub)
 | 
					 | 
				
			||||||
                                except:
 | 
					                                except:
 | 
				
			||||||
                                    self.peer_keypair.pop(address)
 | 
					                                    self.peer_keypair.pop(address)
 | 
				
			||||||
                                    raise socket.error('Init peer public key error')
 | 
					                                    raise socket.error('Init peer public key error')
 | 
				
			||||||
                            self.connection_queue.append((answer, address))
 | 
					                            self.connection_queue.append((answer, conn))
 | 
				
			||||||
                            self.blink_new_conn_event()
 | 
					                            self.blink_new_conn_event()
 | 
				
			||||||
                        else:
 | 
					                        else:
 | 
				
			||||||
                            self.own_socket.sendto('Connections full', address)
 | 
					                            self.own_socket.sendto('Connections full', address)
 | 
				
			||||||
@ -287,34 +295,28 @@ class TCP(object):
 | 
				
			|||||||
                self.new_conn_event.wait(0.1)
 | 
					                self.new_conn_event.wait(0.1)
 | 
				
			||||||
                if self.connection_queue:
 | 
					                if self.connection_queue:
 | 
				
			||||||
                    with self.queue_lock:
 | 
					                    with self.queue_lock:
 | 
				
			||||||
                        answer, address = self.connection_queue.pop()
 | 
					                        answer, conn = self.connection_queue.pop()
 | 
				
			||||||
                        
 | 
					                    self.connections[conn.peer_addr] = conn
 | 
				
			||||||
                    self.connections[address] = TCPPacket()
 | 
					                    packet = TCPPacket(conn.seq)
 | 
				
			||||||
                    self.connections[address].ack = answer.seq + 1
 | 
					                    packet.ack = answer.seq + 1
 | 
				
			||||||
                    self.connections[address].seq += 1
 | 
					                    packet.seq = conn.seq_inc()
 | 
				
			||||||
                    self.connections[address].set_flags(ack=True, syn=True)
 | 
					                    packet.set_flags(ack=True, syn=True)
 | 
				
			||||||
                    if self.encrypted:
 | 
					                    if self.encrypted:
 | 
				
			||||||
                        pubkey = self.peer_keypair[address].my_key.publickey.serialize()
 | 
					                        packet.set_data(conn.peer_pub.encrypt_raw(conn.pubkey))
 | 
				
			||||||
                        self.connections[address].data = self.peer_keypair[address].peer_pub.encrypt_raw(pubkey)
 | 
					                    packet_to_send = pickle.dumps(packet)
 | 
				
			||||||
                        self.connections[address].checksum = TCP.checksum(self.connections[address].data)
 | 
					                    #On packet lost retransmit
 | 
				
			||||||
                    packet_to_send = pickle.dumps(self.connections[address])
 | 
					 | 
				
			||||||
                    if self.encrypted:
 | 
					 | 
				
			||||||
                        self.connections[address].data = b''
 | 
					 | 
				
			||||||
                        self.connections[address].checksum = 0
 | 
					 | 
				
			||||||
                    #lock address, connections dictionary?
 | 
					 | 
				
			||||||
                    packet_not_sent_correctly = True
 | 
					                    packet_not_sent_correctly = True
 | 
				
			||||||
                    while packet_not_sent_correctly or answer is None:
 | 
					                    while packet_not_sent_correctly or answer is None:
 | 
				
			||||||
                        try:
 | 
					                        try:
 | 
				
			||||||
                            packet_not_sent_correctly = False
 | 
					                            packet_not_sent_correctly = False
 | 
				
			||||||
                            self.own_socket.sendto(packet_to_send, address)
 | 
					                            self.own_socket.sendto(packet_to_send, conn.peer_addr)
 | 
				
			||||||
                            answer = self.find_correct_packet('ACK', address)
 | 
					                            answer = self.find_correct_packet('ACK', conn.peer_addr)
 | 
				
			||||||
                        except socket.timeout:
 | 
					                        except socket.timeout:
 | 
				
			||||||
                            packet_not_sent_correctly = True
 | 
					                            packet_not_sent_correctly = True
 | 
				
			||||||
                    self.connections[address].set_flags()
 | 
					                    conn.ack = answer.seq + 1
 | 
				
			||||||
                    self.connections[address].ack = answer.seq + 1
 | 
					                    return ConnectedSOCK(self, conn.peer_addr), conn.peer_addr
 | 
				
			||||||
                    return ConnectedSOCK(self, address), address
 | 
					 | 
				
			||||||
        except Exception as error:
 | 
					        except Exception as error:
 | 
				
			||||||
            self.close(address)
 | 
					            self.close(conn.peer_addr)
 | 
				
			||||||
            raise EOFError('Something went wrong in accept func: ' + str(error))
 | 
					            raise EOFError('Something went wrong in accept func: ' + str(error))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def connect(self, server_address=('127.0.0.1', 10000)):
 | 
					    def connect(self, server_address=('127.0.0.1', 10000)):
 | 
				
			||||||
@ -323,32 +325,24 @@ class TCP(object):
 | 
				
			|||||||
            self.status = 1
 | 
					            self.status = 1
 | 
				
			||||||
            self.client = True
 | 
					            self.client = True
 | 
				
			||||||
            self.central_receive()
 | 
					            self.central_receive()
 | 
				
			||||||
            self.connections[server_address] = TCPPacket()
 | 
					            conn = Connection(server_address, self.encrypted)
 | 
				
			||||||
            self.connections[server_address].set_flags(syn=True)
 | 
					            self.connections[server_address] = Connection(server_address, self.encrypted)
 | 
				
			||||||
 | 
					            syn_packet = TCPPacket(conn.seq)
 | 
				
			||||||
 | 
					            syn_packet.set_flags(syn=True)
 | 
				
			||||||
            if self.encrypted:
 | 
					            if self.encrypted:
 | 
				
			||||||
                self.peer_keypair[server_address] = KeyPair(simplecrypto.RsaKeypair())  # FIXME: but here it creates the key quickly
 | 
					                syn_packet.set_data(conn.pubkey)
 | 
				
			||||||
                pubkey = self.peer_keypair[server_address].my_key.publickey.serialize()
 | 
					            first_packet_to_send = pickle.dumps(syn_packet)
 | 
				
			||||||
                pub_checksum = TCP.checksum(pubkey)
 | 
					            self.own_socket.sendto(first_packet_to_send, server_address)
 | 
				
			||||||
                self.connections[server_address].checksum = pub_checksum
 | 
					 | 
				
			||||||
                self.connections[server_address].data = pubkey
 | 
					 | 
				
			||||||
            first_packet_to_send = pickle.dumps(self.connections[server_address])
 | 
					 | 
				
			||||||
            self.connections[server_address].data = b''
 | 
					 | 
				
			||||||
            self.connections[server_address].checksum = 0
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            self.own_socket.sendto(first_packet_to_send, list(self.connections.keys())[FIRST])
 | 
					 | 
				
			||||||
            self.connections[server_address].set_flags()
 | 
					 | 
				
			||||||
            answer = self.find_correct_packet('SYN-ACK', server_address)
 | 
					            answer = self.find_correct_packet('SYN-ACK', server_address)
 | 
				
			||||||
            if type(answer) == str:  # == 'Connections full':
 | 
					            if type(answer) == str:  # == 'Connections full':
 | 
				
			||||||
                raise socket.error('Server cant receive any connections right now.')
 | 
					                raise socket.error('Server cant receive any connections right now.')
 | 
				
			||||||
            if self.encrypted:
 | 
					            if self.encrypted:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    peer_pub = self.peer_keypair[server_address].my_key.decrypt_raw(answer.data)
 | 
					                    peer_pub = conn.my_key.decrypt_raw(answer.data)
 | 
				
			||||||
                    self.peer_keypair[server_address].peer_pub = simplecrypto.RsaPublicKey(peer_pub)
 | 
					                    conn.peer_pub = simplecrypto.RsaPublicKey(peer_pub)
 | 
				
			||||||
                except:
 | 
					                except:
 | 
				
			||||||
                    raise socket.error('Decrypt peer public key error')
 | 
					                    raise socket.error('Decrypt peer public key error')
 | 
				
			||||||
                if not peer_pub or answer.checksum != TCP.checksum(answer.data):
 | 
					            ack_packet = 
 | 
				
			||||||
                    raise socket.error('Invalid peer public key')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.connections[server_address].ack = answer.seq + 1
 | 
					            self.connections[server_address].ack = answer.seq + 1
 | 
				
			||||||
            self.connections[server_address].seq += 1
 | 
					            self.connections[server_address].seq += 1
 | 
				
			||||||
            self.connections[server_address].set_flags(ack=True)
 | 
					            self.connections[server_address].set_flags(ack=True)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user