def handlePeerSendSelf(self, all_message, to, msg_hash, message, cert, immediate):
        signature_address = all_message["signature"].split("|")[0]

        if to is not None:
            # This is a reply to peerSend
            self.site.p2p_to[to].set({
                "hash": msg_hash,
                "message": message,
                "signed_by": signature_address,
                "cert": cert
            })
        else:
            # Broadcast
            websockets = getWebsockets(self.site)

            data = {
                "ip": "self",
                "hash": msg_hash,
                "message": message,
                "signed_by": signature_address,
                "cert": cert,
                "broadcast": False
            }

            for ws in websockets:
                ws.cmd("peerReceive", data)

            # Save to cache
            if not websockets and immediate:
                self.site.p2p_unread.append(data)
    def handlePeerSend(self, params):
        ip = "%s:%s" % (self.connection.ip, self.connection.port)
        raw = json.loads(params["raw"])


        res, signature_address, cert, msg_hash = self.peerCheckMessage(raw, params, ip)
        if not res:
            return

        self.response({
            "ok": "thx"
        })

        site = self.sites.get(raw["site"])
        if "to" in raw:
            # This is a reply to peerSend
            site.p2p_to[raw["to"]].set({
                "hash": msg_hash,
                "message": raw["message"],
                "signed_by": signature_address,
                "cert": cert
            })
        else:
            # Broadcast
            websockets = getWebsockets(site)
            if websockets:
                # Wait for result (valid/invalid)
                site.p2p_result[msg_hash] = gevent.event.AsyncResult()

            for ws in websockets:
                ws.cmd("peerReceive", {
                    "ip": ip,
                    "hash": msg_hash,
                    "message": raw["message"],
                    "signed_by": signature_address,
                    "cert": cert,
                    "site": raw["site"],
                    "broadcast": False
                })

            # Maybe active filter will reply?
            if websockets:
                # Wait for p2p_result
                result = site.p2p_result[msg_hash].get()
                del site.p2p_result[msg_hash]
                if not result:
                    self.connection.badAction(10)

            # Save to cache
            if not websockets and raw["immediate"]:
                site.p2p_unread.append({
                    "ip": ip,
                    "hash": msg_hash,
                    "message": raw["message"],
                    "signed_by": signature_address,
                    "cert": cert,
                    "site": raw["site"],
                    "broadcast": False
                })
예제 #3
0
    def handlePeerBroadcast(self, to, message, privatekey=None, peer_count=5, immediate=False):
        # Check message
        if not self.peerCheckMessage(to, message):
            return

        # Generate message and sign it
        all_message = {
            "message": message,
            "peer_count": peer_count,
            "broadcast": True, # backward compatibility
            "immediate": immediate,
            "site": self.site.address
        }

        all_message, msg_hash, cert = self.peerGenerateMessage(all_message, privatekey)

        peers = self.site.getConnectedPeers()
        if len(peers) < peer_count:  # Add more, non-connected peers if necessary
            peers += self.site.getRecentPeers(peer_count - len(peers))

        # Send message to peers
        jobs = []
        for peer in peers:
            jobs.append(gevent.spawn(self.p2pBroadcast, peer, all_message))

        # Send message to myself
        self.site.p2p_received.append(msg_hash)

        websockets = getWebsockets(self.site)
        for ws in websockets:
            ws.cmd("peerReceive", {
                "ip": "self",
                "hash": msg_hash,
                "message": message,
                "signed_by": all_message["signature"].split("|")[0] if all_message["signature"] else "",
                "cert": cert,
                "broadcast": True
            })

        if not websockets and immediate:
            self.site.p2p_unread.append({
                "ip": "self",
                "hash": msg_hash,
                "message": message,
                "signed_by": all_message["signature"].split("|")[0] if all_message["signature"] else "",
                "cert": cert,
                "broadcast": True
            })


        # Reply
        self.response(to, {
            "sent": True
        })
    def handlePeerBroadcast(self, params):
        ip = "%s:%s" % (self.connection.ip, self.connection.port)

        raw = json.loads(params["raw"])

        res, signature_address, cert, msg_hash = self.peerCheckMessage(raw, params, ip)
        if not res:
            return

        self.response({
            "ok": "thx"
        })


        site = self.sites.get(raw["site"])
        websockets = getWebsockets(site)
        if websockets:
            # Wait for result (valid/invalid)
            site.p2p_result[msg_hash] = gevent.event.AsyncResult()

        # Send to WebSocket
        for ws in websockets:
            ws.cmd("peerReceive", {
                "ip": ip,
                "hash": msg_hash,
                "message": raw["message"],
                "signed_by": signature_address,
                "cert": cert,
                "site": raw["site"],
                "broadcast": True
            })


        # Maybe active filter will reply?
        if websockets:
            # Wait for p2p_result
            result = site.p2p_result[msg_hash].get()
            del site.p2p_result[msg_hash]
            if not result:
                self.connection.badAction(10)
                return

        # Save to cache
        if not websockets and raw["immediate"]:
            site.p2p_unread.append({
                "ip": "%s:%s" % (self.connection.ip, self.connection.port),
                "hash": msg_hash,
                "message": raw["message"],
                "signed_by": signature_address,
                "cert": cert,
                "site": raw["site"],
                "broadcast": True
            })


        # Get peer list
        peers = site.getConnectedPeers()
        if len(peers) < raw["peer_count"]:  # Add more, non-connected peers if necessary
            peers += site.getRecentPeers(raw["peer_count"] - len(peers))

        # Send message to neighbour peers
        for peer in peers:
            gevent.spawn(peer.request, "peerBroadcast", params)
예제 #5
0
    def handlePeerSend(self,
                       to_,
                       ip,
                       message,
                       privatekey=None,
                       to=None,
                       immediate=False):
        # Check message
        if not self.peerCheckMessage(to_, message):
            return

        # Get peer or connect to it if it isn't cached
        if ip != "self":
            peer = self.site.peers.get(ip)
            if not peer:
                mip, mport = ip.rsplit(":", 1)
                peer = self.site.addPeer(mip, mport, source="peerSend")
            if not peer:
                # Couldn't connect to this IP
                self.response(to_, {"error": "Could not find peer %s" % ip})
                return

        # Generate hash
        all_message = {
            "message": message,
            "immediate": immediate,
            "site": self.site.address
        }
        if to:
            all_message["to"] = to

        all_message, msg_hash, cert = self.peerGenerateMessage(
            all_message, privatekey)

        # Send message
        self.site.p2p_to[msg_hash] = gevent.event.AsyncResult()
        if ip == "self":
            self.handlePeerSendSelf(all_message, to, msg_hash, message, cert,
                                    immediate)
        else:
            peer.request("peerSend", all_message)

        # Get reply
        reply = self.site.p2p_to[msg_hash].get()
        self.response(to_, reply)

        # Also send the message to myself
        data = {
            "ip":
            ip,
            "hash":
            msg_hash,
            "message":
            message,
            "signed_by":
            all_message["signature"].split("|")[0]
            if all_message["signature"] else "",
            "cert":
            cert,
            "site":
            self.site.address,
            "broadcast":
            False
        }
        for ws in getWebsockets(self.site):
            ws.cmd("peerSend", data)