def processMessage(self, pkt): source = pkt.sourceID (type, data) = pkt.myMessage if type == "probe" and not self.rerouting: # no data; send probeAck to source with packet delay msg = ("probeAck", float(now()) - pkt.timeSent) ack = Packet("Probe %d %d" % (self.ID, source), now(), self.ID, source, True, True, msg, self.globs) activate(ack, ack.run()) self.sendPacket(ack, self.routingTable[source]) elif type == "probeAck" and not self.rerouting: # data is packet delay over link to source self.delays[source].append(data) if len(self.delays[source]) >= self.globs.PROBE_SAMPLE_SIZE: self.initiateReroute() elif type == "reroute": # data is list of (start, end, delay) tuples; # if not rerouting, begin rerouting and broadcast delays; # send topAck to source; # process the recieved data and check if done rerouting if self.rerouting == False: self.initiateReroute() pkt = Packet("Delay Data at %d" % (self.ID), now(), self.ID, source, True, True, ("topAck", self.delayData), self.globs) activate(pkt, pkt.run()) self.sendPacket(pkt, self.routingTable[source]) if not self.haveData[source]: self.haveData[source] = True self.updateNetwork(data) if self.haveData == [True] * self.networkSize and self.haveAck == [True] * self.networkSize: self.dijkstra() elif type == "topology": # data is list of (start, end, delay) tuples; # send topAck to source and and check if done rerouting pkt = Packet("Delay Data at %d" % (self.ID), now(), self.ID, source, True, True, ("topAck", self.delayData), self.globs) activate(pkt, pkt.run()) self.sendPacket(pkt, self.routingTable[source]) if self.rerouting: if not self.haveData[source]: self.haveData[source] = True self.updateNetwork(data) if self.haveData == [True] * self.networkSize and self.haveAck == [True] * self.networkSize: self.dijkstra() elif type == "topAck" and self.rerouting: # data is list of (start, end, delay) tuples; # check if data is new and process if so; # source has recieved delay data, check if done rerouting self.haveAck[source] = True if not self.haveData[source]: self.haveData[source] = True self.updateNetwork(data) if self.haveData == [True] * self.networkSize and self.haveAck == [True] * self.networkSize: self.dijkstra()
def timerHandler(self): if not self.rerouting: for link in self.links: dst = link.end.ID if len(link.queue) >= link.bufferCapacity: # if the probe will be dropped self.delays[dst].append(self.globs.PROBE_DROP_DELAY) pkt = Packet("Probe %d %d" % (self.ID, dst), now(), self.ID, dst, True, False, ("probe", None), self.globs) activate(pkt, pkt.run()) self.sendPacket(pkt, link) else: for i in range(self.networkSize): if not self.haveAck[i]: pkt = Packet("Delay Data at %d" % (self.ID), now(), self.ID, i, True, False, ("topology", self.delayData), self.globs) activate(pkt, pkt.run()) self.sendPacket(pkt, self.routingTable[i])
def createPacket(self): message = "Packet " + str(self.currentPacketID) + "'s data goes here!" newPacket = Packet(self.currentPacketID, now(), self.ID, self.destinationID, False, False, message, self.globs) self.currentPacketID += 1 activate(newPacket, newPacket.run()) return newPacket
def initiateReroute(self): self.rerouting = True self.haveData = [False] * self.networkSize self.haveData[self.ID] = True self.haveAck = [False] * self.networkSize self.haveAck[self.ID] = True # calculate delayData self.delayData = [] for i in range(self.networkSize): delays = self.delays[i] if delays != []: self.delayData.append((self.ID, i, sum(delays)/float(len(delays)))) self.delays[i] = [] self.updateNetwork(self.delayData) # broadcast rerouting signal with new delayData for i in range(self.networkSize): if i is not self.ID: if not (self.globs.NODES[i][1] or self.globs.NODES[i][2]): # if device i is a router pkt = Packet("Delay Data at %d" % (self.ID), now(), self.ID, i, True, False, ("reroute", self.delayData), self.globs) activate(pkt, pkt.run()) self.sendPacket(pkt, self.routingTable[i]) else: # device is not a router, so don't need to communicate with it self.haveData[i] = True self.haveAck[i] = True
def createAckPacket(self): message = "Acknowledgement packet " + str(self.currentPacketIDToAck) + "'s data goes here!" # create the packet object with the needed ack packet id, source id, etc. newPacket = Packet(self.currentPacketIDToAck, now(), self.ID, self.sourceID, False, True, message, self.globs) activate(newPacket, newPacket.run()) return newPacket
def generate(self): while(True): Experiment.packet_count = Experiment.packet_count+1 addr = random.randint(0,Experiment.size-1) ipstr = "10.0."+str(addr)+".1" if(IPAddress(ipstr) in self.parent.prefix): continue p = Packet(name="packet") p.ip_dst = int(IPAddress(ipstr)) p.ip_src = self.parent.ip p.resp = False p.probe = False activate(p, p.run(self.parent)) yield hold, self, random.randint(2, 30)
def run(self): self.active = True packetIdToRetransmit = -1 # wait for startTime if this Source needs to wait before it starts to run yield hold, self, self.startTime while True: # returns id to retransmit if we have at least 3 dup acks # otherwise, returns -1 packetIdToRetransmit = self.getPacketIdToRetransmit() # first time we get 3 dup acks if self.enabledCCA and not self.fastRecovery and packetIdToRetransmit != -1: # Enter Fast Recovery if necessary self.fastRecovery = True self.ssthresh = self.windowSize / 2 self.windowSize = self.ssthresh + 3 self.dupAcks = 0 # Create a new packet based on the packetID, and resend the packet message = "Packet " + str(packetIdToRetransmit) + "'s data goes here!" newPacket = Packet(packetIdToRetransmit, now(), self.ID, self.destinationID, False, False, message, self.globs) # send this new packet activate(newPacket, newPacket.run()) self.sendPacketAgain(newPacket) # wait the needed prop delay yield hold, self, newPacket.size/float(self.link.linkRate) # resend anything, if we have packets to retransmit # (this list will be filled with timeout packets) elif len(self.toRetransmit) > 0: # returns whether or not a packet was retransmitted and if so, # the packet that was retransmitted (didtransmit, p) = self.retransmitPacket() if didtransmit: # if transmitted, wait yield hold, self, p.size/float(self.link.linkRate) # collect stats if not now() == 0: self.link.buffMonitor.observe(len(self.link.queue)) self.link.dropMonitor.observe(self.link.droppedPackets) self.sendRateMonitor.observe( self.globs.PACKET_SIZE*self.numPacketsSent / float(now())) # if everything has been sent, go to sleep elif self.globs.PACKET_SIZE * self.numPacketsSent >= self.bitsToSend: self.active = False yield passivate, self self.active = True # otherwise, send new packets! elif len(self.outstandingPackets) < self.windowSize: # send a new packet packet = self.createPacket() self.sendPacket(packet) # wait the prop delay yield hold, self, packet.size/float(self.link.linkRate) # collect stats if not now() == 0: self.link.buffMonitor.observe(len(self.link.queue)) self.link.dropMonitor.observe(self.link.droppedPackets) self.sendRateMonitor.observe(self.globs.PACKET_SIZE*self.numPacketsSent / float(now())) # nothing to retransmit and cannot send new packets, so just passivate else: self.active = False yield passivate, self self.active = True
def p_get_route(self, ip, lasthop, packet): self.ftableclean() #check for flow table matches forward_matches = filter(lambda x: (x.ip_src == packet.ip_src and x.ip_dst == packet.ip_dst), self.flow_table) reverse_matches = filter(lambda x: (x.ip_dst == packet.ip_src and x.ip_src == packet.ip_dst), self.flow_table) routes = filter(lambda x: x.match(ip) and (not x.link.destination in packet.path), self.rib)#and x.link.destination!=lasthop, self.rib) if(len(routes) == 0): routes = filter(lambda x: x.match(ip), self.rib) oldroutes = filter(lambda x: now()-x.timestamp > 300 or x.rttval == 999, routes) if(len(oldroutes)>0 and random.random() < 0.25): outroute = oldroutes[0] Experiment.old = Experiment.old + 1 else: routes.sort(key=(lambda x: x.length*x.rttval)) if Experiment.m and len(routes)>1: r1 = routes[0] r2 = routes[1] if r2.rttval - r1.rttval <= (r1.rttval/2): m1frac = 1.0*r1.m/(r1.m+r2.m) m2frac = 1.0*r2.m/(r1.m+r2.m) if(random.random() <= m2frac): outroute=r2 else: outroute=r1 else: outroute = r1 else: Experiment.current = Experiment.current + 1 outroute = routes[0] #print "forward", packet, "along", outroute, "from", routes if(len(forward_matches) > 0) and not packet.resp: f = forward_matches[0] if f.expiry == 1: f.expiry = 0 f.timestamp = now() elif f.expiry == 2: f.expiry = 1 return f.route.link else: if (now() - f.timestamp > 200 and random.random() < .25): f.expiry = 2 Experiment.packet_count = Experiment.packet_count+1 Experiment.probe_count = Experiment.probe_count+1 p = Packet(name="packet") p.ip_dst = packet.ip_dst p.ip_src = self.ip p.resp = False p.probe = True activate(p, p.run(self)) if(len(reverse_matches) > 0): Experiment.revmatch = Experiment.revmatch+1 #if(reverse_matches[0].expiry == 2): #print "ping came back" #also cool rtt = now() - reverse_matches[0].timestamp reverse_matches[0].route.rtt(rtt) self.flow_table.remove(reverse_matches[0]) else: self.flow_table.append(Flow(packet.ip_src, packet.ip_dst, now(), now(), outroute, 0)) outroute.visited = True #print "selected", outroute, "from", routes return outroute.link
def createPacket(self, packet): message = "Packet " + str(packet.packetID) + "'s data goes here!" newPacket = Packet(packet.packetID, now(), packet.sourceID, packet.desID, packet.isRouterMesg, packet.isAck, message, self.source.globs) activate(newPacket, newPacket.run()) return newPacket