示例#1
0
 def connect(self, factory, name, port, connectionType="RAW"):
     name = str(
         name)  # force to a string in case we're accidentally given an addr
     try:
         pAddr = PlaygroundAddress.FromString(name)
     except:
         pAddr = None
     self.__trueConnectD = defer.Deferred()
     trueConnect = lambda address: self.__trueConnectD.callback(
         self.__clientBase.connect(factory, address, port, connectionType))
     if not pAddr:
         if not isinstance(self.__n2pServerAddr, PlaygroundAddress):
             try:
                 self.__n2pServerAddr = PlaygroundAddress.FromString(
                     self.__n2pServerAddr)
             except:
                 Timer.callLater(
                     .1, lambda: self.__trueConnectD.errback(
                         Exception(
                             "Could not connect to resolver. Bad address %s"
                             % self.__n2pServerAddr)))
                 return self.__trueConnectD
         srcport, self.__resolver = self.__clientBase.connect(
             N2PClient(), self.__n2pServerAddr,
             N2PServer.DEFAULT_SERVING_PORT, "SECURE_STREAM")
         d = self.__resolver.waitForConnection()
         d.addCallback(
             lambda result: self.__resolverConnected(name, trueConnect))
         d.addErrback(self.__resolverConnectFailed)
     else:
         Timer.callLater(.1, lambda: trueConnect(pAddr))
     return self.__trueConnectD
 def __checkConnectionState(self):
     if self.__connected == CONNECTED and self.__state == DATA:
         self.__processBuffer()
     elif self.__connected == CONNECTED and self.__state == FIN:
         self.transport.loseConnection()
         self.getHigherProtocol().connectionLost("Sent FIN, Timed out")
     else:
         Timer.callLater(0.05, lambda:self.__checkConnectionState())
示例#3
0
 def retransmit(self, seqNum, sMessage):
     if not self.state == "CLOSED":
         if seqNum in [x[0] for x in self.unacknowledgedSent]:
             i = [x[0] for x in self.unacknowledgedSent].index(seqNum)
             self.unacknowledgedSent[i][2] = Timer.callLater(self.timeout, self.retransmit, seqNum, sMessage)
             logger.debug("RIP--Retransmitting packet %d", seqNum)
             self.lowerTransport().write(sMessage)
示例#4
0
    def __ptclMessageHandler(self, protocol, msg):
        ##print "I have received a message from the network, checking it's sanity:"
        msgObj = msg.data()
        # first compare the hashes.
        sane = self.sanity(msg)
        if sane:
            ##print "packet is sane"
            pass
        else:
            ##print "packet is insane"
            return 0

        # Bifurcate the code flow based on the message type
        # handleConnectionMessages takes care of SYN/SYNACK/ACK/FIN/FINACK
        # handleDataAck handles the ACKs sent to acknowledge successful data delivery
        # handleDataRcvMessage handles the data messages
        if msgObj.MessageType == "SYN":
            #DO This
            ##print "I got a SYN \n"
            self.__handleConnectionMessages(1, msgObj)
            # TO DO check for current state.

        elif msgObj.MessageType == "SYNACK":
            #Do this
            ##print "I got a SYNACK \n"
            self.__handleConnectionMessages(2, msgObj)

        elif msgObj.MessageType == "ACK":
            #DO This
            ##print "I got an ACK \n"
            if (self.__connected):
                ##print "For connected connection"
                self.__handleAck(msgObj)
            else:
                ##print "For unconnected connection"
                self.__handleConnectionMessages(3, msgObj)

        elif msgObj.MessageType == "DATA":
            #Fixed : would allow a DATA packet to be processed directly without a connection
            ##print "I got DATA \n"
            self.__data_timer = Timer.OneshotTimer(lambda: self.checkData())
            if (self.__connected == 1):
                self.__handleDataRcvMessage(msgObj)
            else:
                pass
                ##print "No connection present aborting"

        elif msgObj.MessageType == "FIN":
            #Do This
            ##print "I got a FIN \n"
            self.__handleConnectionMessages(6, msgObj)

        elif msgObj.MessageType == "FINACK":
            #Do this
            ##print "I got a FINACK"
            self.__handleConnectionMessages(8, msgObj)

        else:
            #TODO - Do nothing - log it - ##print something to screee/log
            return 0
 def write(self, serialized_msg_from_top):
     #print "write"
     self.__pushToList(serialized_msg_from_top)
     logger.info("Message put in buffer, checking connection state")
     if (self.__connected == NOTCONNECTED): # No existing connection initiating handshake
         logger.info("PSST Handshake: Starting handshake")
         self.__initiateHandshake()
         Timer.callLater(0.05, lambda:self.__checkConnectionState())
     elif (self.__connected == HANDSHAKE): # Handshake still not complete, buffer the messages
         logger.info("PSST Handshake: Handshake not complete")
         Timer.callLater(0.05, lambda:self.__checkConnectionState())
     elif (self.__connected == CONNECTED):
         logger.info("PSST Handshake: Hanshake now complete, ready to send buffered messages")
         self.__processBuffer()
     else:
         logger.debug("PSST Handshake: Unknown connected state reached")
示例#6
0
    def writeSignedMessage(self, rMessage, shouldRetransmit):
        if self.idleTimeout:
            self.resetTimeout()
        else:
            self.initTimeout()
        rMessage.sequence_number = self.nextSequenceNumber
        rMessage.sessionID = self.sessionID
        rMessage.signature = ""
        unsignedMessage = rMessage.__serialize__()
        sig = self.sign(unsignedMessage)
        rMessage.signature = sig
        sMessage = rMessage.__serialize__()
        if len(rMessage.data) == 0:
            if not rMessage.acknowledgement_flag or rMessage.sequence_number_notification_flag:
                self.nextSequenceNumber = self.nextSequenceNumber + 1
        else:
            self.nextSequenceNumber = self.nextSequenceNumber + len(rMessage.data)

        if len(self.unacknowledgedSent) >= self.maxSent and not rMessage.acknowledgement_flag:
            self.sendOverflow.append((self.nextSequenceNumber, sMessage, shouldRetransmit))
        else:
            self.lowerTransport().write(sMessage)
            if shouldRetransmit:
                callNum = Timer.callLater(self.timeout, self.retransmit, self.nextSequenceNumber, sMessage)
                self.unacknowledgedSent.append([self.nextSequenceNumber, sMessage, callNum])
示例#7
0
    def __handleDataRcvMessage(self, msgObj):
        if (self.__connected == 0):
            ##print "Connection Not Established Yet"
            return
        self.__state = 4
        self.__exp_backoff = 0.05
        # Fixed : If server responds, it will not go through connection set up again and hence last_contig needs to be set to
        # the seq number of the first data packet by server - 1 so that the system does not break
        if self.__connected == 1 and self.__last_contig == 0:
            self.__last_contig = msgObj.MessageSeq - 1

        ##print "I have received Data, with serial number: ",msgObj.MessageSeq
        #if msgObj.MessageSeq <= self.__last_contig or msgObj.MessageSeq == 0:
        if msgObj.MessageSeq <= self.__curr_ackSeq or msgObj.MessageSeq == 0:
            ##print "Message is stale or has sequence 0, discard"
            return
        pushed = self.push_to_rcv_window(msgObj.MessageSeq, msgObj)
        if (pushed):
            pass
            ##print "Message pushed to window successfully"
        else:
            pass
            ##print "Pushing to window unsuccessful - either msgseq too big or too small"
        #self.__curr_ackSeq = msgObj.MessageSeq
        # Check if the packet received is the next contiguous packet, if it is check if it
        # completes a sequence, send the maximum number of contiguous packets up the layer
        # and slide the data rcv window
        logger.info("Harsh: " + str(self._addr) +
                    " Got data on the receiver with sequence number: " +
                    str(msgObj.MessageSeq) +
                    " expected contiguous sequence number is :" +
                    str(self.__curr_ackSeq + 1))  #str(self.__last_contig+1))
        #if (msgObj.MessageSeq == self.__last_contig+1):

        if (msgObj.MessageSeq == self.__curr_ackSeq + 1):
            #logger.info("Harsh: "+str(self._addr)+" Got data on the receiver with contiguous sequence number: "+str(msgObj.MessageSeq))
            # TODO: Find a way to reset the timer.
            ##print "Got the next contig packet resetting the timer"
            #print "Cancelled hb_timer"
            self.__hb_timer.cancel()
            #print "Restarted hb_timer"
            self.__hb_timer = Timer.OneshotTimer(lambda: self.checkData())
            self.__hb_timer.run(0.05)
            for seq in range(0, RCVWINDOW):
                if self.__rcvWindow[seq][0] == -1:
                    # reached end of max contiguous list present
                    break
            # set last contig as the maximum contig seq number present in rcv window and acknowledge that packet
            #self.__last_contig = self.__rcvWindow[seq-1][0]
            #self.__curr_ackSeq = self.__last_contig
            self.__curr_ackSeq = self.__rcvWindow[seq - 1][0]
            # print "Sending an ack with seq number: ",self.__currSeq, "and ack-ing max contiguously received seq number: ",self.__last_contig
            self.__handleConnectionMessages(7, msgObj)
            #Do window sliding
            for i in range(0, seq):
                rawData = self.__rcvWindow[i][1].Data
                ##print "Now Passing Data up the layer"
                self.getHigherProtocol().dataReceived(rawData)
            self.slideRcvWindow(i + 1)
示例#8
0
 def transmitOverflow(self):
     self.sendOverflow.sort()
     while len(self.unacknowledgedSent) < self.maxSent and len(self.sendOverflow) > 0:
         seqNum, sMessage, shouldRetransmit = self.sendOverflow.pop()
         self.lowerTransport().write(sMessage)
         if shouldRetransmit:
             callNum = Timer.callLater(self.timeout, self.retransmit, seqNum, sMessage)
             self.unacknowledgedSent.append([seqNum, sMessage, callNum])
示例#9
0
 def start(self, clientBase, args):
     self.clientBase = clientBase
     result, msg = True, ""
     if "start_server" in args:
         mobileCodeServer = playground.network.client.sampleservers.ClientMobileCodeServer(
         )
         result = clientBase.listen(mobileCodeServer, 100)
         if result == True:
             self.serving = True
         else:
             msg = "Could not start server"
     if "start_client" in args:
         print "start client"
         computePi = ComputePi(
             clientBase,
             playground.network.client.sampleservers.MobileCodeClient())
         Timer.callLater(0, lambda: computePi.start(10000000))
         self.client = computePi
     if not self.serving and not self.client:
         result, msg = False, "computePi requires either 'start_server', 'start_client', or both"
     return result, msg
示例#10
0
 def checkData(self):
     ###print "Inside checkData that means I did not get a new Data Message"
     ###print "Re sending ack for last contiguous packet"
     if (self.__finhandshake == 1):
         ##print "Connection Ending no need to send handshake"
         return None
     self.__exp_backoff *= 2
     if self.__exp_backoff >= 10:
         self.__exp_backoff = 10
     self.__handleConnectionMessages(7)
     self.__hb_timer = Timer.OneshotTimer(lambda: self.checkData())
     self.__hb_timer.run(self.__exp_backoff)
示例#11
0
 def checkWindow(self):
     if self.__dataList != [] or self.__window != []:
         #if self.__fin_timer:
         #   self.__fin_timer.cancel()
         self.__fin_timer = Timer.OneshotTimer(lambda: self.checkWindow())
         self.__fin_timer.run(0.1)
     else:
         if self.__connected == 1:
             if self.__finhandshake == 0:
                 self.__finhandshake = 1
                 self.__handleConnectionMessages(5)
             else:
                 pass
         else:
             pass
示例#12
0
    def __handleAck(self, msgObj):
        self.__session_timer.cancel()
        self.__session_timer = Timer.OneshotTimer(lambda: self.checkSession())
        self.__session_timer.run(35)
        if self.__window == []:
            ##print "The window is empty, probably keep alive ACKs"
            pass
        next_expected = self.top('Win')
        if msgObj.AckSeq < next_expected - 1:
            ##print "Delayed/Duplicate ACK, discarding"
            return
        ##print "I have received ACK for the data I sent, ack :",msgObj.AckSeq
        # Move the window forward if the seq number being ACK'd is the first
        # or higher in the list.Accodingly move the dataQueue forward too

        # If the ack'd packet is less than the first packet in the window check
        # if the ACK'd sequence is adjacent to the sequence at Window[0]. If yes
        # that means you have to send Window[0] again.
        # Else just discard the ACK as it is a delayed ACK.
        if (self.__window != [] and msgObj.AckSeq >= next_expected):
            logger.info(
                "Harsh: " + str(self._addr) +
                " Got the ACK on the sender, sliding window, seq no rcvd: " +
                str(msgObj.AckSeq))
            self.slideDataQueue(msgObj.AckSeq - (self.top('Win')) + 1)
            self.slideWindow(msgObj.AckSeq)
        else:
            if (msgObj.AckSeq == next_expected - 1):
                logger.info("Harsh: " + str(self._addr) +
                            " Need to resend data with seq: " +
                            str(next_expected))
                # Resend packet at window[0]
                ##print "Resending AckSeq+1th packet"
                #print "Helloo Helloo"
                #print "This is the data am sending: ",self.top('Data').__hash__()," this is the sequence ",self.top('Win')
                self.wrap_send_buffer(self.top('Data'), self.top('Win'))
示例#13
0
 def checkSession(self):
     #print "I have been waiting for 35 seconds. this shit is not worth it.. I am leaving.."
     Timer.callLater(
         0.1, lambda: self.getHigherProtocol().connectionLost(
             "Connection Lost Due to Inactivity"))
 def __initiateFIN(self):
     hmac = self.__generateHMAC(self.__sym_key, "FIN")
     fin_msg = self.__buildDataMessage("FIN", hmac, "")
     self.__send(fin_msg)
     self.__state = FIN
     Timer.callLater(2,lambda:self.__checkConnectionState())
示例#15
0
 def __generalFailure(self, e):
     self.transport.write("Got error: %s\n" % e)
     Timer.callLater(.1, self.shutdown)
     return Failure
示例#16
0
    def __handleConnectionMessages(self, state, msgObj=None):
        if state == 0:
            self.__state = 0
            self.__connected = 0
            self.__handshake = 1
            self.__currSeq = random.getrandbits(32)
            ##print "Preparing to send a SYN Message"
            ##print "The sequence number I am sending is :", self.__currSeq
            responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage)
            responseMessageBuilder["Hash"].setData('0')
            responseMessageBuilder["MessageType"].setData("SYN")
            responseMessageBuilder["MessageSeq"].setData(self.__currSeq)
            responseMessageBuilder["AckSeq"].setData(0)
            responseMessageBuilder["Data"].setData("")
            # TODO Calculate the hash of the whole packet created above
            # and fill it in the HASH field of the packet
            msg_hash = self.hash_it(responseMessageBuilder)
            responseMessageBuilder["Hash"].setData(msg_hash)
            self.__waiting = 1
            self.transport.writeMessage(responseMessageBuilder)
            Timer.callLater(0.1, lambda: self.checkState(0))

        elif state == 1:
            # Server state where server received a SYN packet and will now send an SYNACK
            if (self.__state == 3 or self.__state == 2):
                ##print "Already Connected"
                return
            ##print "I have got a SYN and will now Send a SYNACK"
            self.__state = 1
            self.__currSeq = random.getrandbits(32)
            #self.__curr_ackSeq = msgObj.MessageSeq
            ##print "The sequence number I got in the SYN is : ",msgObj.MessageSeq,"and the sequence number I am sending in the SYNACK is: ", self.__currSeq
            if (msgObj != None):
                self.__curr_ackSeq = msgObj.MessageSeq

                logger.debug(
                    "Harsh: %s Hey! We got our SYN, setting curr_ackSeq to %d"
                    % (self._addr, self.__curr_ackSeq))
                #Prepare and send a SYNACK Message
                responseMessageBuilder = MessageData.GetMessageBuilder(
                    PTCLMessage)
                responseMessageBuilder["Hash"].setData('0')
                responseMessageBuilder["MessageType"].setData("SYNACK")
                responseMessageBuilder["MessageSeq"].setData(self.__currSeq)
                responseMessageBuilder["AckSeq"].setData(self.__curr_ackSeq)
                responseMessageBuilder["Data"].setData("")
                msg_hash = self.hash_it(responseMessageBuilder)
                responseMessageBuilder["Hash"].setData(msg_hash)
                self.transport.writeMessage(responseMessageBuilder)
                Timer.callLater(0.1, lambda: self.checkState(1))
        elif state == 2:
            if (self.__state >= 2):
                ##print "Multiple SYNACK, Discard"
                return
            self.__state = 2
            ##print "I have got a SYNACK and will now send an ACK followed by data"
            ##print "The sequence number I got is : ",msgObj.MessageSeq, "and the sequence number i am sending is : ", self.__currSeq
            # Extract sequence number and set state variable
            self.__curr_ackSeq = msgObj.MessageSeq
            logger.debug(
                "Harsh: %s Hey! We got our SYNACK, setting curr_ackSeq to %d" %
                (self._addr, self.__curr_ackSeq))
            #Prepare and send an ACK Message
            responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage)
            responseMessageBuilder["Hash"].setData('0')
            responseMessageBuilder["MessageType"].setData("ACK")
            responseMessageBuilder["MessageSeq"].setData(0)
            responseMessageBuilder["AckSeq"].setData(msgObj.MessageSeq)
            responseMessageBuilder["Data"].setData("")
            #TODO Calculate the hash of the whole packet created above
            # and fill it in the HASH field of the packet
            msg_hash = self.hash_it(responseMessageBuilder)
            responseMessageBuilder["Hash"].setData(msg_hash)
            self.transport.writeMessage(responseMessageBuilder)
            ##print "sent an ACK , we are connected ,now sending Data:"
            ##print "Setting connected in client"
            self.__handshake = 1
            self.__connected = 1

            #self.__last_contig = self.__curr_ackSeq
            #set the timer
            #No timer because now data has to be sent, after sending ACK you don't
            # wait and start pushing data directly
            ##print "Sent Data"
            #print "Setting hb timer on receiver"
            self.__hb_timer = Timer.OneshotTimer(lambda: self.checkData())
            self.__hb_timer.run(10)
            Timer.callLater(0.1, lambda: self.processQueue())
            self.__session_timer = Timer.OneshotTimer(
                lambda: self.checkSession())
            self.__session_timer.run(35)
            #Timer.callLater(0.1,lambda:self.checkState(2,msgObj))
            #Check if the state has looped back to the same state. Store the current time
            # and check if it has changed after timeout
        elif state == 3:
            # Server side state, once server has received ACK from Client in response to SYNACK
            self.__state = 3
            # Extract sequence number, check and set state variable
            ##print "I have got an ACK"

            #self.__currSeq = self.__currSeq +1
            ##print "Setting connected in server"
            self.__connected = 1
            self.__handshake = 1
            self.__last_contig = msgObj.MessageSeq
            ##print "The sequence number I got is: ", msgObj.MessageSeq
            #print "Setting hb timer on sender"
            self.__hb_timer = Timer.OneshotTimer(lambda: self.checkData())
            self.__hb_timer.run(10)
            self.__session_timer = Timer.OneshotTimer(
                lambda: self.checkSession())
            self.__session_timer.run(35)

        elif state == 5:
            self.__state = 5
            # Extract sequence number and set state variable
            ##print "I am going to send a FIN Message"
            self.__currSeq = self.__currSeq + 1
            #Prepare and send an FIN Message
            responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage)
            responseMessageBuilder["Hash"].setData('0')
            responseMessageBuilder["MessageType"].setData("FIN")
            responseMessageBuilder["MessageSeq"].setData(self.__currSeq)
            responseMessageBuilder["AckSeq"].setData(0)
            responseMessageBuilder["Data"].setData("")
            #TODO Calculate the hash of the whole packet created above
            # and fill it in the HASH field of the packet
            msg_hash = self.hash_it(responseMessageBuilder)
            responseMessageBuilder["Hash"].setData(msg_hash)
            self.transport.writeMessage(responseMessageBuilder)
            #set the timer
            self.__timely = Timer.callLater(0.1, lambda: self.checkState(5))
        elif state == 6:
            ##print "I got a FIN Message and I will send a FINACK"
            self.__finhandshake = 1
            self.__state = 6
            self.__curr_ackSeq = msgObj.MessageSeq
            #Prepare and send an FINACK Message
            responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage)
            responseMessageBuilder["Hash"].setData('0')
            responseMessageBuilder["MessageType"].setData("FINACK")
            responseMessageBuilder["MessageSeq"].setData(0)
            responseMessageBuilder["AckSeq"].setData(self.__curr_ackSeq)
            responseMessageBuilder["Data"].setData("")
            #TODO Calculate the hash of the whole packet created above
            # and fill it in the HASH field of the packet
            msg_hash = self.hash_it(responseMessageBuilder)
            responseMessageBuilder["Hash"].setData(msg_hash)
            ##print "Sending FINACK now: "
            self.transport.writeMessage(responseMessageBuilder)
            Timer.callLater(
                0.1, lambda: self.getHigherProtocol().connectionLost(
                    "Received FIN"))
            self.transport.loseConnection()
            self.__connected = 0
        elif state == 7:
            ###print "I am suppose to send an ACK for data received:"
            responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage)
            responseMessageBuilder["Hash"].setData('0')
            responseMessageBuilder["MessageType"].setData("ACK")
            responseMessageBuilder["MessageSeq"].setData(0)
            logger.info("Harsh: %s Sending ACK with ACK Sequence %d" %
                        (self._addr, self.__curr_ackSeq))
            responseMessageBuilder["AckSeq"].setData(self.__curr_ackSeq)
            # There is no data being piggy bagged on the ACK , if required put the data here from the
            # buffer where it is stored.
            responseMessageBuilder["Data"].setData("")
            responseMessageBuilder["Hash"].setData(
                self.hash_it(responseMessageBuilder))
            self.transport.writeMessage(responseMessageBuilder)
        elif state == 8:
            self.__state = 8
            self.__currSeq = 0
            self.__curr_ackSeq = 0
            ##print "I received a FINACK - Trying to terminate connection"
            ##print "dataList and rcvWindow are both empty, safe to terminate, connectionLost() called"
            Timer.callLater(
                0.2, lambda: self.getHigherProtocol().connectionLost(
                    "Received FINACK"))
            self.transport.loseConnection()
            if self.__timely:
                self.__timely.cancel()
            self.__connected = 0
        else:
            pass
示例#17
0
 def initTimeout(self):
     self.idleTimeout = Timer.callLater(self.idleTimeoutPeriod, self.timeoutExpired)
示例#18
0
 def loseConnection(self):
     self.__fin_timer = Timer.OneshotTimer(lambda: self.checkWindow())
     self.__fin_timer.run(0.1)
     #start FIN sequence
     """