Пример #1
0
 def bootstrap(self, timeout=5, interval=30):
     """A generator to perform bootstrap function."""
     candidates = self.candidates[:]  # a copy of list of candidates
     while True:
         if _debug:
             print self.net.name, "bootstrap server=", self.server, "neighbors=", len(
                 self.neighbors
             ), "candidates=", len(candidates)
         if not self.server and not self.neighbors and candidates:  # more candidates but no more neighbors
             node = candidates.pop(0)
             if _debug:
                 print "bootstrap trying node=", repr(node)
             if node.type == socket.SOCK_DGRAM and isMulticast(node.ip):
                 yield self.net.send(Message(name="Discover:Request"), node=node)
                 msg = yield self.net.get(lambda x: x.name == "Discover:Response" and x.multicast, timeout=timeout)
             else:
                 if not isIPv4(node.ip):  # is a IP address?
                     node = Node(ip=socket.gethostbyname(node.ip), port=node.port, type=node.type, guid=node.guid)
                 yield self.net.send(Message(name="Discover:Request"), node=node)
                 msg = yield self.net.get(
                     lambda x: x.name == "Discover:Response" and not x.multicast, timeout=timeout
                 )
             if msg:
                 added = False
                 for node in msg.neighbors:
                     if (
                         node.hostport == msg.remote.hostport
                     ):  # whether msg.remote exists in msg.neighbors, which means remote is a server and we are already connected.
                         if _debug:
                             print "received neighbor", repr(node)
                         self.neighbors.insert(0, node)  # put this as most preferred neighbor.
                         added = True
                     else:
                         if _debug:
                             print "received candidate", repr(node)
                         candidates.append(node)  # put this as the next candidate
                 if added:
                     yield self.net.put(
                         Message(name="Discover:Indication", node=self.node, neighbors=self.neighbors)
                     )  # indicate change in client.
             else:
                 if _debug:
                     print "bootstrap did not receive response."
         elif not self.server and self.neighbors:  # perform neighbor refresh
             yield dht.randomsleep(timeout)
             result = yield self.net.send(Message(name="Ping:Request"), node=self.neighbors[0], timeout=timeout)
             if not result:  # no response received, remove the neighbor
                 del self.neighbors[0]
                 yield self.net.put(
                     Message(name="Discover:Indication", node=self.node, neighbors=self.neighbors)
                 )  # indicate change in client.
         elif not self.server and not self.neighbors and not candidates:
             candidates = self.candidates[:]
             yield dht.randomsleep(timeout)
         else:  # just wait before trying again.
             yield dht.randomsleep(interval)
Пример #2
0
 def promotionhandler(self, timeout=10): # TODO: change to 10 min (600) for production use.
     '''Promote the node to super node after some uptime.'''
     yield dht.randomsleep(timeout) # wait for some uptime
     if _debug: print 'promotionhandler invoked'
     if self.client and self.client.neighbors:
         if self.router is None: self.router = dht.Router(self.net).start()
         if self.storage is None: self.storage = dht.Storage(self.net, self.router).start()
         if not self.router.initialized: 
             self.router.bs = self.client.neighbors;
             if _debug: print 'joining the dht'
             joined = yield self.router.join(self.router.bs[0])
             if joined: 
                 self.client.server = True
Пример #3
0
 def mcastreceiver(self, maxsize=1500, timeout=None, interval=30):
     while True:
         if self.mcast is not None:
             data, addr = yield multitask.recvfrom(self.mcast, maxsize, timeout=timeout)
             msg, remote = self.parse(data, addr, self.mcast.type)
             if not msg: print 'ignoring empty msg'; continue # ignore invalid message. TODO: handle non-p2p message
             if remote == self.node: 
                 if _debug: print 'ignoring our own multicast packet'
                 continue
             if _debug: print self.name, 'mcast-received %s=>%s: %r'%(remote.hostport, self.nodemcast.hostport, msg)
             if 'ack' in msg: del msg['ack'] # just remove ack, but don't send an ack for multicast
             msg['remote'] = remote
             msg['multicast'] = True # so that application knows that this is received on multicast
             yield self.put(msg) 
         else:
             yield dht.randomsleep(interval)
Пример #4
0
 def promotionhandler(
         self,
         timeout=10):  # TODO: change to 10 min (600) for production use.
     '''Promote the node to super node after some uptime.'''
     yield dht.randomsleep(timeout)  # wait for some uptime
     if _debug: print 'promotionhandler invoked'
     if self.client and self.client.neighbors:
         if self.router is None: self.router = dht.Router(self.net).start()
         if self.storage is None:
             self.storage = dht.Storage(self.net, self.router).start()
         if not self.router.initialized:
             self.router.bs = self.client.neighbors
             if _debug: print 'joining the dht'
             joined = yield self.router.join(self.router.bs[0])
             if joined:
                 self.client.server = True
Пример #5
0
 def mcastreceiver(self, maxsize=1500, timeout=None, interval=30):
     while True:
         if self.mcast is not None:
             data, addr = yield multitask.recvfrom(self.mcast,
                                                   maxsize,
                                                   timeout=timeout)
             msg, remote = self.parse(data, addr, self.mcast.type)
             if not msg:
                 print 'ignoring empty msg'
                 continue  # ignore invalid message. TODO: handle non-p2p message
             if remote == self.node:
                 if _debug: print 'ignoring our own multicast packet'
                 continue
             if _debug:
                 print self.name, 'mcast-received %s=>%s: %r' % (
                     remote.hostport, self.nodemcast.hostport, msg)
             if 'ack' in msg:
                 del msg[
                     'ack']  # just remove ack, but don't send an ack for multicast
             msg['remote'] = remote
             msg['multicast'] = True  # so that application knows that this is received on multicast
             yield self.put(msg)
         else:
             yield dht.randomsleep(interval)
Пример #6
0
 def bootstrap(self, timeout=5, interval=30):
     '''A generator to perform bootstrap function.'''
     candidates = self.candidates[:]  # a copy of list of candidates
     while True:
         if _debug:
             print self.net.name, 'bootstrap server=', self.server, 'neighbors=', len(
                 self.neighbors), 'candidates=', len(candidates)
         if not self.server and not self.neighbors and candidates:  # more candidates but no more neighbors
             node = candidates.pop(0)
             if _debug: print 'bootstrap trying node=', repr(node)
             if node.type == socket.SOCK_DGRAM and isMulticast(node.ip):
                 yield self.net.send(Message(name='Discover:Request'),
                                     node=node)
                 msg = yield self.net.get(
                     lambda x: x.name == 'Discover:Response' and x.
                     multicast,
                     timeout=timeout)
             else:
                 if not isIPv4(node.ip):  # is a IP address?
                     node = Node(ip=socket.gethostbyname(node.ip),
                                 port=node.port,
                                 type=node.type,
                                 guid=node.guid)
                 yield self.net.send(Message(name='Discover:Request'),
                                     node=node)
                 msg = yield self.net.get(
                     lambda x: x.name == 'Discover:Response' and not x.
                     multicast,
                     timeout=timeout)
             if msg:
                 added = False
                 for node in msg.neighbors:
                     if node.hostport == msg.remote.hostport:  # whether msg.remote exists in msg.neighbors, which means remote is a server and we are already connected.
                         if _debug: print 'received neighbor', repr(node)
                         self.neighbors.insert(
                             0,
                             node)  # put this as most preferred neighbor.
                         added = True
                     else:
                         if _debug: print 'received candidate', repr(node)
                         candidates.append(
                             node)  # put this as the next candidate
                 if added:
                     yield self.net.put(
                         Message(name='Discover:Indication',
                                 node=self.node,
                                 neighbors=self.neighbors)
                     )  # indicate change in client.
             else:
                 if _debug: print 'bootstrap did not receive response.'
         elif not self.server and self.neighbors:  # perform neighbor refresh
             yield dht.randomsleep(timeout)
             result = yield self.net.send(Message(name='Ping:Request'),
                                          node=self.neighbors[0],
                                          timeout=timeout)
             if not result:  # no response received, remove the neighbor
                 del self.neighbors[0]
                 yield self.net.put(
                     Message(name='Discover:Indication',
                             node=self.node,
                             neighbors=self.neighbors)
                 )  # indicate change in client.
         elif not self.server and not self.neighbors and not candidates:
             candidates = self.candidates[:]
             yield dht.randomsleep(timeout)
         else:  # just wait before trying again.
             yield dht.randomsleep(interval)