Sexy system trac icon instead of ugly console, Total received/sent stat, List all site peer, Dont sent passive peers over pex, Dont store passive peers on trackers, Dont monkey patch thread at all, Allow main command plugins

This commit is contained in:
HelloZeroNet 2015-04-15 02:54:10 +02:00
parent 804fed2659
commit 30281c8fb5
14 changed files with 1170 additions and 207 deletions

View file

@ -162,6 +162,7 @@ class Connection:
self.last_recv_time = time.time()
self.incomplete_buff_recv += 1
self.bytes_recv += len(buff)
self.server.bytes_recv += len(buff)
if not self.unpacker:
self.unpacker = msgpack.Unpacker()
self.unpacker.feed(buff)
@ -198,13 +199,19 @@ class Connection:
if config.debug_socket: self.log("Got handshake response: %s, ping: %s" % (message, ping))
self.last_ping_delay = ping
self.handshake = message
self.port = message["fileserver_port"] # Set peer fileserver port
if self.handshake.get("port_opened", None) == False: # Not connectable
self.port = 0
else:
self.port = message["fileserver_port"] # Set peer fileserver port
else:
self.log("Unknown response: %s" % message)
elif message.get("cmd"): # Handhsake request
if message["cmd"] == "handshake":
self.handshake = message["params"]
self.port = self.handshake["fileserver_port"] # Set peer fileserver port
if self.handshake.get("port_opened", None) == False: # Not connectable
self.port = 0
else:
self.port = self.handshake["fileserver_port"] # Set peer fileserver port
if config.debug_socket: self.log("Handshake request: %s" % message)
data = self.handshakeInfo()
data["cmd"] = "response"
@ -242,6 +249,7 @@ class Connection:
else: # Normal connection
data = msgpack.packb(message)
self.bytes_sent += len(data)
self.server.bytes_sent += len(data)
self.sock.sendall(data)
self.last_sent_time = time.time()
return True

View file

@ -22,6 +22,9 @@ class ConnectionServer:
self.running = True
self.thread_checker = gevent.spawn(self.checkConnections)
self.bytes_recv = 0
self.bytes_sent = 0
self.zmq_running = False
self.zmq_last_connection = None # Last incoming message client
@ -82,6 +85,8 @@ class ConnectionServer:
return connection
# No connection found
if port == 0:
raise Exception("This peer is not connectable")
try:
connection = Connection(self, ip, port)
self.ips[ip] = connection

View file

@ -131,10 +131,10 @@ class FileRequest:
address = self.unpackAddress(peer)
got_peer_keys.append("%s:%s" % address)
if (site.addPeer(*address)): added += 1
# Send back peers that is not in the sent list
# Send back peers that is not in the sent list and connectable (not port 0)
peers = site.peers.values()
random.shuffle(peers)
packed_peers = [peer.packAddress() for peer in peers if peer.key not in got_peer_keys][0:params["need"]]
packed_peers = [peer.packAddress() for peer in peers if not peer.key.endswith(":0") and peer.key not in got_peer_keys][0:params["need"]]
if added:
self.log.debug("Added %s peers to %s using pex, sending back %s" % (added, site, len(packed_peers)))
self.response({"peers": packed_peers})

View file

@ -150,7 +150,7 @@ class Peer:
if not site: site = self.site # If no site definied request peers for this site
peers = self.site.peers.values()
random.shuffle(peers)
packed_peers = [peer.packAddress() for peer in peers][0:need_num]
packed_peers = [peer.packAddress() for peer in peers if not peer.key.endswith(":0")][0:need_num]
response = self.request("pex", {"site": site.address, "peers": packed_peers, "need": need_num})
if not response or "error" in response:
return False

View file

@ -319,11 +319,10 @@ class Site:
address_hash = hashlib.sha1(self.address).hexdigest()
my_peer_id = sys.modules["main"].file_server.peer_id
# Later, if we have peer exchange
"""if sys.modules["main"].file_server.port_opened:
if sys.modules["main"].file_server.port_opened:
fileserver_port = config.fileserver_port
else: # Port not opened, report port 0
fileserver_port = 0"""
fileserver_port = 0
fileserver_port = config.fileserver_port
s = time.time()

View file

@ -112,9 +112,11 @@ class UiServer:
def stop(self):
self.log.debug("Stopping...")
# Close WS sockets
for client in self.server.clients.values():
client.ws.close()
if "clients" in dir(self.server):
for client in self.server.clients.values():
client.ws.close()
# Close http sockets
sock_closed = 0
for sock in self.server.sockets.values():

View file

@ -35,11 +35,10 @@ logging.getLogger('').name = "-" # Remove root prefix
from Debug import DebugHook
if config.debug:
console_log.setLevel(logging.DEBUG) # Display everything to console
from gevent import monkey; monkey.patch_all(thread=False) # thread=False because of pyfilesystem
else:
console_log.setLevel(logging.INFO) # Display only important info to console
from gevent import monkey; monkey.patch_all() # Make time, thread, socket gevent compatible
from gevent import monkey; monkey.patch_all(thread=False) # Make time, socket gevent compatible
import gevent
import time
@ -64,195 +63,196 @@ PluginManager.plugin_manager.loadPlugins()
# -- Actions --
@PluginManager.acceptPlugins
class Actions:
# Default action: Start serving UiServer and FileServer
def main(self):
logging.info("Version: %s, Python %s, Gevent: %s" % (config.version, sys.version, gevent.__version__))
global ui_server, file_server
from File import FileServer
from Ui import UiServer
logging.info("Creating UiServer....")
ui_server = UiServer()
logging.info("Creating FileServer....")
file_server = FileServer()
logging.info("Starting servers....")
gevent.joinall([gevent.spawn(ui_server.start), gevent.spawn(file_server.start)])
# Site commands
def siteCreate(self):
logging.info("Generating new privatekey...")
from Crypt import CryptBitcoin
privatekey = CryptBitcoin.newPrivatekey()
logging.info("----------------------------------------------------------------------")
logging.info("Site private key: %s" % privatekey)
logging.info(" !!! ^ Save it now, required to modify the site ^ !!!")
address = CryptBitcoin.privatekeyToAddress(privatekey)
logging.info("Site address: %s" % address)
logging.info("----------------------------------------------------------------------")
while True:
if raw_input("? Have you secured your private key? (yes, no) > ").lower() == "yes": break
else: logging.info("Please, secure it now, you going to need it to modify your site!")
logging.info("Creating directory structure...")
from Site import Site
os.mkdir("data/%s" % address)
open("data/%s/index.html" % address, "w").write("Hello %s!" % address)
logging.info("Creating content.json...")
site = Site(address)
site.content_manager.sign(privatekey=privatekey)
site.settings["own"] = True
site.saveSettings()
logging.info("Site created!")
def siteSign(self, address, privatekey=None, inner_path="content.json"):
from Site import Site
logging.info("Signing site: %s..." % address)
site = Site(address, allow_create = False)
if not privatekey: # If no privatekey in args then ask it now
import getpass
privatekey = getpass.getpass("Private key (input hidden):")
site.content_manager.sign(inner_path=inner_path, privatekey=privatekey, update_changed_files=True)
def siteVerify(self, address):
from Site import Site
logging.info("Verifing site: %s..." % address)
site = Site(address)
for content_inner_path in site.content_manager.contents:
logging.info("Verifing %s signature..." % content_inner_path)
if site.content_manager.verifyFile(content_inner_path, site.storage.open(content_inner_path, "rb"), ignore_same=False) == True:
logging.info("[OK] %s signed by address %s!" % (content_inner_path, address))
else:
logging.error("[ERROR] %s not signed by address %s!" % (content_inner_path, address))
logging.info("Verifying site files...")
bad_files = site.storage.verifyFiles()
if not bad_files:
logging.info("[OK] All file sha512sum matches!")
else:
logging.error("[ERROR] Error during verifying site files!")
def dbRebuild(self, address):
from Site import Site
logging.info("Rebuilding site sql cache: %s..." % address)
site = Site(address)
s = time.time()
site.storage.rebuildDb()
logging.info("Done in %.3fs" % (time.time()-s))
def dbQuery(self, address, query):
from Site import Site
import json
site = Site(address)
result = []
for row in site.storage.query(query):
result.append(dict(row))
print json.dumps(result, indent=4)
def siteAnnounce(self, address):
from Site.Site import Site
logging.info("Announcing site %s to tracker..." % address)
site = Site(address)
s = time.time()
site.announce()
print "Response time: %.3fs" % (time.time()-s)
print site.peers
def siteNeedFile(self, address, inner_path):
from Site import Site
site = Site(address)
site.announce()
print site.needFile(inner_path, update=True)
def sitePublish(self, address, peer_ip=None, peer_port=15441, inner_path="content.json"):
global file_server
from Site import Site
from File import FileServer # We need fileserver to handle incoming file requests
logging.info("Creating FileServer....")
file_server = FileServer()
file_server_thread = gevent.spawn(file_server.start, check_sites=False) # Dont check every site integrity
file_server.openport()
if file_server.port_opened == False:
logging.info("Port not opened, passive publishing not supported yet :(")
return
site = file_server.sites[address]
site.settings["serving"] = True # Serving the site even if its disabled
if peer_ip: # Announce ip specificed
site.addPeer(peer_ip, peer_port)
else: # Just ask the tracker
logging.info("Gathering peers from tracker")
site.announce() # Gather peers
site.publish(20, inner_path) # Push to 20 peers
time.sleep(3)
logging.info("Serving files...")
gevent.joinall([file_server_thread])
logging.info("Done.")
# Crypto commands
def cryptoPrivatekeyToAddress(self, privatekey=None):
from Crypt import CryptBitcoin
if not privatekey: # If no privatekey in args then ask it now
import getpass
privatekey = getpass.getpass("Private key (input hidden):")
print CryptBitcoin.privatekeyToAddress(privatekey)
# Peer
def peerPing(self, peer_ip, peer_port):
logging.info("Opening a simple connection server")
global file_server
from Connection import ConnectionServer
file_server = ConnectionServer("127.0.0.1", 1234)
from Peer import Peer
logging.info("Pinging 5 times peer: %s:%s..." % (peer_ip, int(peer_port)))
peer = Peer(peer_ip, peer_port)
for i in range(5):
s = time.time()
print peer.ping(),
print "Response time: %.3fs" % (time.time()-s)
time.sleep(1)
def peerGetFile(self, peer_ip, peer_port, site, filename):
logging.info("Opening a simple connection server")
global file_server
from Connection import ConnectionServer
file_server = ConnectionServer()
from Peer import Peer
logging.info("Getting %s/%s from peer: %s:%s..." % (site, filename, peer_ip, peer_port))
peer = Peer(peer_ip, peer_port)
s = time.time()
print peer.getFile(site, filename).read()
print "Response time: %.3fs" % (time.time()-s)
actions = Actions()
# Starts here when running zeronet.py
def start():
action_func = globals()[config.action] # Function reference
action_kwargs = config.getActionArguments() # non-config arguments when calling zeronet.py
action_func(**action_kwargs)
# Start serving UiServer and PeerServer
def main():
logging.info("Version: %s, Python %s, Gevent: %s" % (config.version, sys.version, gevent.__version__))
global ui_server, file_server
from File import FileServer
from Ui import UiServer
logging.info("Creating UiServer....")
ui_server = UiServer()
logging.info("Creating FileServer....")
file_server = FileServer()
logging.info("Starting servers....")
gevent.joinall([gevent.spawn(ui_server.start), gevent.spawn(file_server.start)])
# Site commands
def siteCreate():
logging.info("Generating new privatekey...")
from Crypt import CryptBitcoin
privatekey = CryptBitcoin.newPrivatekey()
logging.info("----------------------------------------------------------------------")
logging.info("Site private key: %s" % privatekey)
logging.info(" !!! ^ Save it now, required to modify the site ^ !!!")
address = CryptBitcoin.privatekeyToAddress(privatekey)
logging.info("Site address: %s" % address)
logging.info("----------------------------------------------------------------------")
while True:
if raw_input("? Have you secured your private key? (yes, no) > ").lower() == "yes": break
else: logging.info("Please, secure it now, you going to need it to modify your site!")
logging.info("Creating directory structure...")
from Site import Site
os.mkdir("data/%s" % address)
open("data/%s/index.html" % address, "w").write("Hello %s!" % address)
logging.info("Creating content.json...")
site = Site(address)
site.content_manager.sign(privatekey=privatekey)
site.settings["own"] = True
site.saveSettings()
logging.info("Site created!")
def siteSign(address, privatekey=None, inner_path="content.json"):
from Site import Site
logging.info("Signing site: %s..." % address)
site = Site(address, allow_create = False)
if not privatekey: # If no privatekey in args then ask it now
import getpass
privatekey = getpass.getpass("Private key (input hidden):")
site.content_manager.sign(inner_path=inner_path, privatekey=privatekey, update_changed_files=True)
def siteVerify(address):
from Site import Site
logging.info("Verifing site: %s..." % address)
site = Site(address)
for content_inner_path in site.content_manager.contents:
logging.info("Verifing %s signature..." % content_inner_path)
if site.content_manager.verifyFile(content_inner_path, site.storage.open(content_inner_path, "rb"), ignore_same=False) == True:
logging.info("[OK] %s signed by address %s!" % (content_inner_path, address))
else:
logging.error("[ERROR] %s not signed by address %s!" % (content_inner_path, address))
logging.info("Verifying site files...")
bad_files = site.storage.verifyFiles()
if not bad_files:
logging.info("[OK] All file sha512sum matches!")
else:
logging.error("[ERROR] Error during verifying site files!")
def dbRebuild(address):
from Site import Site
logging.info("Rebuilding site sql cache: %s..." % address)
site = Site(address)
s = time.time()
site.storage.rebuildDb()
logging.info("Done in %.3fs" % (time.time()-s))
def dbQuery(address, query):
from Site import Site
import json
site = Site(address)
result = []
for row in site.storage.query(query):
result.append(dict(row))
print json.dumps(result, indent=4)
def siteAnnounce(address):
from Site.Site import Site
logging.info("Announcing site %s to tracker..." % address)
site = Site(address)
s = time.time()
site.announce()
print "Response time: %.3fs" % (time.time()-s)
print site.peers
def siteNeedFile(address, inner_path):
from Site import Site
site = Site(address)
site.announce()
print site.needFile(inner_path, update=True)
def sitePublish(address, peer_ip=None, peer_port=15441, inner_path="content.json"):
global file_server
from Site import Site
from File import FileServer # We need fileserver to handle incoming file requests
logging.info("Creating FileServer....")
file_server = FileServer()
file_server_thread = gevent.spawn(file_server.start, check_sites=False) # Dont check every site integrity
file_server.openport()
if file_server.port_opened == False:
logging.info("Port not opened, passive publishing not supported yet :(")
return
site = file_server.sites[address]
site.settings["serving"] = True # Serving the site even if its disabled
if peer_ip: # Announce ip specificed
site.addPeer(peer_ip, peer_port)
else: # Just ask the tracker
logging.info("Gathering peers from tracker")
site.announce() # Gather peers
site.publish(20, inner_path) # Push to 20 peers
time.sleep(3)
logging.info("Serving files...")
gevent.joinall([file_server_thread])
logging.info("Done.")
# Crypto commands
def cryptoPrivatekeyToAddress(privatekey=None):
from Crypt import CryptBitcoin
if not privatekey: # If no privatekey in args then ask it now
import getpass
privatekey = getpass.getpass("Private key (input hidden):")
print CryptBitcoin.privatekeyToAddress(privatekey)
# Peer
def peerPing(peer_ip, peer_port):
logging.info("Opening a simple connection server")
global file_server
from Connection import ConnectionServer
file_server = ConnectionServer("127.0.0.1", 1234)
from Peer import Peer
logging.info("Pinging 5 times peer: %s:%s..." % (peer_ip, int(peer_port)))
peer = Peer(peer_ip, peer_port)
for i in range(5):
s = time.time()
print peer.ping(),
print "Response time: %.3fs" % (time.time()-s)
time.sleep(1)
def peerGetFile(peer_ip, peer_port, site, filename):
logging.info("Opening a simple connection server")
global file_server
from Connection import ConnectionServer
file_server = ConnectionServer()
from Peer import Peer
logging.info("Getting %s/%s from peer: %s:%s..." % (site, filename, peer_ip, peer_port))
peer = Peer(peer_ip, peer_port)
s = time.time()
print peer.getFile(site, filename).read()
print "Response time: %.3fs" % (time.time()-s)
# Call function
func = getattr(actions, config.action, None)
action_kwargs = config.getActionArguments()
func(**action_kwargs)