def packets(self): message_type = self.body[0:2] body_remaining = self.body[2:] + self.computed_crc_bytes() packets = [] while len(body_remaining) > 0: packet = Packet() packet.pod_address_1 = self.pod_id packet.sequence = self.start_seq + len(packets) * 2 if len(packets) == 0: packet.packet_type = Packet.PACKET_TYPE_PDM packet.pod_address_2 = self.pod_id packet.byte9 = self.byte9 packet.message_type = message_type segment_len = min(Packet.MAX_BODY_SEGMENT_LEN,len(body_remaining)) packet.body = body_remaining[:segment_len] packet.body_len = len(self.body) body_remaining = body_remaining[segment_len:] else: packet.packet_type = Packet.PACKET_TYPE_CON segment_len = min(Packet.MAX_CON_BODY_SEGMENT_LEN,len(body_remaining)) packet.body = body_remaining[:segment_len] body_remaining = body_remaining[segment_len:] packets.append(packet) return packets
def packets(self): message_type = self.body[0:2] body_remaining = self.body[2:] + self.computed_crc_bytes() packets = [] while len(body_remaining) > 0: packet = Packet() packet.pod_address_1 = self.pod_id packet.sequence = self.start_seq + len(packets) * 2 if len(packets) == 0: packet.packet_type = Packet.PACKET_TYPE_PDM packet.pod_address_2 = self.pod_id packet.byte9 = self.byte9 packet.message_type = message_type segment_len = min(Packet.MAX_BODY_SEGMENT_LEN, len(body_remaining)) packet.body = body_remaining[:segment_len] packet.body_len = len(self.body) body_remaining = body_remaining[segment_len:] else: packet.packet_type = Packet.PACKET_TYPE_CON segment_len = min(Packet.MAX_CON_BODY_SEGMENT_LEN, len(body_remaining)) packet.body = body_remaining[:segment_len] body_remaining = body_remaining[segment_len:] packets.append(packet) return packets
def packetize(self, start_sequence): body_remaining = self.body + self.computed_crc_bytes() sequence_num = start_sequence packets = [] while len(body_remaining) > 0: packet = Packet() packet.pod_address_1 = self.pod_address packet.sequence = sequence_num if len(packets) == 0: packet.packet_type = PacketType.PDM packet.pod_address_2 = self.pod_address packet.byte9 = self.byte9 segment_len = min(Packet.MAX_BODY_SEGMENT_LEN, len(body_remaining)) packet.body = body_remaining[:segment_len] packet.body_len = len(self.body) body_remaining = body_remaining[segment_len:] else: packet.packet_type = PacketType.CON segment_len = min(Packet.MAX_CON_BODY_SEGMENT_LEN, len(body_remaining)) packet.body = body_remaining[:segment_len] body_remaining = body_remaining[segment_len:] sequence_num += 2 if sequence_num > 31: sequence_num -= 32 packets.append(packet) return packets
def send_req_udp(router_addr: str, router_port: int, server_addr: str, server_port: int, packet_type: int, seq_num: int, req: str, verbose=False): peer_ip = ipaddress.ip_address(socket.gethostbyname(server_addr)) conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) timeout = 5 print("sending SYN") syn = Packet(packet_type=1, seq_num=seq_num, peer_ip_addr=peer_ip, peer_port=server_port, payload='') conn.sendto(syn.to_bytes(), (router_addr, router_port)) print("waiting for SYN-ACK") conn.settimeout(timeout) syn.packet_type = -1 while syn.packet_type != 2: resp, send = conn.recvfrom(1024) recv_packet = Packet.from_bytes(resp) syn.packet_type = recv_packet.packet_type print("Received SYN-ACK") print("Sending ACK") ack = Packet(packet_type=3, seq_num=seq_num, peer_ip_addr=peer_ip, peer_port=server_port, payload='') conn.sendto(ack.to_bytes(), (router_addr, router_port)) res = "" try: msg = req p = Packet(packet_type=packet_type, seq_num=seq_num, peer_ip_addr=peer_ip, peer_port=server_port, payload=msg.encode("UTF-8")) conn.sendto(p.to_bytes(), (router_addr, router_port)) print('Send: \n"{}"\nto router'.format(msg)) # Try to receive a response within timeout conn.settimeout(timeout) response, sender = conn.recvfrom(1024) print('Waiting for a response') p = Packet.from_bytes(response) print('Router: ', sender) print('Packet: ', p) res = Response(p.payload.decode("UTF-8")) print('Payload: ' + p.payload.decode("UTF-8")) except socket.timeout: print('No response after {}s'.format(timeout)) finally: conn.close() return res
def connect(host, port, peer_ip): global conn global p_constructor global router global seq_num print(peer_ip) print(port) data = b'' p = Packet(packet_type=Packet_Constructor.syn_type, seq_num=seq_num, peer_ip_addr=peer_ip, peer_port=port, is_last_packet=False, payload=data) conn.sendto(p.to_bytes(), router) response, sender = conn.recvfrom(1024) p = Packet.from_bytes(response) if (p.packet_type == Packet_Constructor.syn_ack_type): print("Got syn ack, responding with ack") p.packet_type = Packet_Constructor.ack_type conn.sendto(p.to_bytes(), sender) else: print("During TCP handshake, got the wrong packet type. Restarting") connect(host, port, peer_ip)
def client_packet_send(self, conn, all_packet, router_addr, router_port, peer_ip, server_port): if (len(all_packet) > 1): window_size = int(len(all_packet) / 2) else: window_size = len(all_packet) windowcount = 0 while (len(all_packet) != 0): while (len(self.window) < window_size and len(all_packet) != 0): j = 0 windowcount = windowcount + 1 for i in all_packet: self.window[i] = all_packet[i] j = j + 1 if len(self.window) == window_size: break for i in self.window.keys(): del self.all_pkt[i] p = Packet(packet_type=0, seq_num=i, peer_ip_addr=peer_ip, peer_port=server_port, payload=bytes(self.window[i])) print('sending packet:', p.seq_num) self.connections.sendto(p.to_bytes(), (router_addr, router_port)) time.sleep(self.delay) self.resend_packet(conn, router_addr, router_port, peer_ip, server_port) print('data transmission finished') self.listen_nak = False p.packet_type = 5 self.connections.sendto(p.to_bytes(), (router_addr, router_port)) return
def send_udp_pkt(router_addr, router_port, peer_ip, server_port, conn, seq, packets_list, last_pkt, response_processor, slide_window, lock): timeout = 3 resend = True seq_num = str(seq) while resend: try: # check if seq in buffer (received by other thread) while True: have_lock = lock.acquire(0) try: if have_lock: for s in msg_buffer: if s.seq_num == seq: print("Found correct packet seq# " + seq_num + " in buffer") rp = s msg_buffer.remove(s) resend = False finally: if have_lock: lock.release() break if resend: print('Send packet ' + seq_num + ' and listen for ' + str(timeout) + 's') # create the packet p = Packet(packet_type=0, seq_num=seq, peer_ip_addr=peer_ip, peer_port=server_port, payload=packets_list[seq].encode("utf-8")) # Send this packet out and start the timer for it conn.sendto(p.to_bytes(), (router_addr, router_port)) ######################################################### # program will wait here until receive or timeout # ######################################################### conn.settimeout(timeout) response, sender = conn.recvfrom(1024) # If a packet is received, check matching seq # rp = Packet.from_bytes(response) if rp.seq_num == seq: print("Received correct packet # " + seq_num) resend = False else: print("Was expecting " + seq_num + ", but got " + str(rp.seq_num) + ", buffering it, search buf before resend.") while True: have_lock = lock.acquire(0) try: if have_lock: msg_buffer.append(rp) finally: if have_lock: lock.release() break except OverflowError: print('\nOverflow Error (seq # got too big?)\n') break except socket.timeout: print('No response for seq# "{}" after {}s'.format( seq_num, timeout)) continue ######################################################### # This packet has now been acknowledged # ######################################################### # correct packet is received if not resend: # Only the oldest thread is allowed to complete first the others must wait with slide_window: while seq != window_status[0]: print("Thread w/seq# " + seq_num + " is waiting to finish.") print(window_status) slide_window.wait() print("Thread w/seq# " + seq_num + " is done waiting, notify slide window") window_status.popleft() # if there's more packets to be sent, start a new thread to handle it if len(window_status) != 0 and window_status[len(window_status) - 1] + 1 <= last_pkt: next_seq = window_status[len(window_status) - 1] + 1 window_status.append(next_seq) threading.Thread( target=send_udp_pkt, args=(router_addr, router_port, peer_ip, server_port, conn, next_seq, packets_list, last_pkt, response_processor, slide_window, lock)).start() while True: file_lock = lock.acquire(0) try: if file_lock: f = open(logfile, 'a') f.write(p.payload.decode("utf-8") + "\n") f.close() finally: if file_lock: lock.release() break slide_window.notifyAll() print("window: " + str(window_status)) print("buffer: " + str(msg_buffer)) # clear potential duplicate msg_buffer entries while True: have_lock = lock.acquire(0) try: if have_lock: for s in msg_buffer: if s.seq_num <= seq: print("Removing old buffer entry seq# " + seq_num) msg_buffer.remove(s) finally: if have_lock: lock.release() break if rp.seq_num == last_pkt: while True: have_lock = lock.acquire(0) try: if have_lock: print( "final thread finished sending request, expecting re-handshake for response length" ) # output to file f = open(logfile, 'a') f.write(str(window_status) + "\n" + str(msg_buffer)) f.close() response_window_status = deque() waiting_pkts = deque() response_queue_lock = threading.Condition() # print ("{}\n{}\n{}\n{}\n{}\n".format(conn, sender, last_pkt, window_status, response_msg_buffer)) #todo expect a handshake packet print("waiting for re-handshake packet...") shook = False timeout = 30 conn.settimeout(timeout) while True: try: data, sender = conn.recvfrom(1024) p = Packet.from_bytes(data) print("Router: ", sender) print("Response Packet Type: ", p.packet_type) print("Packet: ", p) #print("Payload: ", p.payload.decode("utf-8")) #print ("response_window_status: ") #print (response_window_status) # if handshake request, just send handshake ack if p.packet_type == 5: if not shook: shook = True last_pkt = int(p.payload.decode("utf-8")) for seq in range(0, WINDOW_SIZE): if seq <= last_pkt: response_window_status.append(seq) p.packet_type = 6 conn.sendto(p.to_bytes(), sender) # if response data, handle it elif p.packet_type == 0: if shook: # handle response packet threading.Thread( target=handle_server_response, args=(conn, p, sender, last_pkt, response_processor, response_window_status, waiting_pkts, slide_window, response_queue_lock)).start() except socket.timeout: print('No response packets after {}s, timing out'. format(timeout)) break continue finally: if have_lock: lock.release() break else: break