예제 #1
0
파일: dsr.py 프로젝트: reidlindsay/wins
 def IPROUTING(self, fsm, p):
     """IPROUTING state; start route discovery for `p`."""
     # error messages
     dropbuffer = "sendbuffer overflow"
     # get IP/DSR/Option parameters
     ip, dsr = p[IP], p[DSRPacket]
     src, dst = ip.src, ip.dst
     # has route -> resend
     if self.hasroute(dst):
         yield fsm.goto(self.IPSEND, ip, src, dst)
     # otherwise -> start route discovery
     rre = self.rrt.getentry(dst)
     drop = rre.buffer(p)
     kwargs = {'src':src, 'dst':dst}
     kwargs['nbuffered'] = len(rre.sendbuffer)
     kwargs['timeleft']  = time2msec(rre.timeleft())
     self.debug("SENDBUFF", p, **kwargs)
     for d in drop:
         self.log_drop(d, drop=dropbuffer)
     # send RREQ
     yield fsm.goto(self.TXRREQ, dst)
예제 #2
0
파일: dsr.py 프로젝트: reidlindsay/wins
    def TXRREQ(self, fsm, target, options=[], rexmt=0):
        """TXRREQ state; create and send route request.

        :param target: Target for route discovery.
        :param options: Additional DSR options [default=None].

        :note: This state is persistent. It will keep trying to send until
        """
        # error messages
        rreqerror = "[DSR]: Error getting RREQ Table entry!"
        droprexmt = "max rexmt exceeded"
        drophasrt = "route already exists"
        # pause for jitter
        jitter = random.uniform(0,1)*self.BroadcastJitter
        yield hold, fsm, jitter
        # check route and rexmt count
        if self.hasroute(target):
            self.log("RREQSTOP", target=target, rexmt=rexmt, drop=drophasrt)
            rre = self.rrt.getentry(target)
            while rre.sendbuffer:
                p = rre.sendbuffer.pop(0)
                f = FSM.launch(self.IPRECOVER, p, self.address, target)
            self.rrt.delentry(target)
            # signal that RREQ has finished
            self.finrreq.signal(target)
            yield fsm.stop()    # HALT and stop sending RREQ
        if (rexmt>self.rrt.MaxRequestRexmt):
            self.log("RREQDROP", target=target, rexmt=rexmt, drop=droprexmt)
            rre = self.rrt.getentry(target)
            while rre.sendbuffer:
                p = rre.sendbuffer.pop(0)
                self.log_drop(p, drop=droprexmt)
            self.rrt.delentry(target)
            # signal that RREQ has been abandoned
            self.drprreq.signal(target)
            yield fsm.stop()    # HALT and stop sending RREQ
        # get RREQ parameters
        sendrreq = self.rrt.sendrreq(target)
        rre = self.rrt.getentry(target)
        tleft = rre.timeleft()
        # get parameters for logging
        kwargs = {'rexmt':rexmt, 'nbuffered': len(rre.sendbuffer)}
        kwargs['options']  = [o.tracename for o in options]
        kwargs['jitter'] = time2msec(jitter)
        kwargs['timeleft'] = time2msec(tleft)
        # cannot send RREQ? -> RREQ is busy, drop attempt
        if not sendrreq:
            self.debug("RREQBUSY", target=target, **kwargs)
            yield fsm.stop()    # HALT and allow other RREQ to finish
        # otherwise -> send RREQ
        ID, ttl = rre.ID, rre.ttl
        # create DSR+RREQ+options
        nextheader = self.getproto(None)
        dsr = DSRPacket(nextheader=nextheader)
        rreq = DSROPT_RREQ(identification=ID, target=target)
        dsr.options = [rreq] + [o for o in options]
        # create IP+DSR
        proto = self.getproto(dsr)
        src, dst = self.address, self.broadcast
        ip = IP(src=src, dst=dst, proto=proto, ttl=ttl)
        ip.add_payload(dsr)
        # send RREQ -> wait for timeout, then rexmt
        self.debug("TXRREQ", ip, target=target, **kwargs)
        f = FSM.launch(self.IPDELIVER, ip, dst)
        # signal that RREQ has been sent to target
        self.sndrreq.signal(target)
        # wait for send RREQ to timeout before trying again
        yield hold, fsm, tleft
        yield fsm.goto(self.TXRREQ, target, options, rexmt+1)