Esempio n. 1
0
    def handle_timer(self):
        """
    Called periodically.

    When called, your router should send tables to neighbors.  It also might
    not be a bad place to check for whether any entries have expired.
    """
        to_delete = []
        for dest in self.routeTableLatency:
            if api.current_time() - self.routeTableTime[dest] <= 15:
                routePacket = basics.RoutePacket(dest,
                                                 self.routeTableLatency[dest])
                self.send(routePacket, self.routeTablePort[dest], True)
            else:
                if dest in self.neighborHosts and self.neighborHosts[dest][
                        1] == self.routeTablePort[dest]:
                    self.routeTableLatency[dest] = self.neighborHosts[dest][0]
                    self.routeTablePort[dest] = self.neighborHosts[dest][1]
                    self.routeTableTime[dest] = api.current_time()
                    routePacket = basics.RoutePacket(
                        dest, self.routeTableLatency[dest])
                    self.send(routePacket, self.routeTablePort[dest], True)
                else:
                    to_delete.append(dest)
                    routePacket = basics.RoutePacket(dest, INFINITY)
                    self.send(routePacket, self.routeTablePort[dest], True)

        self.delete(to_delete)
Esempio n. 2
0
    def handle_timer(self):
        """
        Called periodically.

        When called, your router should send tables to neighbors.  It
        also might not be a bad place to check for whether any entries
        have expired.

        """
        for route in self.routes:
            if (api.current_time() -
                    self.route_time[route]) > self.ROUTE_TIMEOUT:
                self.log("%s (%s)",
                         api.current_time() - self.route_time[route],
                         api.current_time())
                self.delete_route(route)
                self.update_state(route[0])

        for destination in self.dst_port_lookup:
            self.update_neighbors(destination,
                                  self.dst_port_lookup[destination],
                                  self.dst_latency_lookup[destination])
        for port in self.link:
            pack = basics.RoutePacket(self, 0)
            self.send(pack, port)
Esempio n. 3
0
    def handle_timer(self):
        """
        Called periodically.

        When called, your router should send tables to neighbors.  It
        also might not be a bad place to check for whether any entries
        have expired.

        """
        # remove expired routes
        remove_dests = []

        for dest, info in self.router_table.items():
            time = api.current_time() - info[2]
            if time >= self.ROUTE_TIMEOUT:
                remove_dests.append(dest)
        for dest in remove_dests:
            # remove routes
            del self.router_table[dest]
            if self.POISON_MODE:
                self.poison.append(dest)
            self.host_route_default(dest, api.current_time())

        # send to neighbors the router_table
        for port in self.port_latency.keys():
            for dest, info in self.router_table.items():
                if (info[0] != port):
                    self.send(basics.RoutePacket(dest, info[1]), port)
                elif (info[0] == port and self.POISON_MODE):
                    self.send(basics.RoutePacket(dest, INFINITY), port)
            if self.POISON_MODE:
                for dest in self.poison:
                    if dest not in self.host_port:
                        self.send(basics.RoutePacket(dest, INFINITY), port)
        self.poison = []
    def expire_routes(self):
        """
        Clears out expired routes from table.
        accordingly.
        """
        # TODO: fill this in!
        hosts = list(self.table.keys())
        for host in hosts:
            table_entry = self.table[host]
            if table_entry.expire_time == FOREVER:
                return

            # route is poison and expired
            if self.POISON_EXPIRED and api.current_time(
            ) > table_entry.expire_time:
                current_route = self.table[host]
                poison_route = TableEntry(host,
                                          current_route.port,
                                          latency=INFINITY,
                                          expire_time=self.ROUTE_TTL)
                self.table[host] = poison_route

            # route is expired
            elif api.current_time() > table_entry.expire_time:
                del self.table[host]
Esempio n. 5
0
    def handle_route_advertisement(self, route_dst, route_latency, port):
        """
        Called when the router receives a route advertisement from a neighbor.

        :param route_dst: the destination of the advertised route.
        :param route_latency: latency from the neighbor to the destination.
        :param port: the port that the advertisement arrived on.
        :return: nothing.
        """
        # TODO: fill this in!
        # if its not in the table entry then I need to add it since it is a new destination
        if route_dst not in self.table.keys():
            self.table[route_dst] = TableEntry(
                route_dst, port,
                self.ports.get_latency(port) + route_latency,
                api.current_time() + self.ROUTE_TTL)
        else:
            for host, entry in self.table.items():
                if route_dst == host:  # if my destination is in my table entry then maybe I have found a better path and must update my existing path
                    if port == entry.port and route_latency >= INFINITY:
                        self.table[host] = TableEntry(route_dst, port,
                                                      INFINITY,
                                                      api.current_time())
                        self.send_routes(False)
                    elif port == entry.port or entry.latency > route_latency + self.ports.get_latency(
                            port):
                        self.table[host] = TableEntry(
                            route_dst, port,
                            route_latency + self.ports.get_latency(port),
                            api.current_time() + self.ROUTE_TTL)
                        self.send_routes(False)
Esempio n. 6
0
    def route_update(self, destination, port, latency):
        if (latency + self.port_latency[port] < INFINITY):
            total_distance = latency + self.port_latency[port]
        else:
            total_distance = INFINITY

        if destination in self.router_table:
            # Destination in routing table
            if port == self.router_table[destination][0]:
                if total_distance != INFINITY:
                    # trust most recent route
                    self.router_table[destination] = [
                        port, total_distance,
                        api.current_time()
                    ]
                else:
                    if destination in self.router_table:
                        del self.router_table[destination]
                        if self.POISON_MODE:
                            self.poison.append(destination)
            elif (port != self.router_table[destination][0]
                  and total_distance <= self.router_table[destination][1]):
                self.router_table[destination] = [
                    port, total_distance,
                    api.current_time()
                ]
        else:
            if total_distance != INFINITY:
                self.router_table[destination] = [
                    port, total_distance,
                    api.current_time()
                ]
        # add default host route
        self.host_route_default(destination, api.current_time())
Esempio n. 7
0
    def bellman_ford_update(self, packet, port):
        packet_distance = self.neighbors_distance[port] + packet.latency
        # If we don't have our own distance, then packet_distance is the shortest one!
        if packet.destination not in self.distance_vectors.keys():
            self.distance_vectors[packet.destination] = RoutingTable(
                packet_distance, port, api.current_time())
        else:
            table = self.distance_vectors[packet.destination]
            our_distance = table.latency

            # If packet distance is different despite using that port, that means something has changed on their end, so have to update the distance.
            if (port == table.port):
                if packet.destination in self.neighbors:
                    direct_table = self.neighbors[packet.destination]
                    if packet_distance > direct_table.latency:
                        table.update_table(direct_table.latency,
                                           direct_table.port,
                                           api.current_time())
                else:
                    table.update_table(packet_distance, table.port,
                                       api.current_time())

            #If our distance is greater than through this packet, then we update our distance and change the port we go through.
            elif our_distance >= packet_distance:
                table.update_table(packet_distance, port, api.current_time())
Esempio n. 8
0
  def handle_rx (self, packet, port):
    """
    Called by the framework when this Entity receives a packet.

    packet is a Packet (or subclass).
    port is the port number it arrived on.

    You definitely want to fill this in.
    """
    self.log("RX %s on %s (%s)", packet, port, api.current_time())
    if isinstance(packet, basics.RoutePacket):
      new_latency = packet.latency + self.weights[port]
      
      if new_latency >= INFINITY:
        if packet.destination in self.DP and self.DP[packet.destination][0] == port:
          del self.DP[packet.destination]
          if self.POISON_MODE:
            self.send(basics.RoutePacket(packet.destination, INFINITY), port, flood=True)

      elif packet.destination not in self.DP or self.DP[packet.destination][1] >= new_latency or self.DP[packet.destination][0] == port:
        self.DP[packet.destination] = (port, new_latency)
        self.timer[packet.destination] = api.current_time()
        self.send(basics.RoutePacket(packet.destination, new_latency), port, flood=True)  

    elif isinstance(packet, basics.HostDiscoveryPacket):
      self.DP[packet.src] = (port, self.weights[port])
      self.timer[packet.src] = api.current_time()

    elif packet.dst in self.DP:
      self.send(packet, self.DP[packet.dst][0])
Esempio n. 9
0
    def handle_route_advertisement(self, route_dst, route_latency, port):
        """
        Called when the router receives a route advertisement from a neighbor.

        :param route_dst: the destination of the advertised route.
        :param route_latency: latency from the neighbor to the destination.
        :param port: the port that the advertisement arrived on.
        :return: nothing.
        """
        # TODO: fill this in!
        if route_dst in self.table:
            current_route = self.table.get(route_dst)
            if (route_latency + self.ports.get_latency(port) <
                    current_route.latency) or (port
                                               == self.table[route_dst].port):
                if route_latency >= INFINITY:
                    self.table[route_dst] = TableEntry(route_dst, port,
                                                       route_latency,
                                                       api.current_time())
                else:
                    self.table[route_dst] = TableEntry(
                        route_dst, port,
                        route_latency + self.ports.get_latency(port),
                        api.current_time() + self.ROUTE_TTL)

        else:
            if (route_latency < INFINITY):
                self.table[route_dst] = TableEntry(
                    route_dst, port,
                    route_latency + self.ports.get_latency(port),
                    api.current_time() + self.ROUTE_TTL)
Esempio n. 10
0
 def valid_packet(self, packet, port):
     new_dist = packet.latency + self.port_to_latency[port];
     if self.POISON_MODE:
         if packet.destination in self.poison_state:
             self.poison_state.pop(packet.destination)
         self.send(basics.RoutePacket(packet.destination, INFINITY), port)
     if packet.destination not in self.host_to_route.keys() \
             or self.host_to_route[packet.destination] is None \
             or self.host_to_route[packet.destination][0] > new_dist:
         self.host_to_route[packet.destination] = \
             [self.port_to_latency[port] + packet.latency, port, api.current_time()]
         self.send(basics.RoutePacket(packet.destination, new_dist), port,
                   flood=True)
     else:
         if new_dist == self.host_to_route[packet.destination][0]:
             if self.host_to_route[packet.destination][2] < api.current_time():
                 self.host_to_route[packet.destination] = \
                     [new_dist, port, api.current_time()]
                 self.send(basics.RoutePacket(
                     packet.destination, new_dist), port, flood=True)
         if self.host_to_route[packet.destination][1] == port:  # ???
             if new_dist > self.host_to_route[packet.destination][0]:
                 self.host_to_route[packet.destination][0] = new_dist
                 self.send(basics.RoutePacket(
                     packet.destination, new_dist), port, flood=True)
             self.host_to_route[packet.destination][2] = api.current_time()
    def handle_timer(self):
        """
        Called periodically.

        When called, your router should send tables to neighbors.  It
        also might not be a bad place to check for whether any entries
        have expired.

        """

        # check through the routes and see if 15 seconds have passed -> remove route
        for dest in self.destination_map.keys():
            if dest == self:
                self.destination_map.get(dest)[2] = api.current_time()

            if self.destination_map.get(dest)[3] == True:
                self.destination_map.get(dest)[2] = api.current_time()

            if api.current_time() - self.destination_map.get(
                    dest)[2] >= self.ROUTE_TIMEOUT:
                del self.destination_map[dest]

        #send updated routes to neighbors/ poison stuff
        for port in self.port_latency:
            for dest in self.destination_map:
                #if dest is itself, send with latency 0
                if self.destination_map.get(dest)[0] == 0:
                    latency = 0
                    destination = dest
                    rPacket = basics.RoutePacket(destination, latency)
                    self.send(rPacket, port)
                    continue

                #poison mode
                if self.POISON_MODE:
                    #same port that the route uses, advertise dist of INFINITY
                    if port == self.destination_map.get(dest)[1]:
                        destination = dest
                        latency = INFINITY
                        rPacket = basics.RoutePacket(destination, latency)
                        self.send(rPacket, port)
                    #different port than the one route uses
                    elif port != self.destination_map.get(dest)[1]:
                        latency = self.destination_map.get(dest)[0]
                        destination = dest
                        rPacket = basics.RoutePacket(destination, latency)
                        self.send(rPacket, port)

                #not poison mode
                else:
                    #same port that the route uses, don't advertise route
                    if port == dest[1]:
                        continue
                    #different port than the one route uses
                    elif port != dest[1]:
                        latency = self.destination_map.get(dest)[0]
                        destination = dest
                        rPacket = basics.RoutePacket(destination, latency)
                        self.send(rPacket, port)
Esempio n. 12
0
    def handle_rx(self, packet, port):
        """
        Called by the framework when this Entity receives a packet.

        packet is a Packet (or subclass).
        port is the port number it arrived on.

        You definitely want to fill this in.

        """
        #self.log("RX %s on %s (%s)", packet, port, api.current_time())
        if isinstance(packet, basics.RoutePacket):
            #if host is not in table
            if packet.destination not in self.table:
                #add host to table with (link latency + this latency) and current time
                newLatency = packet.latency + self.portLatency[port]
                self.table[packet.destination] = (newLatency, port, api.current_time(), port)
                #flood new host to other switches/routers
                self.send(basics.RoutePacket(packet.destination, newLatency), port, flood=True)
            #else try to update vector
            else:
                hostVector = self.table[packet.destination]
                originalLatency = hostVector[0]
                newLatency = packet.latency + self.portLatency[port]
                if self.directRoute.has_key(packet.destination) and self.directRoute[packet.destination][0] < originalLatency:
                    #update to direct route if possible
                    self.table[packet.destination] = self.directRoute[packet.destination]
                elif hostVector[1] == port:
                    #update time
                    if newLatency > originalLatency:
                        #update latency
                        self.table[packet.destination] = (newLatency, hostVector[1], api.current_time(), hostVector[3])
                        self.send(basics.RoutePacket(packet.destination, newLatency), port, flood=True)
                    else:
                        self.table[packet.destination] = (originalLatency, hostVector[1], api.current_time(), hostVector[3])
                elif newLatency <= originalLatency:
                    #update vector with lower latency
                    self.table[packet.destination] = (newLatency, port, api.current_time(), originalLatency)

        elif isinstance(packet, basics.HostDiscoveryPacket):
            #add host to table
            hostVector = (self.portLatency[port], port, None, port)
            self.table[packet.src] = hostVector
            self.directRoute[packet.src] = hostVector
            #send host to other links
            self.send(basics.RoutePacket(packet.src, hostVector[0]), port, flood=True)

        else:
            #forward regular packet
            isHairpin = packet.src != packet.dst #need to better implement
            isIntable = packet.dst in self.table
            if isinstance(packet.dst, api.HostEntity) and isHairpin and isIntable:
                hostPort = self.table[packet.dst][1]
                hostLatency = self.table[packet.dst][0]
                if not hostLatency >= INFINITY:
                    self.send(packet, hostPort)
Esempio n. 13
0
  def handle_rx (self, packet, port):
    """
    Called by the framework when this Entity receives a packet.

    packet is a Packet (or subclass).
    port is the port number it arrived on.

    You definitely want to fill this in.
    """
    
    #self.log("RX %s on %s (%s)", packet, port, api.current_time())
    if isinstance(packet, basics.RoutePacket):

      dest = packet.destination
      newLatency = self.neighbours[port] + packet.latency

      oldLatency = INFINITY
      if dest in self.routesToDest:
        oldLatency = self.routesToDest[dest][1]


      if dest not in self.routesToDest or newLatency <= oldLatency or (dest in self.routesToDest and self.routesToDest[dest][0] == port):
        self.routesToDest[dest] = (port, newLatency, api.current_time(), False)
        
        
      if dest in self.hosts and self.hosts[dest][1] <= self.routesToDest[dest][1]:
        self.routesToDest[dest] = self.hosts[dest]
      
      if oldLatency != self.routesToDest[dest][1]:
        newPacket = basics.RoutePacket(dest, self.routesToDest[dest][1])
        self.send(newPacket, port, True)

    elif isinstance(packet, basics.HostDiscoveryPacket):
      self.routesToDest[packet.src] = (port, self.neighbours[port], api.current_time(), True)
      self.send(basics.RoutePacket(packet.src, self.neighbours[port]), port, True)
      self.hosts[packet.src] = (port, self.neighbours[port], api.current_time(), True)
    else:
      # Totally wrong behavior for the sake of demonstration only: send
      # the packet back to where it came from!

      
      reciever = packet.dst
      if reciever in self.routesToDest:
        latency = self.routesToDest[reciever][1]

        if latency < INFINITY and self.routesToDest[reciever][0] != port:
          self.send(packet, self.routesToDest[reciever][0], False)
          return

      if reciever in self.hosts:
        self.routesToDest[reciever] = self.hosts[reciever]
        latency = self.routesToDest[reciever][1]

        if latency < INFINITY and self.routesToDest[reciever][0] != port:
          self.send(packet, self.hosts[reciever][0], False)
Esempio n. 14
0
 def check_times(self):
   """
   Expires all ports whose time last updated is 15 seconds between then and now.
   """
   for destination in self.distanceVectors:
       distanceVector = self.distanceVectors[destination]
       for viaEntity in distanceVector:
           # Don't expire host links or distances to yourself (who cares about that)
           print(api.current_time())
           if not isinstance(viaEntity, basics.BasicHost) and api.current_time() - distanceVector[viaEntity][1] >= 15 and destination != viaEntity:
               self.set_distance_vectors(destination, viaEntity, INFINITY)
  def handle_route_packet(self, packet, port):
      self.port_table[port][packet.destination] = packet.latency
      special_send = False 

      if packet.destination in self.forward_table.keys(): 
        if self.output_port_table[packet.destination] == port: 
          starting_latency = self.latency_table[packet.destination]
          starting_port = self.output_port_table[packet.destination]
          update_latency = self.links[port] + packet.latency
          update_port = port

          for packet_source in self.port_table.keys():
            if packet_source != port and packet.destination in self.port_table[packet_source] and self.port_table[packet_source][packet.destination] < INFINITY:
              if self.links[packet_source] + self.port_table[packet_source][packet.destination] < update_latency:
                update_latency = self.links[packet_source] + self.port_table[packet_source][packet.destination]
                update_port = packet_source 

          if update_latency > INFINITY:
            special_send = True
            update_latency = INFINITY

          if not (update_latency == starting_latency and update_port == starting_port):
            if (update_latency == INFINITY and (self.POISON_MODE or special_send)) or update_latency != INFINITY:
              #print "send infinity update_latency"
              self.send(basics.RoutePacket(packet.destination, update_latency), update_port, True)
          
          self.forward_table[packet.destination] = True
          self.latency_table[packet.destination] = update_latency
          self.output_port_table[packet.destination] = update_port
          self.time_table[packet.destination] = api.current_time()

        else:
          if self.links[port] + packet.latency < self.output_port_table[packet.destination]:
            self.forward_table[packet.destination] = True
            self.latency_table[packet.destination] = self.links[port] + packet.latency
            self.output_port_table[packet.destination] = port
            self.time_table[packet.destination] = api.current_time()

            # print "send handle_route packet for no equal ports"
            self.send(basics.RoutePacket(packet.destination, self.latency_table[packet.destination]), self.output_port_table[packet.destination], True) 
          
          if self.links[port] + self.latency_table[packet.destination] < packet.latency:
            del self.port_table[port][packet.destination]

      else:

        self.forward_table[packet.destination] = True
        self.latency_table[packet.destination] = min(INFINITY, self.links[port] + packet.latency)
        self.output_port_table[packet.destination] = port
        self.time_table[packet.destination] = api.current_time()

        #print "send handle_route packet for no in keys"
        self.send(basics.RoutePacket(packet.destination, self.latency_table[packet.destination]), port, True)
Esempio n. 16
0
    def calc_send(self, cost, port, host):

        self.routing_tb[host] = self.b_ford(cost, port, host)

        if cost == INFINITY:
            if self.POISON_MODE:
                self.routing_tb[host] = [INFINITY, port, api.current_time()]
                self.send(basics.RoutePacket(host, cost), port, flood=True)
            elif host in self.routing_tb:
                del self.routing_tb[host]
        else:
            self.routing_tb[host] = [cost, port, api.current_time()]
            self.send(basics.RoutePacket(host, cost), port, flood=True)
Esempio n. 17
0
 def check_times(self):
     """
 Expires all ports whose time last updated is 15 seconds between then and now.
 """
     for destination in self.distanceVectors:
         distanceVector = self.distanceVectors[destination]
         for viaEntity in distanceVector:
             # Don't expire host links or distances to yourself (who cares about that)
             print(api.current_time())
             if not isinstance(
                     viaEntity, basics.BasicHost
             ) and api.current_time() - distanceVector[viaEntity][
                     1] >= 15 and destination != viaEntity:
                 self.set_distance_vectors(destination, viaEntity, INFINITY)
Esempio n. 18
0
 def expire_routes(self):
     """
     Clears out expired routes from peer tables; updates forwarding table
     accordingly.
     """
     # TODO: fill this in!
     for table in self.peer_tables.values():
         for key, element in table.items():
             if (api.current_time() > element.expire_time):
                 if self.POISON_MODE:
                     table[key]=PeerTableEntry(key,INFINITY,api.current_time()+ROUTE_TTL)
                 else:
                     table.pop(key)
     self.update_forwarding_table()
Esempio n. 19
0
    def handle_rx(self, packet, port):
        """
        Called by the framework when this Entity receives a packet.

        packet is a Packet (or subclass).
        port is the port number it arrived on.

        You definitely want to fill this in.

        """
        #self.log("RX %s on %s (%s)", packet, port, api.current_time())
        if isinstance(packet, basics.RoutePacket):
            router = packet.src
            dst = packet.destination
            latency = packet.latency
            self.neighbors[port] = router
            if not self.dv.has_key(router):
                self.dv[router] = self.ports_latency[port]
                self.paths[router] = (port, api.current_time())
            if dst == self:
                return
            if latency == INFINITY:
                if self.paths.has_key(dst) and (self.paths[dst][0] == port):
                    del self.paths[dst]
                    self.dv[dst] = INFINITY
            if (not self.dv.has_key(dst)) or (self.dv[router] + latency <=
                                              self.dv[dst]):
                self.dv[dst] = self.dv[router] + latency
                self.paths[dst] = (port, api.current_time())

        elif isinstance(packet, basics.HostDiscoveryPacket):
            host = packet.src
            if self.dv.has_key(host):
                self.dv[host] = min(self.dv[host], self.ports_latency[port])
            else:
                self.dv[host] = self.ports_latency[port]
            self.direct_paths[host] = port
        else:
            # Totally wrong behavior for the sake of demonstration only: send
            # the packet back to where it came from!
            dst = packet.dst
            if not self.dv.has_key(dst) or self.dv[dst] == INFINITY:
                return
            if self.paths.has_key(dst):
                if port != self.paths[dst][0]:
                    self.send(packet, self.paths[dst][0])
                    return
            if self.direct_paths.has_key(dst):
                if port != self.direct_paths[dst]:
                    self.send(packet, self.direct_paths[dst])
Esempio n. 20
0
  def handle_rx (self, packet, port):
    """
    Called by the framework when this Entity receives a packet.

    packet is a Packet (or subclass).
    port is the port number it arrived on.
    You definitely want to fill this in.
    """
    #self.log("RX %s on %s (self: %s) (src: %s)", packet, port, self, packet.src)
    if isinstance(packet, basics.RoutePacket):
      if(packet.latency + self.links[port] < INFINITY):
        if ((self.DV.get(packet.destination) == None) or (self.DV[packet.destination][0] > packet.latency + self.links[port])):
          newPacket = basics.RoutePacket(packet.destination, self.links[port] + packet.latency)
          self.DV[packet.destination] = [newPacket.latency, api.current_time(), port]
          self.send(newPacket, port, flood=True)
          if self.POISON_MODE:
            poison = basics.RoutePacket(packet.destination, INFINITY)
            self.send(poison, port, flood=False)
        else:
          if self.DV[packet.destination][2] == port:
            self.DV[packet.destination][1] = api.current_time()
            if packet.latency + self.links[port] > self.DV[packet.destination][0]:
              self.DV[packet.destination][0] = packet.latency + self.links[port]
              newPacket = basics.RoutePacket(packet.destination, self.links[port] + packet.latency)
              self.send(newPacket, port, flood=True)
              if self.POISON_MODE:
                poison = basics.RoutePacket(packet.destination, INFINITY)
                self.send(poison, port, flood=False)
        if self.poisoned.get(packet.destination) != None and self.POISON_MODE:
          del self.poisoned[packet.destination]
      elif packet.latency >= INFINITY and self.POISON_MODE:
        for x in self.DV.keys():
          if (x == packet.destination) and (self.DV[x][2] == port):
            poison = basics.RoutePacket(packet.destination, INFINITY)
            self.send(poison, port, flood=True)
            self.poisoned[x] = self.DV[x]
            del self.DV[x]

    elif isinstance(packet, basics.HostDiscoveryPacket):
        self.DV[packet.src] = [self.links[port], -1, port]
        route = basics.RoutePacket(packet.src, self.links[port])
        self.send(route, port, flood=True)
    else:
      # Totally wrong behavior for the sake of demonstration only: send
      # the packet back to where it came from!
      if (self.DV.get(packet.dst) != None and self.DV[packet.dst][2] != port):
        if self.DV[packet.dst][0] <= INFINITY: 
          self.send(packet, self.DV[packet.dst][2], flood=False)
  def handle_link_down (self, port):
    """
    Called by the framework when a link attached to this Entity does down.

    The port number used by the link is passed in.
    """
    del self.links[port]
    del self.port_table[port]
    for destination_host in self.host_table.keys():
      if self.host_table[destination_host] == port:
        del self.host_table[destination_host]

    for destination_host in self.forward_table:
      if self.output_port_table[destination_host] == port: 
        update_latency = INFINITY
        update_port = port
        for packet_source in self.port_table.keys():
          if (destination_host in self.port_table[packet_source] and self.port_table[packet_source][destination_host] < INFINITY) and (self.links[packet_source] + self.port_table[packet_source][destination_host] < update_latency and self.links[packet_source] + self.port_table[packet_source][destination_host] < INFINITY):
              update_latency = self.links[packet_source] + self.port_table[packet_source][destination_host]
              update_port = packet_source 

        self.forward_table[destination_host] = True 
        self.latency_table[destination_host] = update_latency
        self.time_table[destination_host] = api.current_time()
        self.output_port_table = update_port

        if self.POISON_MODE:
          #print "sent poison mode link down"
          self.send(basics.RoutePacket(destination_host, update_latency), update_port, True)
Esempio n. 22
0
    def handle_rx(self, packet, port):
        """
        Called by the framework when this Entity receives a packet.

        packet is a Packet (or subclass).
        port is the port number it arrived on.

        You definitely want to fill this in.
        """
        if isinstance(packet, basics.RoutePacket):
            self.handle_route_packet(packet, port)
            return
        elif isinstance(packet, basics.HostDiscoveryPacket):
            self.handle_host_discover_packet(packet, port)
            return
        else:
            if not self.NO_LOG:
                self.log("RX UNKNOWN %s on %s (%s)", packet, port,
                         api.current_time())

            host = packet.dst
            mapping = self.route_map.next_hop(host)
            if mapping == DESTINATION_NOT_FOUND:
                self.send(packet, port, flood=True)
                return
            next_hop = m_next_hop(mapping)
            if next_hop != port:
                self.send(packet, next_hop)
            elif self.POISON_MODE:
                # The correct route is sending the packet back to the port
                # we received it on. We need to poison this route
                poison_packet = basics.RoutePacket(host, INFINITY)
                self.send(poison_packet, port)
Esempio n. 23
0
    def handle_timer(self):
        """
        Called periodically.

        When called, your router should send tables to neighbors.  It
        also might not be a bad place to check for whether any entries
        have expired.

        """
        if self.POISON_MODE:
            for p_route in self.routing_data.get_poisoned_route_map():
                self.send(basics.RoutePacket(p_route, INFINITY), flood=True)
        for host in self.routing_data.get_host_route_map():
            route = self.routing_data.get_route(host)
            if route:
                time_diff = api.current_time() - route.get_time()
                if route.get_time() == -1 or time_diff <= self.ROUTE_TIMEOUT:
                    if self.POISON_MODE:
                        self.send(basics.RoutePacket(host, INFINITY),
                                  route.get_port())
                    self.send(basics.RoutePacket(host, route.get_distance()),
                              route.get_port(),
                              flood=True)
                else:
                    if self.POISON_MODE:
                        self.send(basics.RoutePacket(host, INFINITY),
                                  route.get_port())
                        self.routing_data.set_poisoned_route(host, route)
                    self.routing_data.null_route(host)
Esempio n. 24
0
 def handle_route_packet(self, packet, port):
     if not self.NO_LOG:
         self.log("RX RoutePacket %s on %s (%s)", packet, port, api.current_time())
     host = packet.destination
     latency = packet.latency
     # Notify the route map of the new route
     self.route_map.received_route(port, host, latency)
Esempio n. 25
0
 def handle_timer(self):
     for i in self.routeTable.keys():
         if (((api.current_time() - self.routeTable[i][2]) <=
              self.ROUTE_TIMEOUT)
                 or (self.routeTable[i][2]
                     == -1)):  #Checks if a route is expired or not
             self.send(
                 basics.RoutePacket(i, self.routeTable[i][0]),
                 flood=True)  #updates neighbours with distance vector table
             if self.POISON_MODE == True:
                 self.send(basics.RoutePacket(i, INFINITY),
                           self.routeTable[i][1],
                           flood=False)
         else:
             if self.POISON_MODE == True:
                 self.p_reverse[i] = self.routeTable[
                     i]  #populates poisoned reverse dictionary
                 self.send(basics.RoutePacket(i, INFINITY),
                           self.routeTable[i][1],
                           flood=False)
             del self.routeTable[
                 i]  #deletes route from dictionary if it is expired.
     if self.POISON_MODE == True:
         for i in self.p_reverse.keys():
             self.send(basics.RoutePacket(i, INFINITY),
                       port=None,
                       flood=True)
Esempio n. 26
0
    def handle_rx (self, packet, port):
        """
        Called by the framework when this Entity receives a packet.

        packet is a Packet (or subclass).
        port is the port number it arrived on.

        You definitely want to fill this in.
        """
        if isinstance(packet, basics.RoutePacket):
            self.handle_route_packet(packet, port)
            return
        elif isinstance(packet, basics.HostDiscoveryPacket):
            self.handle_host_discover_packet(packet, port)
            return
        else:
            if not self.NO_LOG:
                self.log("RX UNKNOWN %s on %s (%s)", packet, port, api.current_time())
            
            host = packet.dst
            mapping = self.route_map.next_hop(host)
            if mapping == DESTINATION_NOT_FOUND:
                self.send(packet, port, flood=True)
                return
            next_hop = m_next_hop(mapping)
            if next_hop != port:
                self.send(packet, next_hop)
            elif self.POISON_MODE:
                # The correct route is sending the packet back to the port
                # we received it on. We need to poison this route
                poison_packet = basics.RoutePacket(host, INFINITY)
                self.send(poison_packet, port)
Esempio n. 27
0
  def process_route(self, dest, latency, port, next_hop, time_expires=None):
    """
    Add a new RouteEntry to memory, updating self.table and the cache as
    necessary.
    """
    latency = min(latency, INFINITY)
    time_expires = time_expires or api.current_time() + 15
    old_D = self.get_D(dest)
    if old_D != INFINITY:
      old_next_hop = self.table[dest].next_hop
      old_port = self.table[dest].port

    if dest not in self.cache:
      self.cache[dest] = [ENTRY_UNREACHABLE]
    # remove entries from same router
    self.cache[dest] = filter(lambda entry: entry.next_hop != next_hop, self.cache[dest])
    self.cache[dest].append(RouteEntry(latency, port, next_hop, time_expires))
    self.table[dest] = sorted(self.cache[dest], key=BY_LATENCY)[0]
    if old_D != self.get_D(dest):
      self.broadcast_route(dest)
    elif old_D != INFINITY and old_next_hop != self.table[dest].next_hop:
      # D is unchanged, but the next_hop has changed.
      if self.POISON_MODE:
        poisoned = basics.RoutePacket(dest, INFINITY)
        self.send(poisoned, self.table[dest].port)
        unpoison = basics.RoutePacket(dest, latency)
        self.send(unpoison, old_port)
Esempio n. 28
0
 def handle_host_discover_packet(self, packet, port):
     if not self.NO_LOG:
         self.log("RX HostDiscoveryPacket %s on %s (%s)", packet, port,
                  api.current_time())
     host = packet.src
     # Notify the route map of the new host
     self.route_map.host_discover(host, port)
Esempio n. 29
0
    def handle_timer(self):
        """
        Called periodically.

        When called, your router should send tables to neighbors.  It
        also might not be a bad place to check for whether any entries
        have expired.

        """
        #will make expire_routes pass.

        #If time has expired, you remove the entry from the routing table.
        for key, val in self.routing_table.items():
            if val[2] != None:
                if api.current_time() - val[2] > self.ROUTE_TIMEOUT:
                    if self.POISON_MODE:
                        self.routing_table[key][1] = INFINITY
                    else:
                        del self.routing_table[key]

        for port in self.link_up:
            for dest, val_list in self.routing_table.items():
                if self.POISON_MODE == True:
                    latency = val_list[1]
                    if val_list[0] == port:
                        latency = INFINITY
                    new_packet = basics.RoutePacket(dest, latency)
                    self.send(new_packet, port, flood=False)
                else:
                    latency = val_list[1]
                    if val_list[0] != port:
                        new_packet = basics.RoutePacket(dest, latency)
                        self.send(new_packet, port, flood=False)
Esempio n. 30
0
    def update_state(self, root):
        changed = False

        best_port = None
        shortest_latency = INFINITY
        for route in self.route_destination[root]:
            if route[2] < shortest_latency:
                shortest_latency = route[2]
                best_port = route[1]

        if best_port == None:
            return

        if root not in self.dst_port_lookup or self.dst_port_lookup[
                root] != best_port or self.dst_latency_lookup[
                    root] != shortest_latency:
            changed = True

        if changed:
            if root in self.dst_port_lookup:
                self.port_list_dst_lookup[self.dst_port_lookup[root]].remove(
                    root)
            if best_port in self.port_list_dst_lookup:
                self.port_list_dst_lookup[best_port].append(root)
            else:
                self.port_list_dst_lookup[best_port] = [root]
            self.dst_port_lookup[root] = best_port
            self.dst_latency_lookup[root] = shortest_latency

        if changed:
            self.log(
                "I am %s and i think the shorest path to %s is on port %s with latency %s (%s)",
                self.name, root, best_port, shortest_latency,
                api.current_time())
            self.update_neighbors(root, best_port, shortest_latency)
Esempio n. 31
0
    def handle_timer(self):
        """
    Called periodically.

    When called, your router should send tables to neighbors.  It also might
    not be a bad place to check for whether any entries have expired.
    """

        #self.log("handle_timer " + str(len(self.routesToDest)))
        deleteDests = set()
        for dest in self.routesToDest:
            recievedTime = self.routesToDest[dest][2]

            if api.current_time(
            ) - recievedTime <= TimeDiff or self.routesToDest[dest][3]:
                latency = self.routesToDest[dest][1]
                packet = basics.RoutePacket(dest, latency)
                port = self.routesToDest[dest][0]
                self.send(packet, port, True)
            else:
                if dest in self.hosts:
                    packet = basics.RoutePacket(dest, self.hosts[dest][1])
                    self.send(packet, self.hosts[dest][0], True)
                    self.routesToDest[dest] = self.hosts[dest]
                else:
                    deleteDests.add(dest)
                    self.sendPoison(dest)

        for dest in deleteDests:
            del self.routesToDest[dest]
Esempio n. 32
0
    def handle_timer(self):
        """
    Called periodically.

    When called, your router should send tables to neighbors.  It also might
    not be a bad place to check for whether any entries have expired.
    """
        dead_table = True
        current_time = api.current_time()
        for destination in self.table:
            to_expire = []
            for port in self.table[destination]:
                if current_time - self.table[destination][port][1] > 15:
                    to_expire.append(port)
            if destination not in self.hosts:
                for port in to_expire:
                    del (self.table[destination][port])
                    self.poison(destination, port)
        for destination in self.table:
            port = self.best_path(destination)
            if not (port == None):
                dead_table = False
                update_packet = basics.RoutePacket(
                    destination, self.table[destination][port][0])
                self.send(update_packet, [port] + self.hosts.values(),
                          flood=True)
Esempio n. 33
0
  def handle_timer (self):
    """
    Called periodically.

    When called, your router should send tables to neighbors.  It also might
    not be a bad place to check for whether any entries have expired.
    """
    for x in self.DV.keys():
      #print x, self.DV[x][2], self.DV[x][0], self
      if (api.current_time() - self.DV[x][1] ) <= 15 or self.DV[x][1] == -1:
        route = basics.RoutePacket(x, self.DV[x][0])
        self.send(route, self.DV[x][2], flood=True)
        if self.POISON_MODE:
          routePoison = basics.RoutePacket(x, INFINITY)
          self.send(routePoison, self.DV[x][2], flood=False)
      else:
        if self.POISON_MODE:
          routePoison = basics.RoutePacket(x, INFINITY)
          self.send(routePoison, self.DV[x][2], flood=False)
          self.poisoned[x] = self.DV[x]
        del self.DV[x]
    if self.POISON_MODE:
      for x in self.poisoned.keys():
        poison = basics.RoutePacket(x, INFINITY)
        self.send(poison, port=None, flood=True)
Esempio n. 34
0
    def handle_link_down(self, port):
        """
    Called by the framework when a link attached to this Entity does down.

    The port number used by the link is passed in.
    """
        # self.log(" %s (%s)", port, api.current_time())
        to_delete = []

        del self.portLatency[port]

        for d in self.neighborHosts.keys():
            if self.neighborHosts[d][1] == port:
                del self.neighborHosts[d]

        for d in self.routeTablePort:
            if self.routeTablePort[d] == port:
                if d in self.neighborHosts:
                    self.routeTableLatency[d] = self.neighborHosts[d][0]
                    self.routeTablePort[d] = self.neighborHosts[d][1]
                    self.routeTableTime[d] = api.current_time()
                    self.send(basics.RoutePacket(d, self.routeTableLatency[d]),
                              port, True)
                else:
                    to_delete.append(d)
                    self.sendPoison(port, d)
        self.delete(to_delete)
Esempio n. 35
0
    def handle_link_down(self, port):
        """
        Called by the framework when a link attached to this Entity does down.

        The port number used by the link is passed in.

        """
        remove_hosts = []
        remove_dests = []
        for host in self.host_port:
            if (self.host_port[host] == port):
                remove_hosts.append(host)
        for host in remove_hosts:
            del self.host_port[host]

        for dest, info in self.router_table.items():
            if (port == info[0]):
                remove_dests.append(dest)
        # remove routes
        for dest in remove_dests:
            del self.router_table[dest]
            if self.POISON_MODE:
                self.poison.append(dest)
            # add default host route
            self.host_route_default(dest, api.current_time())
        del self.port_latency[port]
Esempio n. 36
0
 def handleHostDiscoveryPacket(self, packet, port):
     # print(self.name , packet.src , self.portLatency[port])
     self.neighborHosts[packet.src] = (self.portLatency[port], port)
     if packet.src not in self.routeTableLatency or self.portLatency[
             port] < self.routeTableLatency[packet.src]:
         self.routeTableLatency[packet.src] = self.portLatency[port]
         self.routeTablePort[packet.src] = port
         self.routeTableTime[packet.src] = api.current_time()
Esempio n. 37
0
def current_time ():
  """
  Returns the current time

  Appears bananas, but works.
  """
  import sim.api as api
  return api.current_time()
Esempio n. 38
0
    def handle_link_down (self, port):
        """
        Called by the framework when a link attached to this Entity does down.

        The port number used by the link is passed in.
        """
        if not self.NO_LOG:
            self.log("handle_link_down on %s (%s)" % (port, api.current_time()))
        self.route_map.remove_link(port)
Esempio n. 39
0
    def handle_link_up (self, port, latency):
        """
        Called by the framework when a link attached to this Entity goes up.

        The port attached to the link and the link latency are passed in.
        """
        if not self.NO_LOG:
            self.log("handle_link_up on %s (%s)" % (port, api.current_time()))
        self.route_map.add_link(port, latency)
 def _handle_route_packet(self, packet, port):
     # if api.get_name(self) == "s3": pdb.set_trace()
     if port not in self.neighbors.keys():
         self.neighbors[port] = {}
     self.neighbors[port][packet.destination] = (packet.latency, port, api.current_time() + 15)
     if packet.destination in self.vector.keys():
         self.recalculate_dest(packet.destination, send_update=True)
     else:
         self.set_dest(packet.destination, min(packet.latency + self.ports[port],INFINITY), port, api.current_time() + 15)
  def handle_discovery_packet(self, packet, port):

      self.forward_table[packet.src] = True
      self.latency_table[packet.destination] = self.links[port] 
      self.output_port_table[packet.destination] = port
      self.time_table[packet.destination] = api.current_time()
      self.host_table[packet.src] = port

      #print "send discovery packet discovery"
      self.send(basics.RoutePacket(packet.src, self.latency_table[packet.destination]), self.output_port_table[packet.destination], True)
Esempio n. 42
0
    def _get_min_latency(self, latencies):
        current_time = api.current_time()
        m_port = None
        m_latency = INFINITY
        for port, (latency, timer) in latencies.items():
            if timer is not None and current_time - timer > TIMEOUT:
                del latencies[port]
                continue

            if latency < m_latency:
                m_port = port
                m_latency = latency

        return m_port, m_latency
Esempio n. 43
0
  def update(self, dst, port, cost):
    """
    Called by self.handle_rx() when a entry in the table need to be updated.

    arguments
    dst - destination
    port - from which neighbour
    cost - latency to destination
    """
    self.table[dst] = [port, cost, api.current_time()]
    p = basics.RoutePacket(dst, cost)
    self.send(p, port=port, flood=True)
    if self.POISON_MODE:
      p = basics.RoutePacket(dst, INFINITY)
      self.send(p, port=port)
Esempio n. 44
0
  def handle_timer (self):
    """
    Called periodically.

    When called, your router should send tables to neighbors.  It also might
    not be a bad place to check for whether any entries have expired.
    """
    # weed expired packets
    for dest in self.cache:
      old_D = self.get_D(dest)
      self.cache[dest] = filter(lambda entry: api.current_time() < entry.time_expires,
                                self.cache[dest])
      self.table[dest] = sorted(self.cache[dest], key=BY_LATENCY)[0]
    self.broadcast_all_routes()
    self.sanity_check()

    if self.SHOW_TICK:
      self.log('tick')
Esempio n. 45
0
  def set_distance_vectors(self, destination, viaEntity, distance):
    """
    Sets distanceVector[destination][viaEntity] = distance if the table exists.
    Creates the table if it doesn't. Also sends out updates where necessary.
    """
    if destination not in self.distanceVectors:
        self.distanceVectors[destination] = {}

    previousMinDistance = self.min_distance_to(destination)
    self.distanceVectors[destination][viaEntity] = [distance, api.current_time()]
    # print("Setting distance vector from " + str(destination) + " via " + str(viaEntity))  
    newMinDistance = self.min_distance_to(destination)

    # If the routing table changes, we want to send out the corresponding updates
    if previousMinDistance != newMinDistance:
        # print("Self: " + str(self) + "Destination: " + str(destination) + "; viaEntity: " + str(viaEntity) + str(previousMinDistance) + " is now " + str(newMinDistance))
        if self.POISON_MODE or not self.is_infinity(newMinDistance):
            self.send_packet_to_all_valid_neighbors(basics.RoutePacket(destination, newMinDistance))
    def check_expiration(self): 
        time = api.current_time()
        for n in self.neighbors.keys():
            for dest in self.neighbors[n].keys():
                l, p, t = self.neighbors[n][dest]
                if t < time:
                    if self.POISON_MODE:
                        self.neighbors[n][dest] = (INFINITY, p, t)
                    else:
                        del self.neighbors[n][dest]

        for dest in self.vector.keys():
            l, p, t = self.vector[dest]
            if t < time:
            #    print api.get_name(self) + ' said that rout to '+ api.get_name(dest) + str(self.vector[dest]) +'is expired'
                if self.POISON_MODE:
                    self.vector[dest] = (INFINITY, p, t)
                else:
                    del self.vector[dest]
  def handle_timer (self):
    """
    Called periodically.

    When called, your router should send tables to port_table.  It also might
    not be a bad place to check for whether any entries have expired.
    """
    current_time = api.current_time()
    for destination_host in self.forward_table.keys():
      if not destination_host in self.host_table:
        if current_time - self.time_table[packet.destination] >= EXPIRED or self.latency_table[packet.destination] >= INFINITY: 
          if self.output_port_table[packet.destination] in self.port_table:
            del self.port_table[self.output_port_table[packet.destination]][destination_host]
          del self.forward_table[destination_host]
          del self.latency_table[destination_host]
          del self.output_port_table[destination_host]
          del self.time_table[desitnation_host]

    for destination_host in self.forward_table.keys():
      if (self.latency_table[destination_host] == INFINITY and self.POISON_MODE) or self.latency_table[destination_host] != INFINITY:
        self.send(basics.RoutePacket(item, self.latency_table[destination_host]), self.output_port_table[destination_host], True)
Esempio n. 48
0
  def handle_timer (self):
    """
    Called periodically.

    When called, your router should send tables to neighbors.  It also might
    not be a bad place to check for whether any entries have expired.
    """
    # check if any entry expire.
    expiredEntries = []
    for dst in self.table:
      # leave the entry of host unchanged
      if self.table[dst][0] not in self.hosts and api.current_time() - self.table[dst][2] >= 15:
        expiredEntries.append(dst)
    for dst in expiredEntries:
      del self.table[dst]
      if self.POISON_MODE:
        p = basics.RoutePacket(dst, INFINITY)
        self.send(p, flood=True)

    # send table to neighbours.
    for dst in self.table:
      p = basics.RoutePacket(dst, self.table[dst][1])
      self.send(p, port=self.table[dst][0], flood=True)
Esempio n. 49
0
    def handle_rx(self, packet, port):
        """
        Called by the framework when this Entity receives a packet.

        packet is a Packet (or subclass).
        port is the port number it arrived on.

        You definitely want to fill this in.
        """
        #self.log("RX %s on %s (%s)", packet, port, api.current_time())
        if isinstance(packet, basics.RoutePacket):
            if self.route_table.get(packet.destination) is None:
                self.route_table[packet.destination] = {}
            latency = self.port_latency[port] + packet.latency
            if latency >= INFINITY:
                if port in self.route_table[packet.destination]:
                    del self.route_table[packet.destination][port]
                    self._forward_route(packet.destination)
            else:
                self.route_table[packet.destination][port] =\
                    (latency, api.current_time())
                self._forward_route(packet.destination)
        elif isinstance(packet, basics.HostDiscoveryPacket):
            if self.route_table.get(packet.src) is None:
                self.route_table[packet.src] = {}
            self.route_table[packet.src][
                port] = (self.port_latency[port], None)
            self._forward_route(packet.src)
        else:
            # Totally wrong behavior for the sake of demonstration only: send
            # the packet back to where it came from!
            out_port, _ = self._get_min_latency(
                self.route_table.get(packet.dst, {}))
            if out_port is None:
                self.send(packet, port, flood=True)
            else:
                self.send(packet, out_port)
Esempio n. 50
0
  def handle_timer (self):
    """
    Called periodically.

    When called, your router should send tables to neighbors.  It also might
    not be a bad place to check for whether any entries have expired.
    """
    dead_table = True;
    current_time = api.current_time()
    for destination in self.table:
        to_expire = []
        for port in self.table[destination]:
            if current_time - self.table[destination][port][1] > 15:
                to_expire.append(port)
        if destination not in self.hosts:
            for port in to_expire:
                del(self.table[destination][port])
                self.poison(destination,port)
    for destination in self.table:
        port = self.best_path(destination);
        if not(port == None):
            dead_table = False;
            update_packet = basics.RoutePacket(destination, self.table[destination][port][0])
            self.send(update_packet, [port] + self.hosts.values(), flood=True)
Esempio n. 51
0
  def handle_rx (self, packet, port):
    """
    Called by the framework when this Entity receives a packet.

    packet is a Packet (or subclass).
    port is the port number it arrived on.

    You definitely want to fill this in.
    """
    #self.log("RX %s on %s (%s)", packet, port, api.current_time())
    if isinstance(packet, basics.RoutePacket):
      dst = packet.destination
      cost = packet.latency + self.neighbour[port]
      if packet.latency == INFINITY and self.POISON_MODE:
        if dst in self.table and self.table[dst][0] == port:
          del self.table[dst]
          p = basics.RoutePacket(dst, INFINITY)
          self.send(p, flood=True)
      elif dst not in self.table or cost < self.table[dst][1]:
        self.update(dst, port, cost)
      # trust neighbour
      elif port == self.table[dst][0] and cost > self.table[dst][1]:
        self.update(dst, port, cost)
      elif port == self.table[dst][0] and cost == self.table[dst][1]:
        self.table[dst][2] = api.current_time()

    elif isinstance(packet, basics.HostDiscoveryPacket):
      self.hosts.append(port)
      dst = packet.src
      cost = self.neighbour[port]
      self.update(dst, port, cost)

    else:
      dst = packet.dst
      if dst in self.table and not self.table[dst][1] == INFINITY and self.table[dst][0] != port:
        self.send(packet, self.table[packet.dst][0])
Esempio n. 52
0
  def handle_rx (self, packet, port):
    """
    Called by the framework when this Entity receives a packet.

    packet is a Packet (or subclass).
    port is the port number it arrived on.

    You definitely want to fill this in.
    """
    self.log("RX %s on %s (%s)", packet, port, api.current_time())
    if isinstance(packet, basics.RoutePacket):
        if packet.destination in self.table:
            #either too big or poisoned.
            #possibly no port created.
            if self.infinity(packet.latency, port):
                if port not in self.table[packet.destination]:
                    return
                self.poison(packet.destination,port)
                del(self.table[packet.destination][port])
                best_port = self.best_path(packet.destination);
                if(best_port != None):
                    actual_latency = self.get_latency(packet.destination,best_port)
                    update_packet = basics.RoutePacket(packet.destination, actual_latency)
                    self.send(update_packet,[best_port] + self.hosts.values(), flood = True)
                else:
                    #poison reverse if no proper backup
                    update_packet = basics.RoutePacket(packet.destination, INFINITY)
                    self.send(update_packet, port, flood = False)
                return
            same_port = False
            old_best_port = self.best_path(packet.destination)
            if( port in self.table[packet.destination]):
                old_latency = self.table[packet.destination][port][0]
                new_latency = packet.latency + self.neighbors[port];
                self.table[packet.destination][port][0] = new_latency;
                self.table[packet.destination][port][1] = api.current_time()
                best_port = self.best_path(packet.destination);
                #replace if New optimal port or latency change on own port where it either stays the best option or becomes it.
                if((best_port != old_best_port) or (port == best_port and old_latency!=new_latency)):
                    actual_latency = self.get_latency(packet.destination,best_port)
                    update_packet = basics.RoutePacket(packet.destination, actual_latency)
                    self.send(update_packet,[best_port] + self.hosts.values(), flood = True)

            else:
                new_latency = packet.latency + self.neighbors[port];
                self.table[packet.destination][port] = [new_latency] + [api.current_time()];
                best_port = self.best_path(packet.destination);
                actual_latency = self.table[packet.destination][best_port][0]
                update_packet = basics.RoutePacket(packet.destination, actual_latency)
                self.send(update_packet,[best_port] + self.hosts.values(), flood = True)
        else:
            # if not in the table, update a dictionary mapping
            time_rx = api.current_time()
            actual_latency = packet.latency + self.neighbors[port]
            if not self.infinity(packet.latency,port):
                self.table[packet.destination] = {port: [actual_latency,time_rx]}
                update_packet = basics.RoutePacket(packet.destination,actual_latency);
                self.send(update_packet,[port] + self.hosts.values(),flood=True);
    elif isinstance(packet, basics.HostDiscoveryPacket):
        if(packet.src in self.table):
            self.table[packet.src][port] = [self.neighbors[port]] + [api.current_time()]
        else:
            self.table[packet.src] = {port: [self.neighbors[port]] + [api.current_time()]}
            self.hosts[packet.src] = port
        if(self.neighbors[port]>=INFINITY):
            pass
        update_packet = basics.RoutePacket(packet.src, self.neighbors[port]);
        self.send(update_packet, [port] + self.hosts.values(), flood = True);
    else:
        if packet.dst in self.table:
            best_port = self.best_path(packet.dst)
            #If hairpinning
            if port == best_port:
                return
            self.send(packet, best_port)
        else:
            pass
Esempio n. 53
0
def m_expired(mapping):
    time = m_time(mapping)
    return api.current_time() - time > TIME_TO_REMEMBER_ROUTE
Esempio n. 54
0
def m_update_time(mapping):
    mapping[kTime] = api.current_time()
Esempio n. 55
0
 def handle_host_discover_packet(self, packet, port):
     if not self.NO_LOG:
         self.log("RX HostDiscoveryPacket %s on %s (%s)", packet, port, api.current_time())
     host = packet.src
     # Notify the route map of the new host
     self.route_map.host_discover(host, port)
Esempio n. 56
0
def m_mapping(distance, next_hop):
    return {
        kDistance : distance,
        kNextHop : next_hop,
        kTime : api.current_time(),
    }