def process(self): if (self.link.buf_processing or self.link.buffer_empty()): return else: self.link.buf_processing = True assert (self.link.buffer_empty() == False) packet, src = self.link.buffer_get() send_time = packet.size / self.link.rate + self.link.prop_delay receiver = self.link.get_receiver(src) enqueue(ReceivePacket(self.start_time + send_time, packet, \ self.link, receiver)) next_pkt, next_src = self.link.buffer_peek() if next_src is not None: next_dest = self.link.get_receiver(next_src) else: next_dest = None # if next_dest is None or self.link.curr_recipient != next_dest: if next_dest is not None and self.link.curr_recipient != next_dest and HALF_DUPLEX: self.link.curr_recipient = next_dest done_time = packet.size / self.link.rate + self.link.prop_delay else: done_time = packet.size / self.link.rate enqueue( BufferDoneProcessing(self.start_time + done_time, self.link))
def receive(self, pkt, time): # Pass ACKs to flows to handle congestion control and dropped packets if (isinstance(pkt, packet.Ack)): pkt.flow.receiveAck(pkt, time) else: # Only send ACKs for packets we have not yet recieved # (next_pkt = pkt.number) or packets out of order # (next_pkt < pkt.number). # If first packet from flow, then set expected_pkt to 0. if self.expected_pkt.setdefault(pkt.flow.id, 0) <= pkt.number: # If the packet is the one we're expecting, # increment its value in next_packet. if self.expected_pkt[pkt.flow.id] == pkt.number: self.expected_pkt[pkt.flow.id] += 1 while self.expected_pkt[pkt.flow.id] in \ self.received_pkts.setdefault(pkt.flow.id, []): self.received_pkts[pkt.flow.id].remove( self.expected_pkt[pkt.flow.id]) self.expected_pkt[pkt.flow.id] += 1 else: self.received_pkts.setdefault(pkt.flow.id, []).append(pkt.number) ack = packet.makeAck(pkt.flow, self.expected_pkt[pkt.flow.id]) enqueue(event.SendPacket(time, ack, self.link, self)) pkt.flow.received_packets += 1
def handleTimeout(self, pkt, curr_time): # If unacknowledged, resend the packet + its timeout event if pkt.number in self.unacknowledged: self.window_size = 1 enqueue(event.SendPacket(curr_time, pkt, self.source.link, \ self.source)) enqueue(event.PacketTimeout(curr_time + self.timeout, pkt)) self.unacknowledged[pkt.number] = curr_time
def broadcast_distvec(self, time): for rtr_id in self.rneighbours: link = self.rneighbours[rtr_id] dest = link.get_receiver(self) rtPkt = packet.RoutingPkt(self, dest, self.bf_distvec, \ self.bf_round) enqueue(event.SendPacket(time, rtPkt, link, self)) self.sent_rtpkts[rtPkt] = Router.PKT_SENT enqueue( event.RtPktTimeout(time + Router.RTPKT_TIMEOUT, self, rtPkt))
def makePacket(self, payload, number, start_time): # Makes a new packet and then enqueues SendPacket and PacketTimeout # events. pkt = packet.DataPkt(self.source, self.destination, payload, number, self) # We send the packet (put the event in the pqueue at the flow's start # time. enqueue( event.SendPacket(start_time, pkt, self.source.link, self.source)) enqueue(event.PacketTimeout(start_time + self.timeout, pkt))
def handle_timeout(self, curr_time, rtpkt): ''' Handle timeout for a routing packet ''' status = self.sent_rtpkts.get(rtpkt, None) # If it's been sent but not acknowledged, resend. if status == Router.PKT_SENT: send_link = self.rneighbours[rtpkt.recipient.id] enqueue(event.SendPacket(curr_time, rtpkt, send_link, self)) # If it's been acknowledged, remove it from the sent list. elif status == Router.PKT_ACKED: del self.sent_rtpkts[rtpkt]
def startFlow(self): # While our window isn't filled yet, we create packets. while (self.curr_pkt < min(self.num_packets, self.window_size)): self.makePacket("PACKET %d" % self.curr_pkt, self.curr_pkt, self.start_time) if self.TCP_ALG == 'fast': enqueue( event.UpdateWindow(self.start_time + self.update_period, self)) # We keep track of which packets we haven't received ACKS # for yet. self.unacknowledged[self.curr_pkt] = self.start_time self.curr_pkt += 1 self.sent_packets += 1
def receive(self, pkt, time): # Record ACKed routing packet if (isinstance(pkt, packet.RtAck)): self.sent_rtpkts[pkt.rtpkt] = Router.PKT_ACKED # Handle received routing packet (update BF) elif (isinstance(pkt, packet.RoutingPkt)): if self.bf_updated.get(pkt.sender.id, False) == False: ack_link = self.rneighbours[pkt.sender.id] rt_ack = packet.RtAck(pkt) enqueue(event.SendPacket(time, rt_ack, ack_link, self)) if pkt.bf_round == self.bf_round: self.update_bf(pkt.sender.id, pkt.distvec, ack_link, time) # Forward packet on according to routing table else: next_link = link.Link.l_map[self.routing_table[pkt.recipient.id]] enqueue(event.SendPacket(time, pkt, next_link, self))
def process(self): # Debugging output cprint("==================================") cprint("Rerouting round %d" % self.round_no) # Update link costs, trigger rerouting, and enqueue the event # for the next rerouting link.set_linkcosts() router.reset_bf(self.start_time, self.round_no) enqueue( Reroute(self.start_time + Reroute.WAIT_INTERVAL, self.round_no + 1)) # Debugging output cprint("Link costs:") coststr = "" for l_id in link.Link.ids: coststr += "%s: %d " % (l_id, link.Link.l_map[l_id].bf_lcost) cprint(coststr) cprint("\nRouting tables:") for r_id in router.Router.ids: cprint(r_id + str(router.Router.r_map[r_id].routing_table)) cprint("==================================")
def process(self): enqueue(CheckBuffer( self.start_time, self.link, )) self.receiver.receive(self.packet, self.start_time)
def process(self): self.link.buf_processing = False self.link.size_in_transit = 0 enqueue(CheckBuffer(self.start_time, self.link))
def process(self): self.link.buffer_add((self.packet, self.sender)) enqueue(CheckBuffer(self.start_time, self.link))
def process(self): self.flow.window_size = self.flow.fast_window() enqueue(UpdateWindow(self.start_time + self.flow.update_period, \ self.flow)) cprint('%s updated window to %d' % (self.flow.id, self.flow.window_size))