def receive(self, packet): """Receives a packet. Based on its message, returns a response packet.""" # Reads basic data from received packet clientIp = packet.getOriginIp() segment = packet.getSegment() clientPort = segment.getOriginPort() msg = packet.getSegment().getMessage() # Adjusts ack and seq numbers ackNumber = segment.getSeqNumber() + segment.getMessageSize() seqNumber = segment.getAckNumber() # Received a SYN packet; establish connection with client if segment.getSYN() is True: clientIp = packet.getOriginIp() synSegment = TcpSegment("", self.serverPort, clientPort) synSegment.setSYN() synSegment.setACK() synSegment.setAckNumber(1) synSegment.setSeqNumber(seqNumber) return IpDatagram(synSegment, self.serverIp, clientIp) # Received a FIN packet; close connection with client elif segment.getFIN() is True: clientIp = packet.getOriginIp() finSegment = TcpSegment("", self.serverPort, clientPort) finSegment.setFIN() finSegment.setACK() finSegment.setAckNumber(ackNumber + 1) finSegment.setSeqNumber(seqNumber) return IpDatagram(finSegment, self.serverIp, clientIp) # Received an ACK packet; do nothing elif msg == "": return None # Packet contains a message from the client; # send an ACK packet and a message packet # ACK packet ackSegment = TcpSegment("", self.serverPort, clientPort) ackSegment.setACK() ackSegment.setAckNumber(ackNumber) ackSegment.setSeqNumber(seqNumber) ackPacket = IpDatagram(ackSegment, self.serverIp, clientIp) # Response packet (contains a non-empty message) respMessage = self.__parseMessage([clientIp, clientPort], msg) respSegment = TcpSegment(respMessage, self.serverPort, clientPort) respSegment.setACK() respSegment.setAckNumber(ackNumber) respSegment.setSeqNumber(seqNumber) respPacket = IpDatagram(respSegment, self.serverIp, clientIp) return [ackPacket, respPacket]
def __dnsConnect(self, name): """Connects to the DNS server to obtain the given name's corresponding IP.""" segment = UdpSegment(name, 2000, self.dnsPort) datagram = IpDatagram(segment, self.ipAddr, self.dnsAddr) datagram.setId(self.__nextPacketId()) self.link.putTargetQueue(datagram) packet = self.netQueue.get() ip = packet.getSegment().getMessage().split(',')[1] self.netQueue.task_done() return ip
def __tcpEstablishConnection(self, serverIp): """Establishes a TCP connection by doing a handshake with the server.""" clientPort = random.randint(1025, 65530) # Sends a SYN message to establish connection segment = TcpSegment("", clientPort, self.ircPort) segment.setSYN() datagram = IpDatagram(segment, self.ipAddr, serverIp) datagram.setId(self.__nextPacketId()) self.link.putTargetQueue(datagram) packet = self.netQueue.get() # Receives packet containing server's SYN segment = TcpSegment("", clientPort, self.ircPort) segment.setAckNumber(packet.getSegment().getAckNumber()) segment.setACK() segment.setSeqNumber(1) segment.setSeqNumber(1) datagram = IpDatagram(segment, self.ipAddr, packet.getOriginIp()) self.netQueue.task_done() datagram.setId(self.__nextPacketId()) self.link.putTargetQueue(datagram) # Defines the randomized client port number self.application.setClientPort(clientPort)
def receive(self, packet): """Receives and parses a packet from the IRC server.""" segment = packet.getSegment() msg = segment.getMessage() # Packet contains a message from the server; # first, read message contained in the packet # Received CONNECT confirmation if msg[0] == '0': self.serverIp = packet.getOriginIp() # Received USER confirmation elif msg[0] == '1': pass # Received QUIT confirmation elif msg[0] == '2': self.mustClose = True # Then, create and send an ACK packet ackSegment = TcpSegment("", self.clientPort, self.serverPort) # Adjusts ack and seq numbers self.ackNumber = segment.getSeqNumber() + segment.getMessageSize() self.seqNumber = segment.getAckNumber() ackSegment.setACK() ackSegment.setAckNumber(self.ackNumber) ackSegment.setSeqNumber(self.seqNumber) ackPacket = IpDatagram(ackSegment, self.clientIp, self.serverIp) if self.mustClose: self.mustClose = False finSegment = TcpSegment("", self.clientPort, self.serverPort) finSegment.setFIN() finSegment.setAckNumber(self.ackNumber) finSegment.setSeqNumber(self.seqNumber) finPacket = IpDatagram(finSegment, self.clientIp, self.serverIp) self.clientPort = None self.serverIp = None return [ackPacket, finPacket] return ackPacket
def __tcpCloseConnection(self, finalPacket): """Close TCP connection by doing a handshake with the server.""" serverIp = finalPacket.getDestinationIp() clientPort = finalPacket.getSegment().getOriginPort() # Sends a FIN/ACK message to close connection packet = self.netQueue.get() # Receives packet containing server's SYN segment = TcpSegment("", clientPort, self.ircPort) segment.setAckNumber(packet.getSegment().getAckNumber()) segment.setACK() segment.setSeqNumber(packet.getSegment().getAckNumber()) segment.setAckNumber(packet.getSegment().getSeqNumber() + 1) datagram = IpDatagram(segment, self.ipAddr, packet.getOriginIp()) self.netQueue.task_done() datagram.setId(self.__nextPacketId()) self.link.putTargetQueue(datagram)
def receive(self, packet): """Receives a packet asking for the IP of a name address. Returns a packet with the desired IP.""" if self.dnsTable is None: raise Exception("DNS table not defined in the server!") name = packet.getSegment().getMessage() ip = self.dnsTable[name] segment = UdpSegment(name + ',' + ip, self.port, packet.getSegment().getOriginPort()) datagram = IpDatagram(segment, self.serverIp, packet.getOriginIp()) return datagram
def send(self, msgList): """Sends the specified message to an IRC server This method supposes that the message is correct!.""" msg = ' '.join(msgList) if msgList[0] == self.CONNECT: self.ackNumber = self.seqNumber = 1 self.serverIp = msgList[1] if self.serverIp is None: raise Exception("IRC client must CONNECT first!") segment = TcpSegment(msg, self.clientPort, self.serverPort) segment.setACK() segment.setAckNumber(self.ackNumber) segment.setSeqNumber(self.seqNumber) datagram = IpDatagram(segment, self.clientIp, self.serverIp) return datagram