示例#1
0
    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))
示例#2
0
    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
示例#3
0
 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
示例#4
0
 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))
示例#5
0
    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))
示例#6
0
    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]
示例#7
0
    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
示例#8
0
    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))
示例#9
0
    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("==================================")
示例#10
0
 def process(self):
     enqueue(CheckBuffer(
         self.start_time,
         self.link,
     ))
     self.receiver.receive(self.packet, self.start_time)
示例#11
0
 def process(self):
     self.link.buf_processing = False
     self.link.size_in_transit = 0
     enqueue(CheckBuffer(self.start_time, self.link))
示例#12
0
 def process(self):
     self.link.buffer_add((self.packet, self.sender))
     enqueue(CheckBuffer(self.start_time, self.link))
示例#13
0
 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))