def pex(self, site=None, need_num=5): if not site: site = self.site # If no site defined request peers for this site # give back 5 connectible peers packed_peers = helper.packPeers(self.site.getConnectablePeers(5)) request = {"site": site.address, "peers": packed_peers["ip4"], "need": need_num} if packed_peers["onion"]: request["peers_onion"] = packed_peers["onion"] res = self.request("pex", request) if not res or "error" in res: return False added = 0 # Ip4 for peer in res.get("peers", []): address = helper.unpackAddress(peer) if site.addPeer(*address): added += 1 # Onion for peer in res.get("peers_onion", []): address = helper.unpackOnionAddress(peer) if site.addPeer(*address): added += 1 if added: self.log("Added peers using pex: %s" % added) return added
def pex(self, site=None, need_num=5): if not site: site = self.site # If no site defined request peers for this site # give back 5 connectible peers packed_peers = helper.packPeers(self.site.getConnectablePeers(5)) request = { "site": site.address, "peers": packed_peers["ip4"], "need": need_num } if packed_peers["onion"]: request["peers_onion"] = packed_peers["onion"] res = self.request("pex", request) if not res or "error" in res: return False added = 0 # Ip4 for peer in res.get("peers", []): address = helper.unpackAddress(peer) if site.addPeer(*address): added += 1 # Onion for peer in res.get("peers_onion", []): address = helper.unpackOnionAddress(peer) if site.addPeer(*address): added += 1 if added: self.log("Added peers using pex: %s" % added) return added
def processPeerRes(tracker_address, site, peers): added = 0 # Onion found_onion = 0 for packed_address in peers["onion"]: found_onion += 1 peer_onion, peer_port = helper.unpackOnionAddress(packed_address) if site.addPeer(peer_onion, peer_port, source="tracker"): added += 1 # Ip4 found_ipv4 = 0 peers_normal = itertools.chain(peers.get("ip4", []), peers.get("ipv4", []), peers.get("ipv6", [])) for packed_address in peers_normal: found_ipv4 += 1 peer_ip, peer_port = helper.unpackAddress(packed_address) if site.addPeer(peer_ip, peer_port, source="tracker"): added += 1 if added: site.worker_manager.onPeers() site.updateWebsocket(peers_added=added) return added
def actionPex(self, params): site = self.sites.get(params["site"]) if not site or not site.settings[ "serving"]: # Site unknown or not serving self.response({"error": "Unknown site"}) self.connection.badAction(5) return False got_peer_keys = [] added = 0 # Add requester peer to site connected_peer = site.addPeer(self.connection.ip, self.connection.port, source="request") if connected_peer: # It was not registered before added += 1 connected_peer.connect( self.connection) # Assign current connection to peer # Add sent peers to site for packed_address in itertools.chain(params.get("peers", []), params.get("peers_ipv6", [])): address = helper.unpackAddress(packed_address) got_peer_keys.append("%s:%s" % address) if site.addPeer(*address, source="pex"): added += 1 # Add sent onion peers to site for packed_address in params.get("peers_onion", []): address = helper.unpackOnionAddress(packed_address) got_peer_keys.append("%s:%s" % address) if site.addPeer(*address, source="pex"): added += 1 # Send back peers that is not in the sent list and connectable (not port 0) packed_peers = helper.packPeers( site.getConnectablePeers(params["need"], ignore=got_peer_keys, allow_private=False)) if added: site.worker_manager.onPeers() if config.verbose: self.log.debug( "Added %s peers to %s using pex, sending back %s" % (added, site, {key: len(val) for key, val in packed_peers.iteritems()})) back = { "peers": packed_peers["ipv4"], "peers_ipv6": packed_peers["ipv6"], "peers_onion": packed_peers["onion"] } self.response(back)
def actionPex(self, params): site = self.sites.get(params["site"]) if not site or not site.settings["serving"]: # Site unknown or not serving self.response({"error": "Unknown site"}) return False got_peer_keys = [] added = 0 # Add requester peer to site connected_peer = site.addPeer(self.connection.ip, self.connection.port) if connected_peer: # It was not registered before added += 1 connected_peer.connect(self.connection) # Assign current connection to peer # Add sent peers to site for packed_address in params.get("peers", []): address = helper.unpackAddress(packed_address) got_peer_keys.append("%s:%s" % address) if site.addPeer(*address): added += 1 # Add sent peers to site for packed_address in params.get("peers_onion", []): address = helper.unpackOnionAddress(packed_address) got_peer_keys.append("%s:%s" % address) if site.addPeer(*address): added += 1 # Add sent peers to site for packed_address in params.get("peers_i2p", []): address = helper.unpackI2PAddress(packed_address) got_peer_keys.append("%s:%s" % address) if site.addPeer(*address): added += 1 # Send back peers that is not in the sent list and connectable (not port 0) packed_peers = helper.packPeers(site.getConnectablePeers(params["need"], got_peer_keys)) if added: site.worker_manager.onPeers() if config.verbose: self.log.debug( "Added %s peers to %s using pex, sending back %s" % (added, site, len(packed_peers["ip4"]) + len(packed_peers["onion"]) + len(packed_peers["i2p"])) ) back = {} if packed_peers["ip4"]: back["peers"] = packed_peers["ip4"] if packed_peers["onion"]: back["peers_onion"] = packed_peers["onion"] if packed_peers["i2p"]: back["peers_i2p"] = packed_peers["i2p"] self.response(back)
def pex(self, site=None, need_num=5): if not site: site = self.site # If no site defined request peers for this site # give back 5 connectible peers packed_peers = helper.packPeers( self.site.getConnectablePeers(5, allow_private=False)) request = { "site": site.address, "peers": packed_peers["ipv4"], "need": need_num } if packed_peers["onion"]: request["peers_onion"] = packed_peers["onion"] if packed_peers["ipv6"]: request["peers_ipv6"] = packed_peers["ipv6"] res = self.request("pex", request) if not res or "error" in res: return False added = 0 # Remove unsupported peer types if "peers_ipv6" in res and "ipv6" not in self.connection.server.supported_ip_types: del res["peers_ipv6"] if "peers_onion" in res and "onion" not in self.connection.server.supported_ip_types: del res["peers_onion"] # Add IPv4 + IPv6 for peer in itertools.chain(res.get("peers", []), res.get("peers_ipv6", [])): address = helper.unpackAddress(peer) if site.addPeer(*address, source="pex"): added += 1 # Add Onion for peer in res.get("peers_onion", []): address = helper.unpackOnionAddress(peer) if site.addPeer(*address, source="pex"): added += 1 if added: self.log("Added peers using pex: %s" % added) return added
def actionPex(self, params): site = self.sites.get(params["site"]) if not site or not site.settings["serving"]: # Site unknown or not serving self.response({"error": "Unknown site"}) return False got_peer_keys = [] added = 0 # Add requester peer to site connected_peer = site.addPeer(self.connection.ip, self.connection.port, source="request") if connected_peer: # It was not registered before added += 1 connected_peer.connect(self.connection) # Assign current connection to peer # Add sent peers to site for packed_address in params.get("peers", []): address = helper.unpackAddress(packed_address) got_peer_keys.append("%s:%s" % address) if site.addPeer(*address, source="pex"): added += 1 # Add sent peers to site for packed_address in params.get("peers_onion", []): address = helper.unpackOnionAddress(packed_address) got_peer_keys.append("%s:%s" % address) if site.addPeer(*address, source="pex"): added += 1 # Send back peers that is not in the sent list and connectable (not port 0) packed_peers = helper.packPeers(site.getConnectablePeers(params["need"], got_peer_keys, allow_private=False)) if added: site.worker_manager.onPeers() if config.verbose: self.log.debug( "Added %s peers to %s using pex, sending back %s" % (added, site, len(packed_peers["ip4"]) + len(packed_peers["onion"])) ) back = {} if packed_peers["ip4"]: back["peers"] = packed_peers["ip4"] if packed_peers["onion"]: back["peers_onion"] = packed_peers["onion"] self.response(back)
def processPeerRes(site, peers): added = 0 # Ip4 found_ip4 = 0 for packed_address in peers["ip4"]: found_ip4 += 1 peer_ip, peer_port = helper.unpackAddress(packed_address) if site.addPeer(peer_ip, peer_port): added += 1 # Onion found_onion = 0 for packed_address in peers["onion"]: found_onion += 1 peer_onion, peer_port = helper.unpackOnionAddress(packed_address) if site.addPeer(peer_onion, peer_port): added += 1 if added: site.worker_manager.onPeers() site.updateWebsocket(peers_added=added) site.log.debug("Found %s ip4, %s onion peers, new: %s" % (found_ip4, found_onion, added))
def processPeerRes(tracker_address, site, peers): added = 0 # Ip4 found_ip4 = 0 for packed_address in peers["ip4"]: found_ip4 += 1 peer_ip, peer_port = helper.unpackAddress(packed_address) if site.addPeer(peer_ip, peer_port): added += 1 # Onion found_onion = 0 for packed_address in peers["onion"]: found_onion += 1 peer_onion, peer_port = helper.unpackOnionAddress(packed_address) if site.addPeer(peer_onion, peer_port): added += 1 if added: site.worker_manager.onPeers() site.updateWebsocket(peers_added=added) return added
def processPeerRes(site, peers): added = 0 have_ip4 = "ip4" in peers have_onion = "onion" in peers have_i2p = "i2p" in peers #Ip4 found_ip4 = 0 if have_ip4: for packed_address in peers["ip4"]: found_ip4 += 1 peer_ip, peer_port = helper.unpackAddress(packed_address) if site.addPeer(peer_ip, peer_port): added += 1 # Onion found_onion = 0 if have_onion: for packed_address in peers["onion"]: found_onion += 1 peer_onion, peer_port = helper.unpackOnionAddress(packed_address) if site.addPeer(peer_onion, peer_port): added += 1 # I2P found_i2p = 0 if have_i2p: for packed_address in peers["i2p"]: found_i2p += 1 peer_i2p, peer_port = helper.unpackI2PAddress(packed_address) if site.addPeer(peer_i2p, peer_port): added += 1 if added: site.worker_manager.onPeers() site.updateWebsocket(peers_added=added) site.log.debug("Found %s ip4, %s onion peers, %s i2p peers, new: %s" % (found_ip4, found_onion, found_i2p, added))
def testPackAddress(self): for port in [1, 1000, 65535]: for ip in [ "1.1.1.1", "127.0.0.1", "0.0.0.0", "255.255.255.255", "192.168.1.1" ]: assert len(helper.packAddress(ip, port)) == 6 assert helper.unpackAddress(helper.packAddress(ip, port)) == (ip, port) for ip in [ "1:2:3:4:5:6:7:8", "::1", "2001:19f0:6c01:e76:5400:1ff:fed6:3eca", "2001:4860:4860::8888" ]: assert len(helper.packAddress(ip, port)) == 18 assert helper.unpackAddress(helper.packAddress(ip, port)) == (ip, port) assert len(helper.packOnionAddress("boot3rdez4rzn36x.onion", port)) == 12 assert helper.unpackOnionAddress( helper.packOnionAddress("boot3rdez4rzn36x.onion", port)) == ("boot3rdez4rzn36x.onion", port) with pytest.raises(struct.error): helper.packAddress("1.1.1.1", 100000) with pytest.raises(socket.error): helper.packAddress("999.1.1.1", 1) with pytest.raises(Exception): helper.unpackAddress("X")
def testAddOnion(self, file_server, site, bootstrapper_db, tor_manager): onion1 = tor_manager.addOnion() onion2 = tor_manager.addOnion() peer = Peer("127.0.0.1", 1544, connection_server=file_server) hash1 = hashlib.sha256("site1").digest() hash2 = hashlib.sha256("site2").digest() hash3 = hashlib.sha256("site3").digest() bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=1234, hashes=[hash1, hash2, hash3]) res = peer.request( "announce", { "onions": [onion1, onion1, onion2], "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert len(res["peers"][0]["ip4"]) == 1 # Onion address not added yet site_peers = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers["onion"]) == 0 assert "onion_sign_this" in res # Sign the nonces sign1 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion1)) sign2 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion2)) # Bad sign (different address) res = peer.request( "announce", { "onions": [onion1], "onion_sign_this": res["onion_sign_this"], "onion_signs": { tor_manager.getPublickey(onion2): sign2 }, "hashes": [hash1], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Bad sign (missing one) res = peer.request( "announce", { "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": { tor_manager.getPublickey(onion1): sign1 }, "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Good sign res = peer.request( "announce", { "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": { tor_manager.getPublickey(onion1): sign1, tor_manager.getPublickey(onion2): sign2 }, "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" not in res # Onion addresses added site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 1 site_peers2 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash2) assert len(site_peers2["onion"]) == 1 site_peers3 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash3) assert len(site_peers3["onion"]) == 1 assert site_peers1["onion"][0] == site_peers2["onion"][0] assert site_peers2["onion"][0] != site_peers3["onion"][0] assert helper.unpackOnionAddress( site_peers1["onion"][0])[0] == onion1 + ".onion" assert helper.unpackOnionAddress( site_peers2["onion"][0])[0] == onion1 + ".onion" assert helper.unpackOnionAddress( site_peers3["onion"][0])[0] == onion2 + ".onion" tor_manager.delOnion(onion1) tor_manager.delOnion(onion2)
def testAddOnion(self, file_server, site, bootstrapper_db, tor_manager): onion1 = tor_manager.addOnion() onion2 = tor_manager.addOnion() peer = Peer("127.0.0.1", 1544, connection_server=file_server) hash1 = hashlib.sha256("site1").digest() hash2 = hashlib.sha256("site2").digest() bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=1234, hashes=[hash1, hash2]) res = peer.request("announce", { "onions": [onion1, onion2], "hashes": [hash1, hash2], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert len(res["peers"][0]["ip4"]) == 1 assert "onion_sign_this" in res # Onion address not added yet site_peers = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers["onion"]) == 0 assert "onion_sign_this" in res # Sign the nonces sign1 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion1)) sign2 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion2)) # Bad sign (different address) res = peer.request("announce", { "onions": [onion1], "onion_sign_this": res["onion_sign_this"], "onion_signs": {tor_manager.getPublickey(onion2): sign2}, "hashes": [hash1], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Bad sign (missing one) res = peer.request("announce", { "onions": [onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": {tor_manager.getPublickey(onion1): sign1}, "hashes": [hash1, hash2], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Good sign res = peer.request("announce", { "onions": [onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": {tor_manager.getPublickey(onion1): sign1, tor_manager.getPublickey(onion2): sign2}, "hashes": [hash1, hash2], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" not in res # Onion addresses added site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 1 site_peers2 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash2) assert len(site_peers2["onion"]) == 1 assert site_peers1["onion"][0] != site_peers2["onion"][0] assert helper.unpackOnionAddress(site_peers1["onion"][0])[0] == onion1+".onion" assert helper.unpackOnionAddress(site_peers2["onion"][0])[0] == onion2+".onion" tor_manager.delOnion(onion1) tor_manager.delOnion(onion2)