Beispiel #1
0
    def __traceDiscoveryPacket(cls, received, type, attrs, addr, port=None):
        """
        Log that a TCF Discovery packet has be sent or received. The trace is
        sent to stdout. This should be called only if the tracing has been turned
        on.

        @param received
                   True if the packet was sent, otherwise it was received
        @param type
                   a string specifying the type of packet, e.g., "CONF_PEER_INFO"
        @param attrs
                   a set of attributes relevant to the type of packet (typically
                   a peer's attributes)
        @param addr
                   the network address the packet is being sent to
        @param port
                   the port the packet is being sent to
        """
        assert __TRACE_DISCOVERY__
        if port is None:
            # addr is a InputPacket
            port = addr.getPort()
            addr = addr.getAddress()
        str = cStringIO.StringIO()
        str.write(type)
        str.write((" sent to ", " received from ")[received])
        str.write("%s/%s" % (addr, port))
        if attrs is not None:
            for key, value in attrs.items():
                str.write("\n\t%s=%s" % (key, value))
        logging.trace(str.getvalue())
Beispiel #2
0
 def __refreshSubNetList(self):
     subNetSet = set()
     try:
         self.__getSubNetList(subNetSet)
     except Exception as x:
         self._log("Cannot get list of network interfaces", x)
     for s in tuple(self.subnets):
         if s in subNetSet: continue
         self.subnets.remove(s)
     for s in subNetSet:
         if s in self.subnets: continue
         self.subnets.add(s)
     if __TRACE_DISCOVERY__:
         str = cStringIO.StringIO()
         str.write("Refreshed subnet list:")
         for subnet in self.subnets:
             str.write("\n\t* address=%s, broadcast=%s" % (subnet.address, subnet.broadcast))
         logging.trace(str.getvalue())
Beispiel #3
0
 def _startup(self):
     if self._alive: return
     self._alive = True
     self._addr_cache_lock = threading.Condition()
     self.subnets = set()
     self.slaves = []
     self.inp_buf = bytearray(MAX_PACKET_SIZE)
     self.out_buf = bytearray(MAX_PACKET_SIZE)
     service = self
     class TimerThread(threading.Thread):
         def __init__(self, callable):
             self._callable = callable
             super(TimerThread, self).__init__()
         def run(self):
             while service._alive:
                 try:
                     time.sleep(locator.DATA_RETENTION_PERIOD / 4 / 1000.)
                     protocol.invokeAndWait(self._callable)
                 except RuntimeError:
                     # TCF event dispatch is shut down
                     return
                 except Exception as x:
                     service._log("Unhandled exception in TCF discovery timer thread", x)
     self.timer_thread = TimerThread(self.__refresh_timer)
     class DNSLookupThread(threading.Thread):
         def run(self):
             while service._alive:
                 try:
                     itemSet = None
                     with service._addr_cache_lock:
                         if not LocatorService.addr_request:
                             service._addr_cache_lock.wait(locator.DATA_RETENTION_PERIOD)
                         msec = int(time.time() * 1000)
                         for host, a in LocatorService.addr_cache.items():
                             if a.time_stamp + locator.DATA_RETENTION_PERIOD * 10 < msec:
                                 if a.used:
                                     if itemSet is None: itemSet = set()
                                     itemSet.add(a)
                                 else:
                                     del LocatorService.addr_cache[host]
                         LocatorService.addr_request = False
                     if itemSet is not None:
                         for a in itemSet:
                             addr = None
                             try:
                                 addr = socket.gethostbyname(a.host)
                             except socket.gaierror:
                                 pass
                             with service._addr_cache_lock:
                                 if addr is None:
                                     a.address = None
                                 else:
                                     a.address = InetAddress(a.host, addr)
                                 a.time_stamp = msec
                                 a.used = False
                 except Exception as x:
                     service._log("Unhandled exception in TCF discovery DNS lookup thread", x)
     self.dns_lookup_thread = DNSLookupThread()
     class InputThread(threading.Thread):
         def __init__(self, callable):
             self._callable = callable
             super(InputThread, self).__init__()
         def run(self):
             try:
                 while service._alive:
                     sock = service.socket
                     try:
                         data, addr = sock.recvfrom(MAX_PACKET_SIZE)
                         p = InputPacket(data, InetAddress(None, addr[0]), addr[1])
                         protocol.invokeAndWait(self._callable, p)
                     except RuntimeError:
                         # TCF event dispatch is shutdown
                         return
                     except socket.error as x:
                         if sock != service.socket: continue
                         # frequent  error on windows, unknown reason
                         if x.errno == 10054: continue
                         port = sock.getsockname()[1]
                         service._log("Cannot read from datagram socket at port %d" % port, x)
                         time.sleep(2)
             except Exception as x:
                 service._log("Unhandled exception in socket reading thread", x)
     self.input_thread = InputThread(self.__handleDatagramPacket)
     try:
         self.loopback_addr = InetAddress(None, "127.0.0.1")
         self.out_buf[0:8] = 'TCF%s\0\0\0\0' % locator.CONF_VERSION
         self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
         try:
             self.socket.bind(('', DISCOVEY_PORT))
             if __TRACE_DISCOVERY__:
                 logging.trace("Became the master agent (bound to port %d)" % self.socket.getsockname()[1])
         except socket.error as x:
             self.socket.bind(('', 0))
             if __TRACE_DISCOVERY__:
                 logging.trace("Became a slave agent (bound to port %d)" % self.socket.getsockname()[1])
         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
         self.input_thread.setName("TCF Locator Receiver")
         self.timer_thread.setName("TCF Locator Timer")
         self.dns_lookup_thread.setName("TCF Locator DNS Lookup")
         self.input_thread.setDaemon(True)
         self.timer_thread.setDaemon(True)
         self.dns_lookup_thread.setDaemon(True)
         self.input_thread.start()
         self.timer_thread.start()
         self.dns_lookup_thread.start()
         class LocatorListener(locator.LocatorListener):
             def peerAdded(self, peer):
                 service._sendPeerInfo(peer, None, 0)
             def peerChanged(self, peer):
                 service._sendPeerInfo(peer, None, 0)
         self.listeners.append(LocatorListener())
         self.__refreshSubNetList()
         self.__sendPeersRequest(None, 0)
         self.__sendAll(None, 0, None, int(time.time() * 1000))
     except Exception as x:
         self._log("Cannot open UDP socket for TCF discovery protocol", x)