示例#1
0
    def handshake_client(self):
        established = False
        server = self.host, self.port

        while not established:
            self.conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

            logging.debug("(Starting Handshake)")
            syn_pkt = make_ack(SYN, 0, server)
            logging.debug(f'(client->{server}):{syn_pkt}:Sending SYN')
            self.conn.sendto(syn_pkt.to_bytes(), self.router)
            # TODO timeout
            self.conn.settimeout(TIMEOUT)
            try:
                raw_packet, router = self.conn.recvfrom(1024)
            except socket.timeout:
                logging.debug(f'(client->{server}):Timeout, either SYN dropped or SYN-ACK dropped')
                continue
            p = Packet.from_bytes(raw_packet)
            if p.packet_type == SYN_ACK:
                logging.debug(f'({server}->client):{p}:Received SYN_ACK')
                established = True
                ack_pkt = make_ack(ACK, 0, server)
                logging.debug(f'(client->{server}):{ack_pkt}:Send ACK')
                self.conn.sendto(ack_pkt.to_bytes(), router)
                logging.debug("(Handshake Finished)")
                return established
示例#2
0
    def send_response(self, client, packet, router, server):
        if packet.packet_type == ACK:
            # check if all packets have received acks
            self.validate_ack(client, packet, server)
        else:
            # make response into packets and send them

            # combine packets to data
            payload = [self.clients[client]["request"][p].payload for p in
                       sorted(self.clients[client]["request"].keys())]
            raw_request = b''.join(payload)
            logging.debug(f'(request) {raw_request}')

            # make http response
            if len(raw_request) == 0:
                response = make_http_response([], 'Bad Request', 400)
            else:
                request = parse_http_request(raw_request)  # Get a parsed HTTP request
                # Invoke get or post handler based on the request type
                request_handler = getattr(self, 'handle_%s' % request["method"])
                response = request_handler(request)
            logging.debug(f'(response) {response.encode("utf-8")}')

            # send http response
            packets = split_data_into_packets(response, client)
            fin_pkt = make_ack(FIN, len(packets) + 1, client)
            packets.append(fin_pkt)
            for j in range(math.ceil(len(packets)/WINDOW)):
                for p in packets[WINDOW*j:WINDOW*(j+1)]: #packets
                    logging.debug(f'({server}->{client}):{p}:Sending response packet')
                    self.conn.sendto(p.to_bytes(), router)
                    # store packets in dict, later use that dict for checking acks
                    self.clients[client]["response"][p.seq_num] = p
            self.conn.settimeout(TIMEOUT)
示例#3
0
    def send_request(self, request):
        server = self.host, self.port

        # send request packets
        packets = split_data_into_packets(request, server)
        fin_pkt = make_ack(FIN, len(packets) + 1, server)
        packets.append(fin_pkt)
        for j in range(math.ceil(len(packets) / WINDOW)):
            for p in packets[WINDOW * j:WINDOW * (j + 1)]:  # packets
                logging.debug(f'(client->{server}):{p}:Send Request Packet')
                self.conn.sendto(p.to_bytes(), self.router)
                # store packets in dict, later use that dict for checking acks
                self.communication["request"][p.seq_num] = p

        # validate acks for request packets
        while True:
            try:
                raw_packet, router = self.conn.recvfrom(1024)
            except socket.timeout:
                for key in self.communication["request"].keys():
                    logging.debug(
                        f'(client->{server}):{self.communication["request"][key]}:Timeout, resending Request Packet')
                    self.conn.sendto(self.communication["request"][key].to_bytes(), self.router)
                continue
            packet = Packet.from_bytes(raw_packet)
            if packet.packet_type == SYN_ACK:
                logging.debug(
                    f'({server}->client):{packet}:Received SYN_ACK (Server didn"t receive ACK from handshake)')
                ack_pkt = make_ack(ACK, 0, server)
                logging.debug(f'(client->{server}):{ack_pkt}:Send ACK')
                self.conn.sendto(ack_pkt.to_bytes(), router)
                logging.debug("(Handshake Finished)")
                return False
            if packet.seq_num in self.communication["request"]:
                logging.debug(f'({server}->client):{packet}:ACK received')
                # remove a request packet from dict if ack is received
                del self.communication["request"][packet.seq_num]

                # if no packets in response dict, all the packets have been sent
                is_response_complete = len(self.communication["request"]) == 0
                if is_response_complete:
                    logging.debug(f'(client->{server}):Request Finished')
                    # close connection
                    return True
            else:
                logging.debug(f'({server}->client):{packet}: Duplicate ACK received, ignoring it')
示例#4
0
 def handshake_server(self, client, packet, router, server):
     if packet.packet_type == SYN:
         logging.debug(f'({client}->{server}):{packet}:Received SYN')
         # send syn-ack
         syn_ack_pkt = make_ack(SYN_ACK, packet.seq_num, client)
         logging.debug(f'({server}->{client}):{syn_ack_pkt}:Sending SYN-ACK')
         self.conn.sendto(syn_ack_pkt.to_bytes(), router)
     if packet.packet_type == DATA:
         logging.debug(
             f'({client}->{server}):{packet}:Received data, without handshake -> client"s ACK lost, send SYN-ACK')
         syn_ack_pkt = make_ack(SYN_ACK, packet.seq_num - 1, client)
         self.conn.sendto(syn_ack_pkt.to_bytes(), router)
     if packet.packet_type == ACK:
         # add sender to connections
         logging.debug(f'({server}->{client}):Received ACK, Connection Established')
         self.clients[client] = {
             "request": {},
             "response": {}
         }
示例#5
0
 def recieve_request(self, client, packet, router, server):
     # receive packets
     ack_pkt = make_ack(ACK, packet.seq_num, client)
     if packet.packet_type == DATA:
         if packet.seq_num in self.clients[client]["request"]:
             # duplicate seq num detected send ack
             logging.debug(f'({server}->{client}):{ack_pkt}:Duplicate detected, Sending ACK')
         else:
             # add received packet to request dict and send ack
             self.clients[client]["request"][packet.seq_num] = packet
             logging.debug(f'({server}->{client}):{ack_pkt}:Received data packet, Sending ACK')
     if packet.packet_type == FIN:
         # last packet recieved, use seq num to store packets length
         logging.debug(f'({server}->{client}):{ack_pkt}:Received FIN, Sending ACK')
         self.clients[client]["request_length"] = packet.seq_num - 1
     # send ack to client  for the current packet
     self.conn.sendto(ack_pkt.to_bytes(), router)
示例#6
0
    def receive_response(self):
        server = self.host, self.port
        self.conn.settimeout(None)
        # receive packets
        while True:
            is_receive_complete = "response_length" in self.communication and self.communication[
                "response_length"] == len(
                self.communication["response"])

            if is_receive_complete:
                self.conn.settimeout(4*TIMEOUT)

            try:
                raw_packet, sender = self.conn.recvfrom(1024)
            except socket.timeout:
                logging.debug(f'(Received Response)')
                self.conn.settimeout(None)
                break
            packet = Packet.from_bytes(raw_packet)
            ack_pkt = make_ack(ACK, packet.seq_num, server)
            if packet.packet_type == DATA:
                if packet.seq_num in self.communication["response"]:
                    # duplicate seq num detected send ack
                    logging.debug(f'(client->{server}):{ack_pkt}:Duplicate detected, Sending ACK')
                else:
                    # add received packet to request dict and send ack
                    self.communication["response"][packet.seq_num] = packet
                    logging.debug(f'(client->{server}):{ack_pkt}:Received data packet, Sending ACK')
            if packet.packet_type == FIN:
                # last packet recieved, use seq num to store packets length
                logging.debug(f'(client->{server}):{ack_pkt}:Received FIN, Sending ACK')
                self.communication["response_length"] = packet.seq_num - 1
            # send ack to client  for the current packet
            self.conn.sendto(ack_pkt.to_bytes(), self.router)

        # combine packets to data

        payload = [self.communication["response"][p].payload for p in sorted(self.communication["response"].keys())]
        raw_response = b''.join(payload)
        logging.debug(f'(response) {raw_response}')
        return raw_response