def route_new(self, lvl, dst, gw, rem, event_wait=None): if not self.multipath and self.maproute.node_get(lvl, dst).nroutes_synced() >= 1: # We don't have multipath and we've already set one route. return nip = self.maproute.lvlid_to_nip(lvl, dst) ip = self.maproute.nip_to_ip(nip) ipstr = ip_to_str(ip) neigh = self.neigh.id_to_neigh(gw) dev = neigh.bestdev[0] gwipstr = ip_to_str(neigh.ip) neigh_node = self.maproute.node_get(*self.maproute.routeneigh_get(neigh)) if neigh_node.nroutes() > 1: # Let's wait to add the neighbour first while 1: ev_neigh = event_wait[(self.neigh.events, 'NEIGH_NEW')]() if neigh == ev_neigh[0]: # found break if neigh_node.routes_tobe_synced > 0: # The routes to neigh are still to be synced, let's wait while 1: ev_neigh = event_wait[(self.events, 'KRNL_NEIGH_NEW')]() if neigh == ev_neigh[0]: # found break # We can add the route in the kernel KRoute.add(ipstr, lvl_to_bits(lvl), dev, gwipstr) self.maproute.node_get(lvl, dst).routes_tobe_synced-=1
def route_deleted(self, lvl, dst, gw): nip = self.maproute.lvlid_to_nip(lvl, dst) ip = self.maproute.nip_to_ip(nip) ipstr = ip_to_str(ip) neigh = self.neigh.id_to_neigh(gw) dev = neigh.bestdev[0] gwipstr = ip_to_str(neigh.ip) KRoute.delete(ipstr, lvl_to_bits(lvl), gateway=gwipstr)
def run_test_tcp(): print 'Starting tcp server...' rpc.MicroTCPServer(mod, (ip_to_str(N.net[0].ip), PORT), 'lo', N, N.net[0], Sock) micro(tcp_client) allmicro_run()
def delete(self, ip, remove_from_iptable=True): """Deletes an entry from the ip_table""" logging.info("Deleting neighbour %s", ip_to_str(ip)) if remove_from_iptable: del self.ip_table[ip] # close the connection ( if any ) if self.ntk_client[ip].connected: self.ntk_client[ip].close() # delete the entry from the translation table... old_id = self.translation_table.pop(ip) # ...and from the netid_table old_netid = self.netid_table.pop(ip) # send a message notifying we deleted the entry self.events.send('NEIGH_DELETED', (Neigh(bestdev=None, devs=None, idn=old_id, ip=ip, netid=old_netid, ntkd=self.ntk_client[ip]),)) del self.ntk_client[ip]
def delete(self, ip, remove_from_iptable=True): """Deletes an entry from the ip_table""" logging.info("Deleting neighbour %s", ip_to_str(ip)) if remove_from_iptable: del self.ip_table[ip] # close the connection ( if any ) if self.ntk_client[ip].connected: self.ntk_client[ip].close() # delete the entry from the translation table... old_id = self.translation_table.pop(ip) # ...and from the netid_table old_netid = self.netid_table.pop(ip) # send a message notifying we deleted the entry self.events.send('NEIGH_DELETED', (Neigh(bestdev=None, devs=None, idn=old_id, ip=ip, netid=old_netid, ntkd=self.ntk_client[ip]), )) del self.ntk_client[ip]
def tcp_client(): client = rpc.TCPClient(ip_to_str(N.net[0].ip), port=PORT, net=N, me=N.net[1], sockmodgen=Sock) x = 5 xsquare = client.square(x) print xtime.time(), "assert xsquare == 25" assert xsquare == 25 xmul7 = client.mul(x, 7) print xtime.time(), "assert xmul7 == 35" assert xmul7 == 35 xadd9 = client.nestmod.add(x, 9) print xtime.time(), "assert xadd9 == 14" assert xadd9 == 14 # something trickier n, nn = client, client.nestmod result = n.square(n.mul(x, nn.add(x, 10))) assert (1, 2) == client.caller_test(1, 2) try: # should crash now client.private_func() except Exception, e: logging.debug(str(e))
def tcp_client(): client = rpc.TCPClient(ip_to_str(N.net[0].ip), port=PORT, net=N, me=N.net[1], sockmodgen=Sock) x = 5 xsquare = client.square(x) print xtime.time(), 'assert xsquare == 25' assert xsquare == 25 xmul7 = client.mul(x, 7) print xtime.time(), 'assert xmul7 == 35' assert xmul7 == 35 xadd9 = client.nestmod.add(x, 9) print xtime.time(), 'assert xadd9 == 14' assert xadd9 == 14 # something trickier n, nn = client, client.nestmod result = n.square(n.mul(x, nn.add(x, 10))) assert (1, 2) == client.caller_test(1, 2) try: # should crash now client.private_func() except Exception, e: logging.debug(str(e))
def neigh_new(self, neigh): ipstr = ip_to_str(neigh.ip) dev = neigh.bestdev[0] gwipstr = ipstr KRoute.add(ipstr, lvl_to_bits(0), dev, gwipstr) self.events.send('KRNL_NEIGH_NEW', (neigh,))
def neigh_new(self, neigh): ipstr = ip_to_str(neigh.ip) dev = neigh.bestdev[0] gwipstr = ipstr KRoute.add(ipstr, lvl_to_bits(0), dev, gwipstr) self.events.send('KRNL_NEIGH_NEW', (neigh, ))
def store(self, ip_table): """Substitute the old ip_table with the new and notify about the changes ip_table: the new ip_table; """ # the rows deleted during truncation died_ip_list = [] ip_table, died_ip_list = self._truncate(ip_table) # first of all we cycle through the old ip_table # looking for nodes that aren't in the new one for key in self.ip_table: # if we find a row that isn't in the new ip_table and whose # deletion hasn't already been notified (raising an event) # during truncation if not key in ip_table and not key in died_ip_list: self.delete(key, remove_from_iptable=False) # now we cycle through the new ip_table # looking for nodes who weren't in the old one # or whose rtt has sensibly changed for key in ip_table: # if a node has been added if not key in self.ip_table: # generate an id and add the entry in translation_table self.ip_to_id(key) # create a TCP connection to the neighbour self.ntk_client[key] = rpc.TCPClient(ip_to_str(key)) # send a message notifying we added a node self.events.send('NEIGH_NEW', (Neigh(bestdev=ip_table[key].bestdev, devs=ip_table[key].devs, idn=self.translation_table[key], ip=key, netid=self.netid_table[key], ntkd=self.ntk_client[key]),)) else: # otherwise (if the node already was in old ip_table) check if # its rtt has changed more than rtt_variation new_rtt = ip_table[key].bestdev[1] old_rtt = self.ip_table[key].bestdev[1] rtt_variation = abs(new_rtt - old_rtt) / float(old_rtt) if rtt_variation > self.rtt_variation_threshold: # send a message notifying the node's rtt changed self.events.send('NEIGH_REM_CHGED', (Neigh(bestdev=self.ip_table[key].bestdev, devs=self.ip_table[key].devs, idn=self.translation_table[key], ip=key, netid=self.netid_table[key], ntkd=self.ntk_client[key]), Rtt(new_rtt))) # finally, update the ip_table self.ip_table = ip_table
def store(self, ip_table): """Substitute the old ip_table with the new and notify about the changes ip_table: the new ip_table; """ # the rows deleted during truncation died_ip_list = [] ip_table, died_ip_list = self._truncate(ip_table) # first of all we cycle through the old ip_table # looking for nodes that aren't in the new one for key in self.ip_table: # if we find a row that isn't in the new ip_table and whose # deletion hasn't already been notified (raising an event) # during truncation if not key in ip_table and not key in died_ip_list: self.delete(key, remove_from_iptable=False) # now we cycle through the new ip_table # looking for nodes who weren't in the old one # or whose rtt has sensibly changed for key in ip_table: # if a node has been added if not key in self.ip_table: # generate an id and add the entry in translation_table self.ip_to_id(key) # create a TCP connection to the neighbour self.ntk_client[key] = rpc.TCPClient(ip_to_str(key)) # send a message notifying we added a node self.events.send('NEIGH_NEW', (Neigh(bestdev=ip_table[key].bestdev, devs=ip_table[key].devs, idn=self.translation_table[key], ip=key, netid=self.netid_table[key], ntkd=self.ntk_client[key]), )) else: # otherwise (if the node already was in old ip_table) check if # its rtt has changed more than rtt_variation new_rtt = ip_table[key].bestdev[1] old_rtt = self.ip_table[key].bestdev[1] rtt_variation = abs(new_rtt - old_rtt) / float(old_rtt) if rtt_variation > self.rtt_variation_threshold: # send a message notifying the node's rtt changed self.events.send( 'NEIGH_REM_CHGED', (Neigh(bestdev=self.ip_table[key].bestdev, devs=self.ip_table[key].devs, idn=self.translation_table[key], ip=key, netid=self.netid_table[key], ntkd=self.ntk_client[key]), Rtt(new_rtt))) # finally, update the ip_table self.ip_table = ip_table
def echo_client(): socket = Sock(N, N.net[1]) s1 = socket.socket(AF_INET, SOCK_DGRAM) ip = ip_to_str(0) r = randint(0, 256) print "t:", xtime.time(), ("sending data %d to " + ip) % (r) s1.sendto('hey ' + str(r), (ip, 51423)) message, address = s1.recvfrom(8192) print "t:", xtime.time(), "got reply from %s: %s" % (address, message)
def echo_client(): socket=Sock(N, N.net[1]) s1=socket.socket(AF_INET, SOCK_DGRAM) ip = ip_to_str(0) r=randint(0, 256) print "t:", xtime.time(), ("sending data %d to "+ip)%(r) s1.sendto('hey '+str(r), (ip, 51423)) message, address = s1.recvfrom(8192) print "t:", xtime.time(), "got reply from %s: %s"%(address, message)
def echo_client_II(): socket = Sock(N, N.net[1]) s1 = socket.socket(AF_INET, SOCK_DGRAM) ip = ip_to_str(0) r = randint(0, 256) print "t:", xtime.time(), ("II sending data %d to " + ip) % (r) s1.connect((ip, 51423)) s1.send('hey ' + str(r)) message = s1.recv(8192) print "t:", xtime.time(), "got reply from %s: %s" % (ip, message)
def echo_client_II(): socket=Sock(N, N.net[1]) s1=socket.socket(AF_INET, SOCK_DGRAM) ip = ip_to_str(0) r=randint(0, 256) print "t:", xtime.time(), ("II sending data %d to "+ip)%(r) s1.connect((ip, 51423)) s1.send('hey '+str(r)) message = s1.recv(8192) print "t:", xtime.time(), "got reply from %s: %s"%(ip, message)
def accept(self): if self.sck_type == SOCK_DGRAM: raise error, (EINVAL, os.strerror(EINVAL)) sck, node = self.me.accept() addr = ip_to_str(node.ip) retsck = VirtualSocket(self.addr_family, self.sck_type, self.net, self.me) retsck.sck = sck retsck.addr = addr retsck.node = node return retsck, (addr, 1)
def ip_change(self, oldip, newip): """Adds `newip' in the Neighbours as a copy of `oldip', then it removes `oldip'. The relative events are raised.""" logging.info("New IP of neighbour %s is now %s " % (ip_to_str(oldip), ip_to_str(newip))) self.ip_table[newip] = self.ip_table[oldip] self.translation_table[newip] = self.translation_table[oldip] self.netid_table[newip] = self.netid_table[oldip] # we have to create a new TCP connection self.ntk_client[newip] = rpc.TCPClient(ip_to_str(newip)) self.events.send('NEIGH_NEW', (Neigh(bestdev=self.ip_table[newip].bestdev, devs=self.ip_table[newip].devs, idn=self.translation_table[newip], ip=newip, netid=self.netid_table[newip], ntkd=self.ntk_client[newip]),)) self.delete(oldip)
def ip_change(self, oldip, newip): """Adds `newip' in the Neighbours as a copy of `oldip', then it removes `oldip'. The relative events are raised.""" logging.info("New IP of neighbour %s is now %s " % (ip_to_str(oldip), ip_to_str(newip))) self.ip_table[newip] = self.ip_table[oldip] self.translation_table[newip] = self.translation_table[oldip] self.netid_table[newip] = self.netid_table[oldip] # we have to create a new TCP connection self.ntk_client[newip] = rpc.TCPClient(ip_to_str(newip)) self.events.send('NEIGH_NEW', (Neigh(bestdev=self.ip_table[newip].bestdev, devs=self.ip_table[newip].devs, idn=self.translation_table[newip], ip=newip, netid=self.netid_table[newip], ntkd=self.ntk_client[newip]), )) self.delete(oldip)
def tcp_echo_client(): socket = Sock(N, N.net[1]) s1 = socket.socket(AF_INET, SOCK_STREAM) ip = ip_to_str(0) print "t:", xtime.time(), "waiting" xtime.swait(70) print "t:", xtime.time(), "connecting to " + ip s1.connect((ip, 51423)) r = randint(0, 256) s1.send('Hallo, ' + str(r)) s1.send('How are you?') message = s1.recv(8192) print "t:", xtime.time(), "tcp server replied:", message
def tcp_echo_client(): socket=Sock(N, N.net[1]) s1=socket.socket(AF_INET, SOCK_STREAM) ip = ip_to_str(0) print "t:", xtime.time(), "waiting" xtime.swait(70) print "t:", xtime.time(), "connecting to "+ip s1.connect((ip, 51423)) r=randint(0, 256) s1.send('Hallo, '+str(r)) s1.send('How are you?') message = s1.recv(8192) print "t:", xtime.time(), "tcp server replied:", message
def route_new(self, lvl, dst, gw, rem, event_wait=None): if not self.multipath and self.maproute.node_get( lvl, dst).nroutes_synced() >= 1: # We don't have multipath and we've already set one route. return nip = self.maproute.lvlid_to_nip(lvl, dst) ip = self.maproute.nip_to_ip(nip) ipstr = ip_to_str(ip) neigh = self.neigh.id_to_neigh(gw) dev = neigh.bestdev[0] gwipstr = ip_to_str(neigh.ip) neigh_node = self.maproute.node_get( *self.maproute.routeneigh_get(neigh)) if neigh_node.nroutes() > 1: # Let's wait to add the neighbour first while 1: ev_neigh = event_wait[(self.neigh.events, 'NEIGH_NEW')]() if neigh == ev_neigh[0]: # found break if neigh_node.routes_tobe_synced > 0: # The routes to neigh are still to be synced, let's wait while 1: ev_neigh = event_wait[(self.events, 'KRNL_NEIGH_NEW')]() if neigh == ev_neigh[0]: # found break # We can add the route in the kernel KRoute.add(ipstr, lvl_to_bits(lvl), dev, gwipstr) self.maproute.node_get(lvl, dst).routes_tobe_synced -= 1
def time_register(self, _rpc_caller, radar_id, netid): """save each node's rtt""" if radar_id != self.radar_id: # drop. It isn't a reply to our current bouquet return ip = str_to_ip(_rpc_caller.ip) net_device = _rpc_caller.dev # this is the rtt time_elapsed = int((self.xtime.time() - self.bcast_send_time) / 2) # let's store it in the bcast_arrival_time table if ip in self.bcast_arrival_time: if net_device in self.bcast_arrival_time[ip]: self.bcast_arrival_time[ip][net_device].append(time_elapsed) else: self.bcast_arrival_time[ip][net_device] = [time_elapsed] else: self.bcast_arrival_time[ip] = {} self.bcast_arrival_time[ip][net_device] = [time_elapsed] logging.info("Radar: new IP %s detected", ip_to_str(ip)) self.neigh.netid_table[ip] = netid
def neigh_deleted(self, neigh): ipstr = ip_to_str(neigh.ip) KRoute.delete(ipstr, lvl_to_bits(0))
def testIPToStr(self): ''' Test conversion ip --> str ''' ip = inet.pip_to_ip(inet.str_to_pip(self.ps)) self.assertEqual(inet.ip_to_str(ip), self.ps)
def __repr__(self): return '<Neighbour(%s):%s>' % (ip_to_str(self.ip), self.rem)
def run_test_tcp(): print "Starting tcp server..." rpc.MicroTCPServer(mod, (ip_to_str(N.net[0].ip), PORT), "lo", N, N.net[0], Sock) micro(tcp_client) allmicro_run()
def getsockname(self): return (ip_to_str(self.me.ip), 1)
def getpeername(self): return (ip_to_str(self.addr), 1)
def recvfrom(self, buflen, flag=0): try: src, msg = self.me.recvfrom() return (msg, (ip_to_str(src.ip), 0)) except: raise error, (ENOTSOCK, os.strerror(ENOTSOCK))
def hook(self, neigh_list=[], forbidden_neighs=[], condition=False, gnumb=0): """Lets the current node become a hooking node. I neigh_list!=[], it tries to hook among the given neighbours list, otherwise neigh_list is generated from the Radar. forbidden_neighs is a list [(lvl,nip), ...]. All the neighbours nr with a NIP nr.nip matching nip up to lvl levels are excluded, that is: NIP is excluded <==> nip_cmp(nip, NIP) < lvl If condition is True, the re-hook take place only if the following is true: gnumb < |G| |G'| < |G| where |G'| and `gnumb' is the number of nodes of the gnode where we are going to re-hook, and |G| is the number of nodes of our gnodes. |G'| and |G| are calculated using the coordinator nodes. Note: this is used only by communicating_vessels() """ oldnip=self.maproute.me[:] we_are_alone=False ## Find all the highest non saturated gnodes hfn = [(self.maproute.me, self.highest_free_nodes())] if neigh_list == []: neigh_list = self.neigh.neigh_list() if neigh_list == []: we_are_alone = True def is_neigh_forbidden(nrip): for lvl, fnr in forbidden_neighs: if self.maproute.nip_cmp(nrnip, fnr) < lvl: return True return False for nr in neigh_list: nrnip=self.maproute.ip_to_nip(nr.ip) if self.maproute.nip_cmp(self.maproute.me, nrnip) <= 0: # we're interested in external neighbours continue if is_neigh_forbidden(nrnip): # We don't want forbidden neighbours continue hfn.append((nrnip, nr.ntkd.hook.highest_free_nodes())) ## ## Find all the hfn elements with the highest level and ## remove all the lower ones hfn2=[] hfn_lvlmax = -1 for h in hfn: if h[1][0] > hfn_lvlmax: hfn_lvlmax = h[1][0] hfn2=[] if h[1][0] == hfn_lvlmax: hfn2.append(h) hfn=hfn2 ## ## Find the list with the highest number of elements lenmax = 0 for h in hfn: l=len(h[1][1]) if l > lenmax: lenmax=l H=h ## if lenmax == 0: raise Exception, "Netsukuku is full" ## Generate part of our new IP newnip = list(H[0]) lvl = H[1][0] fnl = H[1][1] newnip[lvl] = choice(fnl) for l in reversed(xrange(lvl)): newnip[l]=randint(0, self.maproute.gsize-1) # If we are alone, let's generate our netid if we_are_alone: self.radar.netid = randint(0, 2**32-1) ## if lvl < self.maproute.levels-1: # We are creating a new gnode which is not in the latest # level. # Contact the coordinator nodes if lvl > 0: # If we are going to create a new gnode, it's useless to pose # any condition condition=False if condition: # <<I'm going out>> co = self.coordnode.peer(key = (1, self.maproute.me)) # get |G| and check that gnumb < |G| Gnumb = co.going_out(0, self.maproute.me[0], gnumb) if Gnumb == None: # nothing to be done return # <<I'm going in, can I?>> co2 = self.coordnode.peer(key = (lvl+1, newnip)) # ask if we can get in and if |G'| < |G|, and get our new IP newnip=co2.going_in(lvl, Gnumb) if newnip: # we've been accepted co.going_out_ok(0, self.maproute.me[0]) else: raise Exception, "Netsukuku is full" co.close() co2.close() elif not we_are_alone: # <<I'm going in, can I?>> co2 = self.coordnode.peer(key = (lvl+1, newnip)) # ask if we can get in, get our new IP newnip=co2.going_in(lvl) if newnip == None: raise Exception, "Netsukuku is full" co2.close() ## ## complete the hook self.radar.do_reply = False # close the ntkd sessions for nr in self.neigh.neigh_list(): if nr.ntkd.connected: nr.ntkd.close() # change the IPs of the NICs newnip_ip = self.maproute.nip_to_ip(newnip) self.nics.activate(ip_to_str(newnip_ip)) # reset the map self.maproute.me_change(newnip[:]) for l in reversed(xrange(lvl)): self.maproute.level_reset(l) # Restore the neighbours in the map and send the ETP self.neigh.readvertise() # warn our neighbours oldip = self.maproute.nip_to_ip(oldnip) for nr in self.neigh.neigh_list(): logging.debug("Hook: calling ip_change of my neighbour %s" % ip_to_str(nr.ip)) nr.ntkd.neighbour.ip_change(oldip, newnip_ip) self.radar.do_reply = True # we've done our part self.events.send('HOOKED', (oldip, newnip[:]))