Ejemplo n.º 1
0
    def test_synack_packet_invalid(self):
        # Input: packet with any flag other than SYN set

        p = Packet(
                   packet.Type.DATA,
                   0,
                   0,
                   None)
        with self.assertRaises(TypeError) as cm:
            packet.create_synack_packet(p)

        self.assertEqual(str(cm.exception), "packet must have only SYN flag set")
Ejemplo n.º 2
0
    def test_data(self, mock_socket):
        data = bytes([128] * packet.MAX_LENGTH * 10)
        data_packets = packet.create_data_packets(data, 1)
        # return a different value on each call
        mock_socket.recvfrom.side_effect = [(packet.pack_packet(data_packets[0]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[1]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[2]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[3]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[4]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[5]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[6]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[7]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[8]), "127.0.0.1"),
                                            (packet.pack_packet(data_packets[9]), "127.0.0.1"),
                                            (packet.pack_packet(packet.create_fin_packet()), "127.0.0.1")]

        expected_ack = packet.create_ack_packet_from_data(data_packets[9], 0)
        r = host.Receiver(mock_socket, 10, "127.0.0.1", 10)
        r.latest_ack = packet.create_synack_packet(packet.create_syn_packet())
        r.ack_num = 1

        for i in range(11):
            r.handle_next_packet()

        mock_socket.sendto.assert_called_with(packet.pack_packet(expected_ack), ("127.0.0.1", 10))
        self.assertEqual(r.ack_num, 14611)
Ejemplo n.º 3
0
    def test_syn(self, mock_socket):
        # mock variables
        syn_packet = packet.create_syn_packet()
        mock_socket.recvfrom.return_value = (packet.pack_packet(syn_packet), "127.0.0.1")

        expected_response = packet.pack_packet(packet.create_synack_packet(syn_packet))
        r = host.Receiver(mock_socket, 10, "127.0.0.1", 10)
        r.wait_for_syn()

        mock_socket.sendto.assert_called_with(expected_response, ("127.0.0.1", 10))
Ejemplo n.º 4
0
    def test_data_timeout(self, mock_socket):
        mock_socket.recvfrom.side_effect = socket.timeout("timed out")

        latest_ack = packet.create_synack_packet(packet.create_syn_packet())
        r = host.Receiver(mock_socket, 10, "127.0.0.1", 10)
        r.latest_ack = latest_ack

        r.handle_next_packet()

        mock_socket.sendto.assert_called_with(packet.pack_packet(latest_ack), ("127.0.0.1", 10))
Ejemplo n.º 5
0
    def test_dup_syn(self, mock_socket):
        syn_packet = packet.create_syn_packet()
        mock_socket.recvfrom.side_effect = [(packet.pack_packet(syn_packet), "127.0.0.1"),
                                            (packet.pack_packet(syn_packet), "127.0.0.1")]

        expected_response = packet.pack_packet(packet.create_synack_packet(syn_packet))
        r = host.Receiver(mock_socket, 10, "127.0.0.1", 10)
        r.wait_for_syn()
        r.handle_next_packet()
        mock_socket.sendto.assert_called_with(expected_response, ("127.0.0.1", 10)) # assert_called_with = most recent call
Ejemplo n.º 6
0
    def test_synack_packet_valid(self):
        # Input: packet with SYN flag set, data len 0, seq 0 (other vars ignored)
        p = Packet(
                   packet.Type.SYN,
                   0,
                   0,
                   None)

        # Expected output: packet with
        #   sequence number: 0
        #   ack number: 1 (next expected byte)
        #   data len: 0
        #   data: none
        result = packet.create_synack_packet(p)
        self.assertEqual(result.flags, packet.Type.SYN | packet.Type.ACK)
        self.assertEqual(result.seq_num, 0)
        self.assertEqual(result.ack_num, 1)
        self.assertEqual(result.data_len, 0)
        self.assertEqual(result.data, None)
Ejemplo n.º 7
0
    def wait_for_syn(self):
        while(True):
            pkt = self.wait_for_packet(False)
            if(pkt.flags == packet.Type.FIN):
                print("received FIN packet, finishing up")
                self.is_done = True
                self.finish_status = DONE
                return
            elif(pkt.flags == (packet.Type.EOT | packet.Type.ACK)):
                print("received EOT/ACK packet while waiting for SYN; remote side didn't receive final ACK, retransmitting")
                self.sock.sendto(packet.pack_packet(packet.create_ack_packet(0, 0)), (self.emulator, self.port))
            elif(pkt.flags == packet.Type.SYN):
                break

        print("received SYN packet; responding with SYN/ACK")
        self.latest_ack = packet.create_synack_packet(pkt)
        response = packet.pack_packet(self.latest_ack)
        self.sock.sendto(response, (self.emulator, self.port))
        self.ack_num = 1
Ejemplo n.º 8
0
    def handle_next_packet(self):
        if(self.rcvd_window_bytes == (self.window_size * packet.MAX_DATA_LENGTH) or self.ack_now):
            print("sending ack {}".format(self.ack_num))
            response = packet.pack_packet(self.latest_ack)
            self.sock.sendto(response, (self.emulator, self.port))
            
            self.ack_now = False
            self.reacked = False
            self.rcvd_window_bytes = 0

            # write buffer to file and create an empty buffer
            self.file.write(self.buf)
            self.buf = bytearray()

        print("waiting for next packet...")
        rcvd = self.wait_for_packet(True)

        # wait_for_packet returns None on timeout
        if(rcvd == None):
            self.reacked = False
            if(not self.got_eot):
                # re-send last ACK
                print("timed out while waiting for packet; retransmitting ack with ack number {}".format(self.ack_num))
                response = packet.pack_packet(self.latest_ack)
                self.sock.sendto(response, (self.emulator, self.port))
            else:
                # need to resend EOT/ACK
                print("timed out while waiting for final ACK; retransmitting EOT/ACK")
                self.sock.sendto(packet.pack_packet(packet.create_eot_ack_packet()), (self.emulator, self.port))

        elif(rcvd.flags == packet.Type.SYN):
            print("received another SYN packet; responding with SYN/ACK")
            response = packet.pack_packet(packet.create_synack_packet(rcvd))
            self.sock.sendto(response, (self.emulator, self.port))

        elif(rcvd.flags == packet.Type.FIN):
            print("received FIN packet, finishing up")
            self.is_done = True
            self.finish_status = DONE

        elif(rcvd.flags == packet.Type.ACK and self.got_eot):
            print("received ACK for EOT/ACK, switching modes")
            self.is_done = True
            self.finish_status = SWITCH

        elif(rcvd.flags == packet.Type.EOT and not self.got_eot):
            print("received EOT packet, responding with EOT/ACK")
            self.sock.sendto(packet.pack_packet(packet.create_eot_ack_packet()), (self.emulator, self.port))
            self.got_eot = True

        elif(rcvd.flags == packet.Type.DATA):
            # we got a spurious retransmission
            if(rcvd.seq_num != self.ack_num):
                if(rcvd.seq_num < self.ack_num):
                    print("spurious retransmission with sequence number {}".format(rcvd.seq_num))
                    if(not self.reacked):
                        print("retransmitting ACK in response to spurious retransmission")
                        response = packet.pack_packet(self.latest_ack)
                        self.sock.sendto(response, (self.emulator, self.port))
                        self.reacked_seq_num = rcvd.seq_num
                        self.reacked = True
                    elif(rcvd.seq_num == self.reacked_seq_num):
                        print("retransmitting ACK in response to spurious retransmission")
                        response = packet.pack_packet(self.latest_ack)
                        self.sock.sendto(response, (self.emulator, self.port))
                    return
                else:
                    # != and ! < , so it's greater than the ACK number we were expecting, AKA packets were dropped (or re-ordered, but that's unlikely)
                    print("received packet with sequence number {}, packet with sequence number {} was dropped".format(rcvd.seq_num, self.ack_num))
                    return

            # the sender will always send max data unless it's almost out of data
            # in that case, we don't want to wait for the timeout
            # we should receive an EOT after this (but it shouldn't actually cause problems if not)
            if(rcvd.data_len < packet.MAX_DATA_LENGTH):
                print("packet had length {}; acking now".format(str(rcvd.data_len)))
                self.ack_now = True

            self.rcvd_window_bytes += rcvd.data_len
            self.latest_ack = packet.create_ack_packet_from_data(rcvd, self.seq_num)
            self.ack_num += rcvd.data_len
            print("received packet with sequence number {}; received {} bytes this window, current ack number is {}".format(rcvd.seq_num, self.rcvd_window_bytes, self.ack_num))
            self.buf.extend(rcvd.data)
Ejemplo n.º 9
0
                    print("{}".format(commands[args[0]]))
            else:
                print("Type help [command] to view more detail for a command")
                for cmd in command_briefs:
                    print(cmd)

        elif(command == "SYN"):
            if(args):
                print("SYN doesn't take any arguments. Sending SYN anyway")
            sock.sendto(packet.pack_packet(packet.create_syn_packet()), (dest, port))
            print("sent SYN packet to {} on port {}".format(dest, port))

        elif(command == "SYNACK"):
            if(args):
                print("SYNACK doesn't take any arguments. Sending SYN/ACK anyway")
            sock.sendto(packet.pack_packet(packet.create_synack_packet(packet.create_syn_packet())), (dest, port))
            print("sent SYN/ACK packet with to {} on port {}".format(dest, port))

        elif(command == "ACK"):
            if(len(args) != 1):
                print("usage: ACK [ack_num] (enter 'help ACK' for more)")
            else:
                sock.sendto(packet.pack_packet(packet.create_ack_packet(int(args[0]), 0)), (dest, port))
                print("sent ACK packet with ack {} to {} on port {}".format(args[0], dest, port))

        elif(command == "DATA"):
            if(len(args) != 2):
                print("usage: DATA [start_seq] [length] (enter 'help DATA' for more')")
            else:
                packets = packet.create_data_packets(bytes([128] * int(args[1])), int(args[0]))
                for p in packets: