コード例 #1
0
ファイル: dispynetrelay.py プロジェクト: wsfax/dispy
    def listen_udp_proc(self, addrinfo, task=None):
        task.set_daemon()

        if addrinfo.family == socket.AF_INET6:
            mreq = socket.inet_pton(addrinfo.family, addrinfo.broadcast)
            mreq += struct.pack('@I', addrinfo.ifn)

        bc_sock = AsyncSocket(socket.socket(addrinfo.family, socket.SOCK_DGRAM))
        if addrinfo.family == socket.AF_INET:
            bc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        else: # addrinfo.family == socket.AF_INET6
            bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS,
                               struct.pack('@i', 1))
            bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, addrinfo.ifn)
        bc_sock.bind((addrinfo.ip, 0))
        if self.scheduler_ip_addrs and self.scheduler_port:
            relay_request = {'ip_addrs': self.scheduler_ip_addrs, 'port': self.scheduler_port,
                             'version': __version__, 'sign': None}
            bc_sock.sendto('PING:'.encode() + serialize(relay_request),
                           (self._broadcast, self.node_port))

        listen_sock = AsyncSocket(socket.socket(addrinfo.family, socket.SOCK_DGRAM))
        if addrinfo.family == socket.AF_INET:
            listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        else: # addrinfo.family == socket.AF_INET6
            listen_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
        listen_sock.bind((addrinfo.ip, self.listen_port))

        while 1:
            msg, addr = yield listen_sock.recvfrom(1024)
            if not msg.startswith('PING:'.encode()):
                logger.debug('Ignoring message "%s" from %s',
                             msg[:min(len(msg), 5)], addr[0])
                continue
            logger.debug('Ping message from %s (%s)', addr[0], addr[1])
            try:
                info = deserialize(msg[len('PING:'.encode()):])
                if info['version'] != __version__:
                    logger.warning('Ignoring %s due to version mismatch: %s / %s',
                                   info['ip_addrs'], info['version'], __version__)
                    continue
                self.scheduler_ip_addrs = info['ip_addrs'] + [addr[0]]
                self.scheduler_port = info['port']
            except:
                logger.debug('Ignoring ping message from %s (%s)', addr[0], addr[1])
                logger.debug(traceback.format_exc())
                continue
            if info.get('relay', None):
                logger.debug('Ignoring ping back (from %s)', addr[0])
                continue
            logger.debug('relaying ping from %s / %s', info['ip_addrs'], addr[0])
            if self.node_port == self.listen_port:
                info['relay'] = 'y'  # 'check if this message loops back to self

            yield bc_sock.sendto('PING:'.encode() + serialize(info), addr)
コード例 #2
0
 def discover_nodes(self, task=None):
     addrinfos = list(self.addrinfos.values())
     for addrinfo in addrinfos:
         info_msg = {
             'ip_addr': addrinfo.ip,
             'port': self.info_port,
             'sign': self.sign,
             'version': _dispy_version
         }
         bc_sock = AsyncSocket(
             socket.socket(addrinfo.family, socket.SOCK_DGRAM))
         bc_sock.settimeout(MsgTimeout)
         ttl_bin = struct.pack('@i', 1)
         if addrinfo.family == socket.AF_INET:
             if self.ipv4_udp_multicast:
                 bc_sock.setsockopt(socket.IPPROTO_IP,
                                    socket.IP_MULTICAST_TTL, ttl_bin)
             else:
                 bc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST,
                                    1)
         else:  # addrinfo.family == socket.AF_INET6
             bc_sock.setsockopt(socket.IPPROTO_IPV6,
                                socket.IPV6_MULTICAST_HOPS, ttl_bin)
             bc_sock.setsockopt(socket.IPPROTO_IPV6,
                                socket.IPV6_MULTICAST_IF, addrinfo.ifn)
         bc_sock.bind((addrinfo.ip, 0))
         try:
             yield bc_sock.sendto(b'NODE_INFO:' + serialize(info_msg),
                                  (addrinfo.broadcast, self.node_port))
         except Exception:
             pass
         bc_sock.close()
コード例 #3
0
ファイル: dispynetrelay.py プロジェクト: ian2009/dispy
    def verify_broadcast(self, addrinfo, msg, task=None):
        if msg.get('relay', None):
            raise StopIteration
        msg['relay'] = 'y'
        # TODO: check if current scheduler is done with nodes?
        if msg['sign']:
            msg['auth'] = dispy.auth_code(self.secret, msg['sign'])
        reply = None
        for scheduler_ip_addr in msg['ip_addrs']:
            msg['scheduler_ip_addr'] = scheduler_ip_addr
            sock = AsyncSocket(socket.socket(addrinfo.family,
                                             socket.SOCK_STREAM),
                               keyfile=self.keyfile,
                               certfile=self.certfile)
            sock.settimeout(dispy.MsgTimeout)
            try:
                yield sock.connect((scheduler_ip_addr, msg['port']))
                yield sock.send_msg('RELAY_INFO:'.encode() + serialize(msg))
                reply = yield sock.recv_msg()
                reply = deserialize(reply)
            except:
                continue
            else:
                break
            finally:
                sock.close()

        if not reply:
            raise StopIteration

        # TODO: since dispynetrelay is not aware of computations closing, if
        # more than one client sends ping, nodes will respond to different
        # clients
        self.scheduler_ip_addr = reply['ip_addrs'] = [scheduler_ip_addr]
        self.scheduler_port = reply['port']
        bc_sock = AsyncSocket(socket.socket(addrinfo.family,
                                            socket.SOCK_DGRAM))
        ttl_bin = struct.pack('@i', 1)
        if addrinfo.family == socket.AF_INET:
            if self.ipv4_udp_multicast:
                bc_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL,
                                   ttl_bin)
            else:
                bc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        else:  # addrinfo.family == socket.AF_INET6
            bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS,
                               ttl_bin)
            bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF,
                               addrinfo.ifn)
        bc_sock.bind((addrinfo.ip, 0))
        yield bc_sock.sendto('PING:'.encode() + serialize(msg),
                             (addrinfo.broadcast, self.node_port))
        bc_sock.close()
コード例 #4
0
ファイル: dispynetrelay.py プロジェクト: pgiri/dispy
    def verify_broadcast(self, addrinfo, msg, task=None):
        if msg.get('relay', None):
            raise StopIteration
        msg['relay'] = 'y'
        # TODO: check if current scheduler is done with nodes?
        if msg['sign']:
            msg['auth'] = dispy.auth_code(self.secret, msg['sign'])
        reply = None
        for scheduler_ip_addr in msg['ip_addrs']:
            msg['scheduler_ip_addr'] = scheduler_ip_addr
            sock = AsyncSocket(socket.socket(addrinfo.family, socket.SOCK_STREAM),
                               keyfile=self.keyfile, certfile=self.certfile)
            sock.settimeout(dispy.MsgTimeout)
            try:
                yield sock.connect((scheduler_ip_addr, msg['port']))
                yield sock.send_msg('RELAY_INFO:'.encode() + serialize(msg))
                reply = yield sock.recv_msg()
                reply = deserialize(reply)
            except Exception:
                continue
            else:
                break
            finally:
                sock.close()

        if not reply:
            raise StopIteration

        # TODO: since dispynetrelay is not aware of computations closing, if
        # more than one client sends ping, nodes will respond to different
        # clients
        self.scheduler_ip_addr = reply['ip_addrs'] = [scheduler_ip_addr]
        self.scheduler_port = reply['port']
        bc_sock = AsyncSocket(socket.socket(addrinfo.family, socket.SOCK_DGRAM))
        ttl_bin = struct.pack('@i', 1)
        if addrinfo.family == socket.AF_INET:
            if self.ipv4_udp_multicast:
                bc_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
            else:
                bc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        else:  # addrinfo.family == socket.AF_INET6
            bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
            bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, addrinfo.ifn)
        bc_sock.bind((addrinfo.ip, 0))
        yield bc_sock.sendto('PING:'.encode() + serialize(msg),
                             (addrinfo.broadcast, self.node_port))
        bc_sock.close()
コード例 #5
0
    def sched_udp_proc(self, addrinfo, task=None):
        task.set_daemon()

        sched_sock = AsyncSocket(
            socket.socket(addrinfo.family, socket.SOCK_DGRAM))
        if addrinfo.family == socket.AF_INET:
            sched_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        else:  # addrinfo.family == socket.AF_INET6
            mreq = socket.inet_pton(addrinfo.family, addrinfo.broadcast)
            mreq += struct.pack('@I', addrinfo.ifn)
            sched_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP,
                                  mreq)

        sched_sock.bind((addrinfo.ip, self.scheduler_port))

        while 1:
            msg, addr = yield sched_sock.recvfrom(1024)
            if (not msg.startswith('PING:'.encode())
                    or not self.scheduler_ip_addrs or not self.scheduler_port):
                logger.debug('Ignoring ping message from %s (%s)', addr[0],
                             addr[1])
                continue
            try:
                info = deserialize(msg[len('PING:'.encode()):])
                assert info['version'] == __version__
                # assert isinstance(info['cpus'], int)
            except:
                logger.debug(traceback.format_exc())
            msg = {
                'ip_addrs': self.scheduler_ip_addrs,
                'port': self.scheduler_port,
                'version': __version__
            }
            if info.get('relay', None):
                logger.debug('Ignoring ping back from %s: %s', addr[0], info)
                continue
            msg['relay'] = 'y'
            relay_sock = AsyncSocket(
                socket.socket(addrinfo.family, socket.SOCK_DGRAM))
            relay_sock.bind((addrinfo.ip, 0))
            yield relay_sock.sendto('PING:'.encode() + serialize(msg),
                                    (info['ip_addr'], info['port']))
            relay_sock.close()
コード例 #6
0
ファイル: dispyadmin.py プロジェクト: pgiri/dispy
    def timer_proc(self, task=None):
        task.set_daemon()

        last_ping = 0
        addrinfos = list(self.addrinfos.values())
        while 1:
            yield task.sleep(self.poll_interval)
            now = time.time()
            with self.lock:
                nodes = list(self.nodes.values())
            # TODO: it may be better to have nodes send updates periodically
            for node in nodes:
                if node._priv.auth:
                    Task(self.update_node_info, node)
            if (now - last_ping) >= self.ping_interval:
                last_ping = now
                for addrinfo in addrinfos:
                    info_msg = {'ip_addr': addrinfo.ip, 'port': self.info_port,
                                'sign': self.sign, 'version': _dispy_version}
                    bc_sock = AsyncSocket(socket.socket(addrinfo.family, socket.SOCK_DGRAM))
                    bc_sock.settimeout(MsgTimeout)
                    ttl_bin = struct.pack('@i', 1)
                    if addrinfo.family == socket.AF_INET:
                        if self.ipv4_udp_multicast:
                            bc_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
                        else:
                            bc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
                    else:  # addrinfo.family == socket.AF_INET6
                        bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
                        bc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF,
                                           addrinfo.ifn)
                    bc_sock.bind((addrinfo.ip, 0))
                    try:
                        yield bc_sock.sendto('NODE_INFO:' + serialize(info_msg),
                                             (addrinfo.broadcast, self.node_port))
                    except Exception:
                        pass
                    bc_sock.close()