예제 #1
0
 def _do_send_identity_to_router(self, identity_source, failed_event):
     try:
         identity_obj = identity.identity(xmlsrc=identity_source)
     except:
         lg.exc()
         return
     if _Debug:
         lg.out(_DebugLevel, 'proxy_receiver.doSendMyIdentity to %s' % self.router_idurl)
         lg.out(_DebugLevel, '        contacts=%s, sources=%s' % (identity_obj.contacts, identity_obj.sources))
     newpacket = signed.Packet(
         commands.Identity(),
         my_id.getLocalID(),
         my_id.getLocalID(),
         commands.Identity(),
         identity_source,
         self.router_idurl,
     )
     packet_out.create(
         newpacket,
         wide=True,
         callbacks={
             commands.Ack(): lambda response, info: self.automat('ack-received', (response, info)),
             commands.Fail(): lambda x: self.automat(failed_event),
         },
         keep_alive=True,
     )
예제 #2
0
def OutboxStatus(pkt_out, status, error=''):
    """
    This method is called when raised a status report after sending a packet to
    remote peer.

    If packet sending was failed - user seems to be OFFLINE.
    """
    global _ShutdownFlag
    if _ShutdownFlag:
        return False
    if pkt_out.outpacket.RemoteID.to_bin() == my_id.getIDURL().to_bin():
        return False
    if pkt_out.outpacket.CreatorID.to_bin() != my_id.getIDURL().to_bin():
        return False
    if status == 'finished':
        if error == 'unanswered' and pkt_out.outpacket.Command == commands.Identity():
            if pkt_out.outpacket.OwnerID == my_id.getIDURL() and pkt_out.outpacket.CreatorID == my_id.getIDURL():
                # if not handshaker.is_running(pkt_out.outpacket.RemoteID):
                if _Debug:
                    lg.dbg(_DebugLevel, 'ping packet %s addressed to %r was "unanswered"' % (pkt_out, pkt_out.outpacket.RemoteID, ))
    else:
        if _Debug:
            lg.dbg(_DebugLevel, 'packet %s is "%s" with %s error: %r' % (pkt_out, status, pkt_out.outpacket, error))
    if pkt_out.outpacket.Command == commands.Identity():
        if pkt_out.outpacket.OwnerID == my_id.getIDURL() and pkt_out.outpacket.CreatorID == my_id.getIDURL():
            if handshaker.is_running(pkt_out.outpacket.RemoteID):
                handshaker.on_identity_packet_outbox_status(pkt_out, status, error)
    return False
예제 #3
0
 def _on_inbox_packet_received(self, newpacket, info, status,
                               error_message):
     if newpacket.Command == commands.Identity() and \
             newpacket.CreatorID == self.router_idurl and \
             newpacket.RemoteID == my_id.getLocalID():
         self.automat('router-id-received', (newpacket, info))
         self.latest_packet_received = time.time()
         return True
     if newpacket.CreatorID == self.router_idurl:
         self.latest_packet_received = time.time()
     if newpacket.Command in [
             commands.Relay(),
             commands.RelayIn(),
             commands.RelayAck(),
             commands.RelayFail(),
     ]:
         if driver.is_enabled('service_proxy_server'):
             # TODO:
             # in case this node already running proxy router service this will not work
             # actually you can not use proxy transport for receiving and running proxy router at same time
             # need to change one of the services to solve that dependency and prevent this
             return False
         self.automat('inbox-packet',
                      (newpacket, info, status, error_message))
         return True
     return False
예제 #4
0
def OutboxStatus(pkt_out, status, error=''):
    """
    This method is called when raised a status report after sending a packet to
    remote peer.

    If packet sending was failed - user seems to be OFFLINE.
    """
    global _ShutdownFlag
    if _ShutdownFlag:
        return False
    if pkt_out.outpacket.RemoteID == my_id.getLocalID():
        return False
    if pkt_out.outpacket.CreatorID != my_id.getLocalID():
        return False
    if status == 'finished':
        if error == 'unanswered' and pkt_out.outpacket.Command == commands.Identity():
            A(pkt_out.outpacket.RemoteID, 'ping-failed', (pkt_out, status, error))
        else:
            A(pkt_out.outpacket.RemoteID, 'sent-done', (pkt_out, status, error))
    else:
        if _Debug:
            lg.out(_DebugLevel, 'contact_status.OutboxStatus %s: [%s] with %s' % (status, pkt_out, pkt_out.outpacket))
        if status == 'cancelled':
            if _Debug:
                lg.out(_DebugLevel, '    skipped')
        else:
            # lg.warn('sending event "sent-failed" to contact status of : %s' % pkt_out.remote_idurl)
            A(pkt_out.outpacket.RemoteID, 'sent-failed', (pkt_out, status, error))
    return False
예제 #5
0
def SendToID(idurl, ack_handler=None, Payload=None, NeedAck=False, wide=False):
    """
    Create ``packet`` with my Identity file and calls
    ``transport.gateway.outbox()`` to send it.
    """
    lg.out(
        8, "propagate.SendToID [%s] wide=%s" %
        (nameurl.GetName(idurl), str(wide)))
    if ack_handler is None:
        ack_handler = HandleAck
    thePayload = Payload
    if thePayload is None:
        thePayload = my_id.getLocalIdentity().serialize()
    p = signed.Packet(
        commands.Identity(),
        my_id.getLocalID(),  # MyID,
        my_id.getLocalID(),  # MyID,
        'Identity',  # my_id.getLocalID(), #PacketID,
        thePayload,
        idurl)
    # callback.register_interest(AckHandler, p.RemoteID, p.PacketID)
    gateway.outbox(p,
                   wide,
                   callbacks={
                       commands.Ack(): ack_handler,
                       commands.Fail(): ack_handler,
                   })
    if wide:
        # this is a ping packet - need to clear old info
        stats.ErasePeerProtosStates(idurl)
        stats.EraseMyProtosStates(idurl)
예제 #6
0
def SendIdentity(remote_idurl, wide=False, timeout=10, callbacks={}):
    """
    """
    packet_id = 'identity:%s' % packetid.UniqueID()
    if _Debug:
        lg.out(
            _DebugLevel,
            "p2p_service.SendIdentity to %s wide=%s packet_id=%r" % (
                nameurl.GetName(remote_idurl),
                wide,
                packet_id,
            ))
    result = signed.Packet(
        Command=commands.Identity(),
        OwnerID=my_id.getLocalID(),
        CreatorID=my_id.getLocalID(),
        PacketID=packet_id,
        Payload=my_id.getLocalIdentity().serialize(),
        RemoteID=remote_idurl,
    )
    gateway.outbox(result,
                   wide=wide,
                   callbacks=callbacks,
                   response_timeout=timeout)
    return result
예제 #7
0
 def isPingPacket(self, *args, **kwargs):
     """
     Condition method.
     """
     pkt_out = args[0]
     return pkt_out.outpacket and pkt_out.outpacket.Command == commands.Identity(
     ) and pkt_out.wide is True
예제 #8
0
 def _do_send_identity_to_router(self, identity_source, failed_event):
     try:
         identity_obj = identity.identity(xmlsrc=identity_source)
     except:
         lg.exc()
         return
     if _Debug:
         lg.out(_DebugLevel, 'proxy_receiver._do_send_identity_to_router to %s' % self.router_idurl)
         lg.out(_DebugLevel, '        contacts=%r, sources=%r' % (
             identity_obj.contacts, identity_obj.getSources(as_originals=True)))
     newpacket = signed.Packet(
         Command=commands.Identity(),
         OwnerID=my_id.getIDURL(),
         CreatorID=my_id.getIDURL(),
         PacketID=('proxy_receiver:%s' % packetid.UniqueID()),
         Payload=identity_obj.serialize(),
         RemoteID=self.router_idurl,
     )
     packet_out.create(
         newpacket,
         wide=True,
         callbacks={
             commands.Ack(): lambda response, info: self.automat('ack-received', (response, info)),
             commands.Fail(): lambda x: self.automat(failed_event),
             None: lambda pkt_out: self.automat('ack-timeout', pkt_out),
             'failed': lambda pkt_out, error_message: self.automat('sending-failed', (pkt_out, error_message)),
         },
         keep_alive=True,
         response_timeout=30,
     )
예제 #9
0
def handle(newpacket, info):
    from transport import packet_out
    handled = False
    # check that signed by a contact of ours
    if not newpacket.Valid():
        lg.warn('new packet from %s://%s is NOT VALID: %r' % (
            info.proto, info.host, newpacket))
        return None
    for p in packet_out.search_by_response_packet(newpacket, info.proto, info.host):
        p.automat('inbox-packet', (newpacket, info))
        handled = True
        if _Debug:
            lg.out(_DebugLevel, '    processed by %s as response packet' % p)
    handled = callback.run_inbox_callbacks(newpacket, info, info.status, info.error_message) or handled
    if not handled and newpacket.Command not in [commands.Ack(), commands.Fail(), commands.Identity(), ]:
        lg.warn('incoming %s from [%s://%s] was NOT HANDLED' % (newpacket, info.proto, info.host))
    if _Debug:
        history().append({
            'time': newpacket.Date,
            'command': newpacket.Command,
            'packet_id': newpacket.PacketID,
            'creator_id': newpacket.CreatorID,
            'owner_id': newpacket.OwnerID,
            'remote_id': newpacket.RemoteID,
            'payload': len(newpacket.Payload),
            'address': '%s://%s' % (info.proto, info.host),
        })
        if len(history()) > 100:
            history().pop(0)
    return handled
예제 #10
0
    def _on_inbox_packet_received(self, newpacket, info, status,
                                  error_message):
        if newpacket.Command == commands.Identity() and \
                newpacket.CreatorID == self.router_idurl and \
                newpacket.RemoteID == my_id.getLocalID():
            self.automat('router-id-received', (newpacket, info))
            self.latest_packet_received = time.time()
            return True
        if newpacket.Command == commands.Fail() and \
                newpacket.CreatorID == self.router_idurl and \
                newpacket.RemoteID == my_id.getLocalID():
            self.automat('service-refused', (newpacket, info))
            return True
        if newpacket.CreatorID == self.router_idurl:
            self.latest_packet_received = time.time()
        if newpacket.Command != commands.Relay():
            return False
        # if not newpacket.PacketID.startswith('routed_in_'):
        # return False
#         if newpacket.RemoteID != my_id.getLocalID():
#             return False
#         if newpacket.CreatorID != self.router_idurl:
#             return False
        self.automat('inbox-packet', (newpacket, info, status, error_message))
        return True
예제 #11
0
def SendToID(idurl, Payload=None, wide=False, ack_handler=None, timeout_handler=None, response_timeout=20, ):
    """
    Create ``packet`` with my Identity file and calls
    ``transport.gateway.outbox()`` to send it.
    """
    global _PropagateCounter
    if _Debug:
        lg.out(_DebugLevel, "propagate.SendToID [%s] wide=%s" % (nameurl.GetName(idurl), str(wide)))
    if ack_handler is None:
        ack_handler = HandleAck
    if timeout_handler is None:
        timeout_handler = HandleTimeOut
    thePayload = Payload
    if thePayload is None:
        thePayload = strng.to_bin(my_id.getLocalIdentity().serialize())
    p = signed.Packet(
        Command=commands.Identity(),
        OwnerID=my_id.getIDURL(),
        CreatorID=my_id.getIDURL(),
        PacketID=('propagate:%d:%s' % (_PropagateCounter, packetid.UniqueID())),
        Payload=thePayload,
        RemoteID=idurl,
    )
    _PropagateCounter += 1
    result = gateway.outbox(p, wide, response_timeout=response_timeout, callbacks={
        commands.Ack(): ack_handler,
        commands.Fail(): ack_handler,
        None: timeout_handler,
    })
    if wide:
        # this is a ping packet - need to clear old info
        p2p_stats.ErasePeerProtosStates(idurl)
        p2p_stats.EraseMyProtosStates(idurl)
    return result
예제 #12
0
def SendToIDs(idlist, wide=False, ack_handler=None, timeout_handler=None, response_timeout=20):
    """
    Same, but send to many IDs and also check previous packets to not re-send.
    """
    global _PropagateCounter
    if _Debug:
        lg.out(_DebugLevel, "propagate.SendToIDs to %d users, wide=%s" % (len(idlist), wide))
    if ack_handler is None:
        ack_handler = HandleAck
    if timeout_handler is None:
        timeout_handler = HandleTimeOut
    LocalIdentity = my_id.getLocalIdentity()
    Payload = strng.to_bin(LocalIdentity.serialize())
    alreadysent = set()
    totalsent = 0
    inqueue = {}
    found_previous_packets = 0
    for pkt_out in packet_out.queue():
        if id_url.is_in(pkt_out.remote_idurl, idlist, as_field=False):
            if pkt_out.description.count('Identity'):
                if pkt_out.remote_idurl not in inqueue:
                    inqueue[pkt_out.remote_idurl] = 0
                inqueue[pkt_out.remote_idurl] += 1
                found_previous_packets += 1
    for contact in idlist:
        if not contact:
            continue
        if contact in alreadysent:
            # just want to send once even if both customer and supplier
            continue
        if contact in inqueue and inqueue[contact] > 2:
            # now only 2 protocols is working: tcp and udp
            if _Debug:
                lg.out(_DebugLevel, '        skip sending [Identity] to %s, packet already in the queue' % contact)
            continue
        p = signed.Packet(
            Command=commands.Identity(),
            OwnerID=my_id.getLocalID(),
            CreatorID=my_id.getLocalID(),
            PacketID=('propagate:%d:%s' % (_PropagateCounter, packetid.UniqueID())),
            Payload=Payload,
            RemoteID=contact,
        )
        _PropagateCounter += 1
        if _Debug:
            lg.out(_DebugLevel, "        sending [Identity] to %s" % nameurl.GetName(contact))
        gateway.outbox(p, wide, response_timeout=response_timeout, callbacks={
            commands.Ack(): ack_handler,
            commands.Fail(): ack_handler,
            None: timeout_handler,
        })
        if wide:
            # this is a ping packet - need to clear old info
            p2p_stats.ErasePeerProtosStates(contact)
            p2p_stats.EraseMyProtosStates(contact)
        alreadysent.add(contact)
        totalsent += 1
    del alreadysent
    return totalsent
예제 #13
0
def process(newpacket, info):
    from p2p import p2p_service
    from userid import my_id
    if not driver.is_on('service_p2p_hookups'):
        if _Debug:
            lg.out(
                _DebugLevel,
                'packet_in.process SKIP incoming packet, service_p2p_hookups is not started'
            )
        return None
    if _Debug:
        lg.out(
            _DebugLevel,
            'packet_in.process [%s/%s/%s]:%s(%s) from %s://%s is "%s"' % (
                nameurl.GetName(newpacket.OwnerID),
                nameurl.GetName(newpacket.CreatorID),
                nameurl.GetName(newpacket.RemoteID),
                newpacket.Command,
                newpacket.PacketID,
                info.proto,
                info.host,
                info.status,
            ))
    if info.status != 'finished':
        if _Debug:
            lg.out(_DebugLevel,
                   '    skip, packet status is : [%s]' % info.status)
        return None
    if newpacket.Command == commands.Identity():
        if newpacket.RemoteID != my_id.getLocalIDURL():
            if _Debug:
                lg.out(_DebugLevel,
                       '    incoming Identity is routed to another user')
            if not p2p_service.Identity(newpacket, send_ack=False):
                lg.warn('non-valid identity received')
                return None
            # remote peer sending a valid identity to another peer routed via my machine
            # need to handle that packet - it should be processed by proxy_server
            return handle(newpacket, info)
        # contact sending us current identity we might not have
        # so we handle it before check that packet is valid
        # because we might not have his identity on hands and so can not verify the packet
        # so we check that his Identity is valid and save it into cache
        # than we check the packet to be valid too.
        if not p2p_service.Identity(newpacket):
            lg.warn('non-valid identity received')
            return None
    if not identitycache.HasKey(newpacket.CreatorID):
        if _Debug:
            lg.out(
                _DebugLevel,
                '    will cache remote identity %s before processing incoming packet %s'
                % (newpacket.CreatorID, newpacket))
        d = identitycache.immediatelyCaching(newpacket.CreatorID)
        d.addCallback(lambda _: handle(newpacket, info))
        d.addErrback(lambda err: lg.err('failed caching remote %s identity: %s'
                                        % (newpacket.CreatorID, str(err))))
        return d
    return handle(newpacket, info)
예제 #14
0
 def _outbox_packet_sent(self, pkt_out):
     from p2p import commands
     from contacts import contactsdb
     from supplier import customer_assistant
     if pkt_out.outpacket.Command == commands.Identity():
         if contactsdb.is_customer(pkt_out.outpacket.RemoteID):
             ca = customer_assistant.by_idurl(pkt_out.outpacket.RemoteID)
             if ca:
                 ca.automat('propagate', pkt_out)
예제 #15
0
def SendToID(
    idurl,
    Payload=None,
    wide=False,
    ack_handler=None,
    timeout_handler=None,
    response_timeout=20,
):
    """
    Create ``packet`` with my Identity file and calls
    ``transport.gateway.outbox()`` to send it.
    """
    lg.out(
        8, "propagate.SendToID [%s] wide=%s" %
        (nameurl.GetName(idurl), str(wide)))
    if ack_handler is None:
        ack_handler = HandleAck
    if timeout_handler is None:
        timeout_handler = HandleTimeOut
    thePayload = Payload
    if thePayload is None:
        thePayload = strng.to_bin(my_id.getLocalIdentity().serialize())
    p = signed.Packet(
        commands.Identity(),
        my_id.getLocalID(),  # MyID,
        my_id.getLocalID(),  # MyID,
        commands.Identity(),  #  'Identity',  # my_id.getLocalID(), #PacketID,
        thePayload,
        idurl,
    )
    # callback.register_interest(AckHandler, p.RemoteID, p.PacketID)
    result = gateway.outbox(p,
                            wide,
                            response_timeout=response_timeout,
                            callbacks={
                                commands.Ack(): ack_handler,
                                commands.Fail(): ack_handler,
                                None: timeout_handler,
                            })
    if wide:
        # this is a ping packet - need to clear old info
        p2p_stats.ErasePeerProtosStates(idurl)
        p2p_stats.EraseMyProtosStates(idurl)
    return result
예제 #16
0
def process(newpacket, info):
    if not driver.is_on('service_p2p_hookups'):
        if _Debug:
            lg.out(
                _DebugLevel,
                'packet_in.process SKIP incoming packet, service_p2p_hookups is not started'
            )
        return
    handled = False
    if _Debug:
        lg.out(
            _DebugLevel, 'packet_in.process %s from %s://%s : %s' %
            (str(newpacket), info.proto, info.host, info.status))
    from p2p import commands
    from p2p import p2p_service
    if newpacket.Command == commands.Identity(
    ) and newpacket.RemoteID == my_id.getLocalID():
        # contact sending us current identity we might not have
        # so we handle it before check that packet is valid
        # because we might not have his identity on hands and so can not verify the packet
        # so we check that his Identity is valid and save it into cache
        # than we check the packet to be valid too.
        if not p2p_service.Identity(newpacket):
            return
    # check that signed by a contact of ours
    if not newpacket.Valid():
        lg.warn('new packet from %s://%s is NOT VALID: %r' %
                (info.proto, info.host, newpacket))
        return
    for p in packet_out.search_by_response_packet(newpacket, info.proto,
                                                  info.host):
        p.automat('inbox-packet', (newpacket, info))
        handled = True
    handled = callback.run_inbox_callbacks(newpacket, info, info.status,
                                           info.error_message) or handled
    if not handled and newpacket.Command not in [
            commands.Ack(), commands.Fail()
    ]:
        if _Debug:
            lg.out(
                _DebugLevel - 8, '    incoming %s from [%s://%s]' %
                (newpacket, info.proto, info.host))
            lg.out(_DebugLevel - 8, '        NOT HANDLED !!!')
    if _Debug:
        history().append({
            'time': newpacket.Date,
            'command': newpacket.Command,
            'packet_id': newpacket.PacketID,
            'creator_id': newpacket.CreatorID,
            'owner_id': newpacket.OwnerID,
            'remote_id': newpacket.RemoteID,
            'payload': len(newpacket.Payload),
            'address': '%s://%s' % (info.proto, info.host),
        })
        if len(history()) > 100:
            history().pop(0)
예제 #17
0
def process(newpacket, info):
    """
    Main entry point where all incoming signed packets are coming from remote peers.
    The main aspect here is to "authenticate" remote node - need to know it identity.
    """
    from p2p import p2p_service
    from userid import my_id
    if not driver.is_on('service_p2p_hookups'):
        if _Debug:
            lg.out(_DebugLevel, 'packet_in.process SKIP incoming packet, service_p2p_hookups is not started')
        return None
    if _Debug:
        lg.out(_DebugLevel, 'packet_in.process [%s/%s/%s]:%s(%s) from %s://%s is "%s"' % (
            nameurl.GetName(newpacket.OwnerID), nameurl.GetName(newpacket.CreatorID), nameurl.GetName(newpacket.RemoteID),
            newpacket.Command, newpacket.PacketID, info.proto, info.host, info.status, ))
    if info.status != 'finished':
        if _Debug:
            lg.out(_DebugLevel, '    skip, packet status is : [%s]' % info.status)
        return None
#     if _PacketLogFileEnabled:
#         lg.out(0, '        \033[0;49;92mIN %s(%s) with %d bytes from %s to %s TID:%s\033[0m' % (
#             newpacket.Command, newpacket.PacketID, info.bytes_received,
#             global_id.UrlToGlobalID(info.sender_idurl), global_id.UrlToGlobalID(newpacket.RemoteID),
#             info.transfer_id), log_name='packet', showtime=True)
    # we must know recipient identity
    if not id_url.is_cached(newpacket.RemoteID):
        d = identitycache.immediatelyCaching(newpacket.RemoteID)
        d.addCallback(lambda _: process(newpacket, info))
        d.addErrback(lambda err: lg.err('incoming remote ID is unknown, failed caching remote %s identity: %s' % (newpacket.RemoteID, str(err))) and None)
        return d
    if newpacket.Command == commands.Identity():
        if newpacket.RemoteID != my_id.getIDURL():
            if _Debug:
                lg.out(_DebugLevel, '    incoming Identity is routed to another user')
            if not p2p_service.Identity(newpacket, send_ack=False):
                lg.warn('received identity was not processed')
                return None
            # remote peer sending a valid identity to another peer routed via my machine
            # need to handle that packet - it should be processed by proxy_server
            return handle(newpacket, info)
        # contact sending us current identity we might not have
        # so we handle it before check that packet is valid
        # because we might not have his identity on hands and so can not verify the packet
        # so we check that his Identity is valid and save it into cache
        # than we check the packet to be valid too.
        if not p2p_service.Identity(newpacket):
            lg.warn('received identity was not processed')
            return None
    if not identitycache.HasKey(newpacket.CreatorID):
        if _Debug:
            lg.out(_DebugLevel, '    will cache remote identity %s before processing incoming packet %s' % (newpacket.CreatorID, newpacket))
        d = identitycache.immediatelyCaching(newpacket.CreatorID)
        d.addCallback(lambda _: handle(newpacket, info))
        d.addErrback(lambda err: lg.err('failed caching remote %s identity: %s' % (newpacket.CreatorID, str(err))) and None)
        return d
    return handle(newpacket, info)
예제 #18
0
def SendIdentity(remote_idurl, wide=False, callbacks={}):
    """
    """
    if _Debug:
        lg.out(
            _DebugLevel,
            "p2p_service.SendIdentity to %s" % nameurl.GetName(remote_idurl))
    result = signed.Packet(commands.Identity(), my_id.getLocalID(),
                           my_id.getLocalID(), 'identity',
                           my_id.getLocalIdentity().serialize(), remote_idurl)
    gateway.outbox(result, wide=wide, callbacks=callbacks)
    return result
 def _on_outbox_packet_sent(self, pkt_out):
     from twisted.internet import reactor  # @UnresolvedImport
     from p2p import commands
     from contacts import contactsdb
     from supplier import customer_assistant
     if pkt_out.outpacket.Command == commands.Identity():
         if contactsdb.is_customer(pkt_out.outpacket.RemoteID):
             ca = customer_assistant.by_idurl(pkt_out.outpacket.RemoteID)
             if ca:
                 reactor.callLater(0, ca.automat, 'propagate',
                                   pkt_out)  # @UndefinedVariable
     return False
예제 #20
0
def search_by_response_packet(newpacket, proto=None, host=None):
    result = []
    incoming_owner_idurl = newpacket.OwnerID
    incoming_creator_idurl = newpacket.CreatorID
    incoming_remote_idurl = newpacket.RemoteID
    if _Debug:
        lg.out(_DebugLevel, 'packet_out.search_by_response_packet for incoming [%s/%s/%s]:%s(%s) from [%s://%s]' % (
            nameurl.GetName(incoming_owner_idurl), nameurl.GetName(incoming_creator_idurl), nameurl.GetName(incoming_remote_idurl),
            newpacket.Command, newpacket.PacketID, proto, host, ))
        lg.out(_DebugLevel, '    [%s]' % (','.join([str(p.outpacket) for p in queue()])))
    for p in queue():
        # TODO: investigate 
        if p.outpacket.PacketID.lower() != newpacket.PacketID.lower():
            # PacketID of incoming packet not matching with that outgoing packet
            continue
        if p.outpacket.PacketID != newpacket.PacketID:
            lg.warn('packet ID in queue "almost" matching with incoming: %s ~ %s' % (
                p.outpacket.PacketID, newpacket.PacketID, ))
        if not commands.IsCommandAck(p.outpacket.Command, newpacket.Command):
            # this command must not be in the reply
            continue
        expected_recipient = [p.outpacket.RemoteID, ]
        if p.outpacket.RemoteID != p.remote_idurl:
            # outgoing packet was addressed to another node, so that means we need to expect response from another node also
            expected_recipient.append(p.remote_idurl)
        matched = False
        if incoming_owner_idurl in expected_recipient and my_id.getLocalIDURL() == incoming_remote_idurl:
            if _Debug:
                lg.out(_DebugLevel, '    matched with incoming owner: %s' % expected_recipient)
            matched = True
        if incoming_creator_idurl in expected_recipient and my_id.getLocalIDURL() == incoming_remote_idurl:
            if _Debug:
                lg.out(_DebugLevel, '    matched with incoming creator: %s' % expected_recipient)
            matched = True
        if incoming_remote_idurl in expected_recipient and my_id.getLocalIDURL() == incoming_owner_idurl and commands.Data() == newpacket.Command:
            if _Debug:
                lg.out(_DebugLevel, '    matched my own incoming Data with incoming remote: %s' % expected_recipient)
            matched = True
        if matched:
            result.append(p)
            if _Debug:
                lg.out(_DebugLevel, '        found pending outbox [%s/%s/%s]:%s(%s) cb:%s' % (
                    nameurl.GetName(p.outpacket.OwnerID), nameurl.GetName(p.outpacket.CreatorID),
                    nameurl.GetName(p.outpacket.RemoteID), p.outpacket.Command, p.outpacket.PacketID,
                    list(p.callbacks.keys())))
    if len(result) == 0:
        if _Debug:
            lg.out(_DebugLevel, '        NOT FOUND pending packets in outbox queue matching incoming %s' % newpacket)
        if newpacket.Command == commands.Ack() and newpacket.PacketID not in [commands.Identity(), commands.Identity().lower()]:
            lg.warn('received %s was not a "good reply" from %s://%s' % (newpacket, proto, host, ))
    return result
예제 #21
0
 def doSendMyIdentity(self, *args, **kwargs):
     """
     Action method.
     """
     global _KnownChannels
     self.ping_attempts += 1
     if self.fake_identity:
         identity_object = self.fake_identity
     else:
         identity_object = my_id.getLocalIdentity()
     if not identity_object.Valid():
         raise Exception('can not use invalid identity for ping')
     if self.channel_counter:
         packet_id = '%s:%d:%d:%s' % (self.channel, _KnownChannels[self.channel], self.ping_attempts, packetid.UniqueID())
     else:
         packet_id = '%s:%d:%s' % (self.channel, self.ping_attempts, packetid.UniqueID())
     ping_packet = signed.Packet(
         Command=commands.Identity(),
         OwnerID=my_id.getIDURL(),
         CreatorID=my_id.getIDURL(),
         PacketID=packet_id,
         Payload=strng.to_bin(identity_object.serialize()),
         RemoteID=self.remote_idurl,
     )
     if self.skip_outbox:
         packet_out.create(
             outpacket=ping_packet,
             wide=True,
             response_timeout=self.ack_timeout,
             callbacks={
                 commands.Ack(): lambda response, info: self.automat('ack-received', response=response, info=info),
                 commands.Fail(): lambda response, info: self.automat('fail-received', response=response, info=info),
                 None: lambda pkt_out: self.automat('ack-timeout', pkt_out),
             },
             keep_alive=self.keep_alive,
         )
     else:
         gateway.outbox(
             outpacket=ping_packet,
             wide=True,
             response_timeout=self.ack_timeout,
             callbacks={
                 commands.Ack(): lambda response, info: self.automat('ack-received', response=response, info=info),
                 commands.Fail(): lambda response, info: self.automat('fail-received', response=response, info=info),
                 None: lambda pkt_out: self.automat('ack-timeout', pkt_out),
             },
             keep_alive=self.keep_alive,
         )
     if _Debug:
         lg.args(_DebugLevel, packet_id=packet_id, remote_idurl=self.remote_idurl, ping_attempts=self.ping_attempts)
예제 #22
0
 def doProcessInboxPacket(self, arg):
     """
     Action method.
     """
     newpacket, info, _, _ = arg
     block = encrypted.Unserialize(newpacket.Payload)
     if block is None:
         lg.out(2, 'proxy_receiver.doProcessInboxPacket ERROR reading data from %s' % newpacket.CreatorID)
         return
     try:
         session_key = key.DecryptLocalPrivateKey(block.EncryptedSessionKey)
         padded_data = key.DecryptWithSessionKey(session_key, block.EncryptedData)
         inpt = cStringIO.StringIO(padded_data[:int(block.Length)])
         data = inpt.read()
     except:
         lg.out(2, 'proxy_receiver.doProcessInboxPacket ERROR reading data from %s' % newpacket.CreatorID)
         lg.exc()
         try:
             inpt.close()
         except:
             pass
         return
     inpt.close()
     routed_packet = signed.Unserialize(data)
     if not routed_packet:
         lg.out(2, 'proxy_receiver.doProcessInboxPacket ERROR unserialize packet failed from %s' % newpacket.CreatorID)
         return
     if routed_packet.Command == commands.Identity():
         newidentity = identity.identity(xmlsrc=routed_packet.Payload)
         idurl = newidentity.getIDURL()
         if not identitycache.HasKey(idurl):
             lg.warn('received new identity: %s' % idurl)
         if not identitycache.UpdateAfterChecking(idurl, routed_packet.Payload):
             lg.warn("ERROR has non-Valid identity")
             return
     if not routed_packet.Valid():
         lg.out(2, 'proxy_receiver.doProcessInboxPacket ERROR invalid packet from %s' % newpacket.CreatorID)
         return
     self.traffic_in += len(data)
     if _Debug:
         lg.out(_DebugLevel, '<<<Relay-IN %s from %s://%s with %d bytes' % (
             str(routed_packet), info.proto, info.host, len(data)))
     packet_in.process(routed_packet, info)
     del block
     del data
     del padded_data
     del inpt
     del session_key
     del routed_packet
예제 #23
0
 def _on_inbox_packet_received(self, newpacket, info, status, error_message):
     if newpacket.Command == commands.Identity() and \
             newpacket.CreatorID == self.router_idurl and \
             newpacket.RemoteID == my_id.getLocalID():
         self.automat('router-id-received', (newpacket, info))
         self.latest_packet_received = time.time()
         return True
     # TODO: if this is a response from supplier - this must be skipped here
     # if newpacket.Command == commands.Fail() and \
     #         newpacket.CreatorID == self.router_idurl and \
     #         newpacket.RemoteID == my_id.getLocalID():
     #     self.automat('service-refused', (newpacket, info))
     #     return True
     if newpacket.CreatorID == self.router_idurl:
         self.latest_packet_received = time.time()
     if newpacket.Command == commands.Relay():
         self.automat('inbox-packet', (newpacket, info, status, error_message))
         return True
     return False
예제 #24
0
 def _on_inbox_packet_received(self, newpacket, info, status,
                               error_message):
     if _Debug:
         lg.out(
             _DebugLevel,
             'proxy_router._on_inbox_packet_received %s from %s for %s' %
             (newpacket, newpacket.CreatorID, newpacket.RemoteID))
     if newpacket.RemoteID == my_id.getLocalID():
         # this packet was addressed directly to me ...
         if newpacket.Command == commands.Relay():
             # but this is a routed packet addressed to someone else
             if newpacket.CreatorID in self.routes.keys():
                 # sent by proxy_sender() from node A : a man behind proxy_router()
                 # addressed to some third node B in outside world - need to route
                 self.automat('routed-outbox-packet-received',
                              (newpacket, info))
                 return True
             lg.warn(
                 'packet %s from %s SKIPPED, because no routes with %s' %
                 (newpacket, newpacket.CreatorID, newpacket.CreatorID))
             return False
         # and this is not a Relay packet
         if newpacket.Command == commands.Identity(
         ) and newpacket.CreatorID == newpacket.OwnerID:
             if newpacket.CreatorID in self.routes.keys():
                 # this is a "propagate" packet from node A addressed to this proxy
                 # mark that packet as handled and send Ack
                 # otherwise it will be wrongly handled in p2p_service
                 self.automat('known-identity-received', newpacket)
                 return True
             else:
                 # this node is not yet in routers list,
                 # but seems like it tries to contact me
                 # mark this packet as handled and try to process it
                 self.automat('unknown-identity-received', newpacket)
                 return True
         # so this packet may be of any kind, but addressed to me
         # for example if I am a supplier for node A he will send me packets in usual way
         # need to skip this packet here and process it as a normal inbox packet
         if _Debug:
             lg.out(
                 _DebugLevel,
                 'proxy_router._on_inbox_packet_received %s from %s SKIPEED, addressed to me'
                 % (newpacket, newpacket.CreatorID))
         return False
     # this packet was addressed to someone else
     receiver_idurl = None
     if newpacket.Command == commands.Data():
         # Data packets may have two cases: a new Data or response with existing Data
         if info.sender_idurl == newpacket.CreatorID:
             # incoming new Data created by node B addressed to node A
             if newpacket.RemoteID in self.routes.keys():
                 receiver_idurl = newpacket.RemoteID
         elif info.sender_idurl == newpacket.RemoteID:
             # response from node B addressed to node A, by request from A who own this Data
             if newpacket.CreatorID in self.routes.keys():
                 # a Data packet sent by node B : a man from outside world
                 # addressed to a man behind this proxy_router() - need to route to node A
                 receiver_idurl = newpacket.CreatorID
         else:
             # some wired packet received
             lg.warn('unidentified Data packet received: %s from %s' %
                     (newpacket, info.sender_idurl))
             return False
     else:
         # other packets (not Data) always should be routed to node A by RemoteID
         if newpacket.RemoteID in self.routes.keys():
             # sent by node B : a man from outside world
             # addressed to a man behind this proxy - need to route to node A
             receiver_idurl = newpacket.RemoteID
     if receiver_idurl is not None:
         self.automat('routed-inbox-packet-received',
                      (receiver_idurl, newpacket, info))
         return True
     if _Debug:
         lg.out(
             _DebugLevel,
             'proxy_router._on_inbox_packet_received SKIPPED %s' %
             newpacket)
     return False
예제 #25
0
    def _on_inbox_packet_received(self, newpacket, info, status,
                                  error_message):
        if _Debug:
            lg.out(
                _DebugLevel,
                'proxy_router._on_inbox_packet_received %s from %s://%s' % (
                    newpacket,
                    info.proto,
                    info.host,
                ))
            lg.out(
                _DebugLevel, '    creator=%s owner=%s' % (
                    newpacket.CreatorID,
                    newpacket.OwnerID,
                ))
            lg.out(
                _DebugLevel, '    sender=%s remote_id=%s' % (
                    info.sender_idurl,
                    newpacket.RemoteID,
                ))
            for k, v in self.routes.items():
                lg.out(
                    _DebugLevel,
                    '        route with %s :  address=%s  contacts=%s' % (
                        k,
                        v.get('address'),
                        v.get('contacts'),
                    ))
        # first filter all traffic addressed to me
        if newpacket.RemoteID == my_id.getLocalID():
            # check command type, filter Routed traffic first
            if newpacket.Command == commands.Relay():
                # look like this is a routed packet addressed to someone else
                if newpacket.CreatorID in list(self.routes.keys()):
                    # sent by proxy_sender() from node A : a man behind proxy_router()
                    # addressed to some third node B in outside world - need to route
                    # A is my consumer and B is a recipient which A wants to contant
                    if _Debug:
                        lg.out(
                            _DebugLevel,
                            '        sending "routed-outbox-packet-received" event'
                        )
                    self.automat('routed-outbox-packet-received',
                                 (newpacket, info))
                    return True
                # looke like we do not know this guy, so why he is sending us routed traffic?
                lg.warn(
                    'unknown %s from %s received, no known routes with %s' %
                    (newpacket, newpacket.CreatorID, newpacket.CreatorID))
                self.automat('unknown-packet-received', (newpacket, info))
                return True
            # and this is not a Relay packet, Identity
            elif newpacket.Command == commands.Identity():
                # this is a "propagate" packet from node A addressed to this proxy router
                if newpacket.CreatorID in list(self.routes.keys()):
                    # also we need to "reset" overriden identity
                    # return False so that other services also can process that Identity()
                    if _Debug:
                        lg.out(
                            _DebugLevel,
                            '        sending "known-identity-received" event')
                    self.automat('known-identity-received', newpacket)
                    return False
                # this node is not yet in routers list,
                # but seems like it tries to contact me
                # return False so that other services also can process that Identity()
                if _Debug:
                    lg.out(
                        _DebugLevel,
                        '        sending "unknown-identity-received" event')
                self.automat('unknown-identity-received', newpacket)
                return False
            # it can be a RequestService or CancelService packets...
#             elif newpacket.Command == commands.RequestService():
#                 self.automat(event_string, *args, **kwargs)
#                 'request-route-received'....
# so this packet may be of any kind, but addressed to me
# for example if I am a supplier for node A he will send me packets in usual way
# need to skip this packet here and process it as a normal inbox packet
            if _Debug:
                lg.out(
                    _DebugLevel,
                    '        proxy_router() SKIP packet %s from %s addressed to me'
                    % (newpacket, newpacket.CreatorID))
            return False
        # this packet was addressed to someone else
        # it can be different scenarios, if can not found valid scenario - must skip the packet
        receiver_idurl = None
        known_remote_id = newpacket.RemoteID in list(self.routes.keys())
        known_creator_id = newpacket.CreatorID in list(self.routes.keys())
        known_owner_id = newpacket.OwnerID in list(self.routes.keys())
        if known_remote_id:
            # incoming packet from node B addressed to node A behind that proxy, capture it!
            receiver_idurl = newpacket.RemoteID
            if _Debug:
                lg.out(
                    _DebugLevel,
                    '        proxy_router() ROUTED packet %s from %s to %s' %
                    (newpacket, info.sender_idurl, receiver_idurl))
            self.automat('routed-inbox-packet-received',
                         (receiver_idurl, newpacket, info))
            return True
        # uknown RemoteID...
        # Data() packets may have two cases: a new Data or response with existing Data
        # in that case RemoteID of the Data packet is not pointing to the real recipient
        # need to filter this scenario here and do workaround
        if known_creator_id or known_owner_id:
            # response from node B addressed to node A, after Retrieve() from A who owns this Data()
            # a Data packet sent by node B : a man from outside world
            # addressed to a man behind this proxy_router() - need to route to node A
            # but who is node A? Creator or Owner?
            based_on = ''
            if known_creator_id:
                receiver_idurl = newpacket.CreatorID
                based_on = 'creator'
            else:
                receiver_idurl = newpacket.OwnerID
                based_on = 'owner'
            if _Debug:
                lg.out(
                    _DebugLevel,
                    '        proxy_router() based on %s ROUTED packet %s from %s to %s'
                    % (based_on, newpacket, info.sender_idurl, receiver_idurl))
            self.automat('routed-inbox-packet-received',
                         (receiver_idurl, newpacket, info))
            return True
        # this packet is not related to any of the routes
        if _Debug:
            lg.out(
                _DebugLevel,
                '        proxy_router() SKIP packet %s from %s : no relations found'
                % (newpacket, newpacket.CreatorID))
        return False
예제 #26
0
def handle(newpacket, info):
    """
    Actually process incoming packet. Here we can be sure that owner/creator of the packet is identified.
    """
    from transport import packet_out
    handled = False
    # check that signed by a contact of ours
    try:
        is_signature_valid = newpacket.Valid(raise_signature_invalid=False)
    except:
        is_signature_valid = False
        # lg.exc('new packet from %s://%s is NOT VALID:\n\n%r\n' % (
        #     info.proto, info.host, newpacket.Serialize()))
    if not is_signature_valid:
        if _Debug:
            lg.args(
                _DebugLevel,
                PacketID=newpacket.PacketID,
                OwnerID=newpacket.OwnerID,
                CreatorID=newpacket.CreatorID,
                RemoteID=newpacket.RemoteID,
            )
        lg.warn('signature is not valid for %r from %r|%r to %r' %
                (newpacket, newpacket.OwnerID, newpacket.CreatorID,
                 newpacket.RemoteID))
        return None
    try:
        for p in packet_out.search_by_response_packet(newpacket, info.proto,
                                                      info.host):
            p.automat('inbox-packet', (newpacket, info))
            handled = True
            if _Debug:
                lg.out(_DebugLevel,
                       '    processed by %s as response packet' % p)
    except:
        lg.exc()
    try:
        handled = callback.run_inbox_callbacks(newpacket, info, info.status,
                                               info.error_message) or handled
    except:
        lg.exc()
    if not handled and newpacket.Command not in [
            commands.Ack(),
            commands.Fail(),
            commands.Identity(),
    ]:
        lg.warn('incoming %s from [%s://%s] was NOT HANDLED' %
                (newpacket, info.proto, info.host))
        if _PacketLogFileEnabled:
            lg.out(
                0,
                '                \033[1;49;91mIN NOT HANDLED %s(%s) with %d bytes from %s to %s TID:%s\033[0m'
                % (newpacket.Command, newpacket.PacketID, info.bytes_received,
                   global_id.UrlToGlobalID(info.sender_idurl),
                   global_id.UrlToGlobalID(
                       newpacket.RemoteID), info.transfer_id),
                log_name='packet',
                showtime=True)
    else:
        if _PacketLogFileEnabled:
            lg.out(
                0,
                '                \033[0;49;32mIN OK %s(%s) with %d bytes from %s to %s TID:%s\033[0m'
                % (newpacket.Command, newpacket.PacketID, info.bytes_received,
                   global_id.UrlToGlobalID(info.sender_idurl),
                   global_id.UrlToGlobalID(
                       newpacket.RemoteID), info.transfer_id),
                log_name='packet',
                showtime=True)
    if _Debug and False:
        history().append({
            'time': newpacket.Date,
            'command': newpacket.Command,
            'packet_id': newpacket.PacketID,
            'creator_id': newpacket.CreatorID,
            'owner_id': newpacket.OwnerID,
            'remote_id': newpacket.RemoteID,
            'payload': len(newpacket.Payload),
            'address': '%s://%s' % (info.proto, info.host),
        })
        if len(history()) > 100:
            history().pop(0)
    return handled
예제 #27
0
    def _do_process_inbox_packet(self, *args, **kwargs):
        newpacket, info, _, _ = args[0]
        block = encrypted.Unserialize(newpacket.Payload)
        if block is None:
            lg.err('reading data from %s' % newpacket.CreatorID)
            return
        try:
            session_key = key.DecryptLocalPrivateKey(block.EncryptedSessionKey)
            padded_data = key.DecryptWithSessionKey(session_key, block.EncryptedData, session_key_type=block.SessionKeyType)
            inpt = BytesIO(padded_data[:int(block.Length)])
            data = inpt.read()
        except:
            lg.err('reading data from %s' % newpacket.CreatorID)
            lg.exc()
            try:
                inpt.close()
            except:
                pass
            return
        inpt.close()

        if newpacket.Command == commands.RelayAck():
            try:
                ack_info = serialization.BytesToDict(data, keys_to_text=True, values_to_text=True)
            except:
                lg.exc()
                return
            if _Debug:
                lg.out(_DebugLevel, '<<<Relay-ACK %s:%s from %s://%s with %d bytes %s' % (
                    ack_info['command'], ack_info['packet_id'], info.proto, info.host, len(data), ack_info['error'], ))
            if _PacketLogFileEnabled:
                lg.out(0, '                \033[0;49;33mRELAY ACK %s(%s) with %d bytes from %s to %s TID:%s\033[0m' % (
                    ack_info['command'], ack_info['packet_id'], info.bytes_received,
                    global_id.UrlToGlobalID(ack_info['from']), global_id.UrlToGlobalID(ack_info['to']),
                    info.transfer_id), log_name='packet', showtime=True)
            from transport.proxy import proxy_sender
            if proxy_sender.A():
                proxy_sender.A('relay-ack', ack_info, info)
            return True

        if newpacket.Command == commands.RelayFail():
            try:
                fail_info = serialization.BytesToDict(data, keys_to_text=True, values_to_text=True)
            except:
                lg.exc()
                return
            if _Debug:
                lg.out(_DebugLevel, '<<<Relay-FAIL %s:%s from %s://%s with %d bytes %s' % (
                    fail_info['command'], fail_info['packet_id'], info.proto, info.host, len(data), fail_info['error'], ))
            if _PacketLogFileEnabled:
                lg.out(0, '                \033[0;49;33mRELAY FAIL %s(%s) with %d bytes from %s to %s TID:%s\033[0m' % (
                    fail_info['command'], fail_info['packet_id'], info.bytes_received,
                    global_id.UrlToGlobalID(fail_info['from']), global_id.UrlToGlobalID(fail_info['to']),
                    info.transfer_id), log_name='packet', showtime=True)
            from transport.proxy import proxy_sender
            if proxy_sender.A():
                proxy_sender.A('relay-failed', fail_info, info)
            return True

        routed_packet = signed.Unserialize(data)
        if not routed_packet:
            lg.err('unserialize packet failed from %s' % newpacket.CreatorID)
            return

        if _Debug:
            lg.out(_DebugLevel, '<<<Relay-IN %s from %s://%s with %d bytes' % (
                str(routed_packet), info.proto, info.host, len(data)))
        if _PacketLogFileEnabled:
            lg.out(0, '                \033[0;49;33mRELAY IN %s(%s) with %d bytes from %s to %s TID:%s\033[0m' % (
                routed_packet.Command, routed_packet.PacketID, info.bytes_received,
                global_id.UrlToGlobalID(info.sender_idurl), global_id.UrlToGlobalID(routed_packet.RemoteID),
                info.transfer_id), log_name='packet', showtime=True)

        if routed_packet.Command == commands.Identity():
            if _Debug:
                lg.out(_DebugLevel, '    found identity in relay packet %s' % routed_packet)
            newidentity = identity.identity(xmlsrc=routed_packet.Payload)
            idurl = newidentity.getIDURL()
            if not identitycache.HasKey(idurl):
                lg.info('received new identity %s rev %r' % (idurl.original(), newidentity.getRevisionValue(), ))
            if not identitycache.UpdateAfterChecking(idurl, routed_packet.Payload):
                lg.warn("ERROR has non-Valid identity")
                return

        if routed_packet.Command in [commands.Relay(), commands.RelayIn(), ] and routed_packet.PacketID.lower().startswith('identity:'):
            if _Debug:
                lg.out(_DebugLevel, '    found routed identity in relay packet %s' % routed_packet)
            try:
                routed_identity = signed.Unserialize(routed_packet.Payload)
                newidentity = identity.identity(xmlsrc=routed_identity.Payload)
                idurl = newidentity.getIDURL()
                if not identitycache.HasKey(idurl):
                    lg.warn('received new "routed" identity: %s' % idurl)
                if not identitycache.UpdateAfterChecking(idurl, routed_identity.Payload):
                    lg.warn("ERROR has non-Valid identity")
                    return
            except:
                lg.exc()

        if newpacket.Command == commands.RelayIn() and routed_packet.Command == commands.Fail():
            if routed_packet.Payload == b'route not exist' or routed_packet.Payload == b'route already closed':
                for pout in packet_out.search_by_packet_id(routed_packet.PacketID):
                    lg.warn('received %r from %r, outgoing packet is failed: %r' % (routed_packet.Payload, newpacket.CreatorID, pout, ))
                    pout.automat('request-failed')
                return

        self.traffic_in += len(data)
        packet_in.process(routed_packet, info)
        del block
        del data
        del padded_data
        del inpt
        del session_key
        del routed_packet
예제 #28
0
 def _on_first_outbox_packet(self,
                             outpacket,
                             wide,
                             callbacks,
                             target=None,
                             route=None,
                             response_timeout=None,
                             keep_alive=True):
     """
     Will be called first for every outgoing packet.
     Must return `None` if that packet should be sent in a normal way.
     Otherwise will create another "routed" packet instead and return it.
     """
     if not driver.is_on('service_proxy_transport'):
         if _Debug:
             lg.out(
                 _DebugLevel,
                 'proxy_sender._on_first_outbox_packet SKIP sending %r because service_proxy_transport is not started yet'
                 % outpacket)
         return None
     if not proxy_receiver.A():
         if _Debug:
             lg.out(
                 _DebugLevel,
                 'proxy_sender._on_first_outbox_packet SKIP sending %r because proxy_receiver() not exist'
                 % outpacket)
         return None
     if outpacket.Command == commands.Identity(
     ) and outpacket.CreatorID == my_id.getIDURL():
         if proxy_receiver.GetPossibleRouterIDURL(
         ) and proxy_receiver.GetPossibleRouterIDURL().to_bin(
         ) == outpacket.RemoteID.to_bin():
             if network_connector.A().state == 'DISCONNECTED':
                 if _Debug:
                     lg.out(
                         _DebugLevel,
                         'proxy_sender._on_first_outbox_packet SKIP sending %r because network_connector() is DISCONNECTED'
                         % outpacket)
                 return None
             if network_connector.A().state == 'CONNECTED':
                 lg.warn(
                     'sending %r to "possible" proxy router %r' %
                     (outpacket, proxy_receiver.GetPossibleRouterIDURL()))
                 pkt_out = packet_out.create(outpacket, wide, callbacks,
                                             target, route,
                                             response_timeout, keep_alive)
                 return pkt_out
             if _Debug:
                 lg.out(
                     _DebugLevel,
                     'proxy_sender._on_first_outbox_packet SKIP sending %r, network_connector() have transition state'
                     % outpacket)
             return None
     if proxy_receiver.A().state != 'LISTEN':
         if _Debug:
             lg.out(
                 _DebugLevel,
                 'proxy_sender._on_first_outbox_packet DELLAYED %r because proxy_receiver state is not LISTEN yet'
                 % outpacket)
         return self._do_add_pending_packet(outpacket, callbacks, wide,
                                            response_timeout, keep_alive)
     return self._do_send_packet_to_router(
         outpacket=outpacket,
         callbacks=callbacks,
         wide=wide,
         keep_alive=keep_alive,
         response_timeout=response_timeout,
     )
예제 #29
0
def SendToIDs(idlist,
              wide=False,
              ack_handler=None,
              timeout_handler=None,
              response_timeout=20):
    """
    Same, but send to many IDs and also check previous packets to not re-send.
    """
    lg.out(8, "propagate.SendToIDs to %d users, wide=%s" % (len(idlist), wide))
    if ack_handler is None:
        ack_handler = HandleAck
    if timeout_handler is None:
        timeout_handler = HandleTimeOut
    # MyID = my_id.getLocalID()
    # PacketID = MyID
    LocalIdentity = my_id.getLocalIdentity()
    Payload = strng.to_bin(LocalIdentity.serialize())
    # Hash = key.Hash(Payload)
    alreadysent = set()
    totalsent = 0
    inqueue = {}
    found_previous_packets = 0
    for pkt_out in packet_out.queue():
        if pkt_out.remote_idurl in idlist:
            if pkt_out.description.count('Identity'):
                if pkt_out.remote_idurl not in inqueue:
                    inqueue[pkt_out.remote_idurl] = 0
                inqueue[pkt_out.remote_idurl] += 1
                found_previous_packets += 1
    for contact in idlist:
        if not contact:
            continue
        if contact in alreadysent:
            # just want to send once even if both customer and supplier
            continue
        if contact in inqueue and inqueue[contact] > 2:
            # now only 2 protocols is working: tcp and udp
            lg.out(
                8,
                '        skip sending [Identity] to %s, packet already in the queue'
                % contact)
            continue


#        found_previous_packets = 0
#        for transfer_id in gate.transfers_out_by_idurl().get(contact, []):
#            ti = gate.transfers_out().get(transfer_id, None)
#            if ti and ti.description.count('Identity'):
#                found_previous_packets += 1
#                break
#        if found_previous_packets >= 3:
#            lg.out(8, '        skip sending to %s' % contact)
#            continue
        p = signed.Packet(
            commands.Identity(),
            my_id.getLocalID(),  # MyID,
            my_id.getLocalID(),  # MyID,
            commands.Identity(
            ),  #'Identity',  # my_id.getLocalID(), #PacketID,
            Payload,
            contact,
        )
        lg.out(8,
               "        sending [Identity] to %s" % nameurl.GetName(contact))
        # callback.register_interest(AckHandler, signed.RemoteID, signed.PacketID)
        gateway.outbox(p,
                       wide,
                       response_timeout=response_timeout,
                       callbacks={
                           commands.Ack(): ack_handler,
                           commands.Fail(): ack_handler,
                           None: timeout_handler,
                       })
        if wide:
            # this is a ping packet - need to clear old info
            p2p_stats.ErasePeerProtosStates(contact)
            p2p_stats.EraseMyProtosStates(contact)
        alreadysent.add(contact)
        totalsent += 1
    del alreadysent
    return totalsent
예제 #30
0
    def _do_process_inbox_packet(self, *args, **kwargs):
        newpacket, info, _, _ = args[0]
        block = encrypted.Unserialize(newpacket.Payload)
        if block is None:
            lg.err('reading data from %s' % newpacket.CreatorID)
            return
        try:
            session_key = key.DecryptLocalPrivateKey(block.EncryptedSessionKey)
            padded_data = key.DecryptWithSessionKey(session_key, block.EncryptedData)
            inpt = BytesIO(padded_data[:int(block.Length)])
            data = inpt.read()
        except:
            lg.err('reading data from %s' % newpacket.CreatorID)
            lg.exc()
            try:
                inpt.close()
            except:
                pass
            return
        inpt.close()
        routed_packet = signed.Unserialize(data)
        if not routed_packet:
            lg.err('unserialize packet failed from %s' % newpacket.CreatorID)
            return
        if _Debug:
            lg.out(_DebugLevel, '<<<Relay-IN %s from %s://%s with %d bytes' % (
                str(routed_packet), info.proto, info.host, len(data)))
        if routed_packet.Command == commands.Identity():
            if _Debug:
                lg.out(_DebugLevel, '    found identity in relay packet %s' % routed_packet)
            newidentity = identity.identity(xmlsrc=routed_packet.Payload)
            idurl = newidentity.getIDURL()
            if not identitycache.HasKey(idurl):
                lg.info('received new identity: %s' % idurl)
            if not identitycache.UpdateAfterChecking(idurl, routed_packet.Payload):
                lg.warn("ERROR has non-Valid identity")
                return
        if routed_packet.Command == commands.Relay() and routed_packet.PacketID.lower() == 'identity':
            if _Debug:
                lg.out(_DebugLevel, '    found routed identity in relay packet %s' % routed_packet)
            try:
                routed_identity = signed.Unserialize(routed_packet.Payload)
                newidentity = identity.identity(xmlsrc=routed_identity.Payload)
                idurl = newidentity.getIDURL()
                if not identitycache.HasKey(idurl):
                    lg.warn('received new "routed" identity: %s' % idurl)
                if not identitycache.UpdateAfterChecking(idurl, routed_identity.Payload):
                    lg.warn("ERROR has non-Valid identity")
                    return
            except:
                lg.exc()
#         if not routed_packet.Valid():
#             lg.err('invalid packet %s from %s' % (
#                 routed_packet, newpacket.CreatorID, ))
#             return
        self.traffic_in += len(data)
        packet_in.process(routed_packet, info)
        del block
        del data
        del padded_data
        del inpt
        del session_key
        del routed_packet