2006-11-30 22:39:24 +00:00
|
|
|
|
|
|
|
from foolscap import Tub, Referenceable
|
2006-12-01 01:09:57 +00:00
|
|
|
from foolscap.eventual import eventually
|
2006-11-30 22:39:24 +00:00
|
|
|
from twisted.application import service
|
|
|
|
from twisted.python import log
|
|
|
|
import os.path
|
2006-11-30 23:39:38 +00:00
|
|
|
from allmydata.util.iputil import get_local_ip_for
|
2006-11-30 22:39:24 +00:00
|
|
|
|
|
|
|
class Roster(service.MultiService, Referenceable):
|
2006-12-01 00:43:15 +00:00
|
|
|
def __init__(self):
|
|
|
|
service.MultiService.__init__(self)
|
2006-12-01 01:09:57 +00:00
|
|
|
self.phonebook = {}
|
|
|
|
self.connections = {}
|
2006-12-01 00:43:15 +00:00
|
|
|
|
2006-12-01 01:09:57 +00:00
|
|
|
def remote_hello(self, nodeid, node, pburl):
|
2006-12-01 00:43:15 +00:00
|
|
|
log.msg("contact from %s" % nodeid)
|
2006-12-01 01:09:57 +00:00
|
|
|
eventually(self._educate_the_new_peer, node)
|
|
|
|
eventually(self._announce_new_peer, nodeid, pburl)
|
|
|
|
self.phonebook[nodeid] = pburl
|
|
|
|
self.connections[nodeid] = node
|
2006-12-01 00:43:15 +00:00
|
|
|
node.notifyOnDisconnect(self._lost_node, nodeid)
|
|
|
|
|
2006-12-01 01:09:57 +00:00
|
|
|
def _educate_the_new_peer(self, node):
|
|
|
|
node.callRemote("add_peers", new_peers=list(self.phonebook.items()))
|
|
|
|
|
|
|
|
def _announce_new_peer(self, new_nodeid, new_node_pburl):
|
|
|
|
for targetnode in self.connections.values():
|
|
|
|
targetnode.callRemote("add_peers",
|
|
|
|
new_peers=[(new_nodeid, new_node_pburl)])
|
|
|
|
|
2006-12-01 00:43:15 +00:00
|
|
|
def _lost_node(self, nodeid):
|
|
|
|
log.msg("lost contact with %s" % nodeid)
|
2006-12-01 01:09:57 +00:00
|
|
|
del self.phonebook[nodeid]
|
|
|
|
del self.connections[nodeid]
|
|
|
|
eventually(self._announce_lost_peer, nodeid)
|
|
|
|
|
|
|
|
def _announce_lost_peer(self, lost_nodeid):
|
|
|
|
for targetnode in self.connections.values():
|
|
|
|
targetnode.callRemote("lost_peers", lost_peers=[lost_nodeid])
|
|
|
|
|
2006-12-01 00:43:15 +00:00
|
|
|
|
2006-11-30 22:39:24 +00:00
|
|
|
|
|
|
|
class Queen(service.MultiService):
|
|
|
|
CERTFILE = "queen.pem"
|
2006-11-30 23:39:38 +00:00
|
|
|
PORTNUMFILE = "queen.port"
|
2006-11-30 22:39:24 +00:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
service.MultiService.__init__(self)
|
|
|
|
if os.path.exists(self.CERTFILE):
|
|
|
|
self.tub = Tub(certData=open(self.CERTFILE, "rb").read())
|
|
|
|
else:
|
|
|
|
self.tub = Tub()
|
|
|
|
f = open(self.CERTFILE, "wb")
|
|
|
|
f.write(self.tub.getCertData())
|
|
|
|
f.close()
|
2006-11-30 23:39:38 +00:00
|
|
|
portnum = 0
|
|
|
|
if os.path.exists(self.PORTNUMFILE):
|
|
|
|
portnum = int(open(self.PORTNUMFILE, "r").read())
|
|
|
|
self.tub.listenOn("tcp:%d" % portnum)
|
|
|
|
# we must wait until our service has started before we can find out
|
|
|
|
# our IP address and thus do tub.setLocation, and we can't register
|
|
|
|
# any services with the Tub until after that point
|
|
|
|
self.tub.setServiceParent(self)
|
2006-11-30 22:39:24 +00:00
|
|
|
self.urls = {}
|
2006-12-01 02:38:38 +00:00
|
|
|
|
|
|
|
AUTHKEYSFILEBASE = "authorized_keys."
|
|
|
|
for f in os.listdir("."):
|
|
|
|
if f.startswith(AUTHKEYSFILEBASE):
|
|
|
|
portnum = int(f[len(AUTHKEYSFILEBASE):])
|
|
|
|
from allmydata import manhole
|
|
|
|
m = manhole.AuthorizedKeysManhole(portnum, f)
|
|
|
|
m.setServiceParent(self)
|
|
|
|
log.msg("AuthorizedKeysManhole listening on %d" % portnum)
|
2006-11-30 23:39:38 +00:00
|
|
|
|
|
|
|
def _setup_tub(self, local_ip):
|
|
|
|
l = self.tub.getListeners()[0]
|
|
|
|
portnum = l.getPortnum()
|
|
|
|
self.tub.setLocation("%s:%d" % (local_ip, portnum))
|
|
|
|
if not os.path.exists(self.PORTNUMFILE):
|
|
|
|
# record which port we're listening on, so we can grab the same
|
|
|
|
# one next time
|
|
|
|
f = open(self.PORTNUMFILE, "w")
|
|
|
|
f.write("%d\n" % portnum)
|
|
|
|
f.close()
|
|
|
|
self.tub.setLocation("%s:%d" % (local_ip, l.getPortnum()))
|
|
|
|
return local_ip
|
|
|
|
|
|
|
|
def _setup_services(self, local_ip):
|
2006-11-30 22:39:24 +00:00
|
|
|
r = Roster()
|
|
|
|
r.setServiceParent(self)
|
2006-11-30 23:39:38 +00:00
|
|
|
self.urls["roster"] = self.tub.registerReference(r, "roster")
|
|
|
|
log.msg(" roster is at %s" % self.urls["roster"])
|
2006-11-30 22:39:24 +00:00
|
|
|
|
|
|
|
def startService(self):
|
2006-11-30 23:39:38 +00:00
|
|
|
# note: this class can only be started and stopped once.
|
2006-11-30 22:39:24 +00:00
|
|
|
service.MultiService.startService(self)
|
2006-11-30 22:55:26 +00:00
|
|
|
log.msg("queen running")
|
2006-11-30 23:39:38 +00:00
|
|
|
d = get_local_ip_for()
|
|
|
|
d.addCallback(self._setup_tub)
|
|
|
|
d.addCallback(self._setup_services)
|
|
|
|
|