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)
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)