2008-06-18 19:24:16 +00:00
|
|
|
|
|
|
|
import time, os.path
|
|
|
|
from zope.interface import implements
|
|
|
|
from twisted.application import service
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
from foolscap.api import Referenceable
|
2008-11-22 00:43:52 +00:00
|
|
|
import allmydata
|
2008-06-18 19:24:16 +00:00
|
|
|
from allmydata import node
|
2012-04-23 22:02:22 +00:00
|
|
|
from allmydata.util import log, rrefutil
|
2008-06-19 00:04:41 +00:00
|
|
|
from allmydata.introducer.interfaces import \
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
RIIntroducerPublisherAndSubscriberService_v2
|
|
|
|
from allmydata.introducer.common import convert_announcement_v1_to_v2, \
|
|
|
|
convert_announcement_v2_to_v1, unsign_from_foolscap, make_index, \
|
2012-04-23 22:02:22 +00:00
|
|
|
get_tubid_string_from_ann, SubscriberDescriptor, AnnouncementDescriptor
|
2008-06-18 19:24:16 +00:00
|
|
|
|
|
|
|
class IntroducerNode(node.Node):
|
|
|
|
PORTNUMFILE = "introducer.port"
|
|
|
|
NODETYPE = "introducer"
|
2011-08-03 01:32:12 +00:00
|
|
|
GENERATED_FILES = ['introducer.furl']
|
2008-06-18 19:24:16 +00:00
|
|
|
|
|
|
|
def __init__(self, basedir="."):
|
|
|
|
node.Node.__init__(self, basedir)
|
2008-09-30 23:21:49 +00:00
|
|
|
self.read_config()
|
2008-06-18 19:24:16 +00:00
|
|
|
self.init_introducer()
|
2008-09-30 23:21:49 +00:00
|
|
|
webport = self.get_config("node", "web.port", None)
|
2008-06-18 19:24:16 +00:00
|
|
|
if webport:
|
|
|
|
self.init_web(webport) # strports string
|
|
|
|
|
|
|
|
def init_introducer(self):
|
|
|
|
introducerservice = IntroducerService(self.basedir)
|
|
|
|
self.add_service(introducerservice)
|
|
|
|
|
|
|
|
d = self.when_tub_ready()
|
|
|
|
def _publish(res):
|
|
|
|
self.introducer_url = self.tub.registerReference(introducerservice,
|
|
|
|
"introducer")
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self.log(" introducer is at %s" % self.introducer_url,
|
|
|
|
umid="qF2L9A")
|
2008-06-18 19:24:16 +00:00
|
|
|
self.write_config("introducer.furl", self.introducer_url + "\n")
|
|
|
|
d.addCallback(_publish)
|
2008-08-26 01:57:59 +00:00
|
|
|
d.addErrback(log.err, facility="tahoe.init",
|
|
|
|
level=log.BAD, umid="UaNs9A")
|
2008-06-18 19:24:16 +00:00
|
|
|
|
|
|
|
def init_web(self, webport):
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self.log("init_web(webport=%s)", args=(webport,), umid="2bUygA")
|
2008-06-18 19:24:16 +00:00
|
|
|
|
|
|
|
from allmydata.webish import IntroducerWebishServer
|
|
|
|
nodeurl_path = os.path.join(self.basedir, "node.url")
|
2012-03-07 02:25:05 +00:00
|
|
|
staticdir = self.get_config("node", "web.static", "public_html")
|
|
|
|
staticdir = os.path.expanduser(staticdir)
|
|
|
|
ws = IntroducerWebishServer(self, webport, nodeurl_path, staticdir)
|
2008-06-18 19:24:16 +00:00
|
|
|
self.add_service(ws)
|
|
|
|
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
class WrapV1SubscriberInV2Interface: # for_v1
|
|
|
|
"""I wrap a RemoteReference that points at an old v1 subscriber, enabling
|
|
|
|
it to be treated like a v2 subscriber.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, original):
|
2012-04-23 22:02:22 +00:00
|
|
|
self.original = original # also used for tests
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
def __eq__(self, them):
|
|
|
|
return self.original == them
|
|
|
|
def __ne__(self, them):
|
|
|
|
return self.original != them
|
|
|
|
def __hash__(self):
|
|
|
|
return hash(self.original)
|
|
|
|
def getRemoteTubID(self):
|
|
|
|
return self.original.getRemoteTubID()
|
|
|
|
def getSturdyRef(self):
|
|
|
|
return self.original.getSturdyRef()
|
|
|
|
def getPeer(self):
|
|
|
|
return self.original.getPeer()
|
2012-04-23 22:02:22 +00:00
|
|
|
def getLocationHints(self):
|
|
|
|
return self.original.getLocationHints()
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
def callRemote(self, methname, *args, **kwargs):
|
|
|
|
m = getattr(self, "wrap_" + methname)
|
|
|
|
return m(*args, **kwargs)
|
|
|
|
def wrap_announce_v2(self, announcements):
|
|
|
|
anns_v1 = [convert_announcement_v2_to_v1(ann) for ann in announcements]
|
|
|
|
return self.original.callRemote("announce", set(anns_v1))
|
|
|
|
def wrap_set_encoding_parameters(self, parameters):
|
|
|
|
# note: unused
|
|
|
|
return self.original.callRemote("set_encoding_parameters", parameters)
|
|
|
|
def notifyOnDisconnect(self, *args, **kwargs):
|
|
|
|
return self.original.notifyOnDisconnect(*args, **kwargs)
|
|
|
|
|
2008-06-18 19:24:16 +00:00
|
|
|
class IntroducerService(service.MultiService, Referenceable):
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
implements(RIIntroducerPublisherAndSubscriberService_v2)
|
2008-06-18 19:24:16 +00:00
|
|
|
name = "introducer"
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
# v1 is the original protocol, supported since 1.0 (but only advertised
|
|
|
|
# starting in 1.3). v2 is the new signed protocol, supported after 1.9
|
|
|
|
VERSION = { "http://allmydata.org/tahoe/protocols/introducer/v1": { },
|
|
|
|
"http://allmydata.org/tahoe/protocols/introducer/v2": { },
|
versioning: include an "appname" in the application version string in the versioning protocol, and make that appname be controlled by setup.py
It is currently hardcoded in setup.py to be 'allmydata-tahoe'. Ticket #556 is to make it configurable by a runtime command-line argument to setup.py: "--appname=foo", but I suddenly wondered if we really wanted that and at the same time realized that we don't need that for tahoe-1.3.0 release, so this patch just hardcodes it in setup.py.
setup.py inspects a file named 'src/allmydata/_appname.py' and assert that it contains the string "__appname__ = 'allmydata-tahoe'", and creates it if it isn't already present. src/allmydata/__init__.py import _appname and reads __appname__ from it. The rest of the Python code imports allmydata and inspects "allmydata.__appname__", although actually every use it uses "allmydata.__full_version__" instead, where "allmydata.__full_version__" is created in src/allmydata/__init__.py to be:
__full_version__ = __appname + '-' + str(__version__).
All the code that emits an "application version string" when describing what version of a protocol it supports (introducer server, storage server, upload helper), or when describing itself in general (introducer client), usese allmydata.__full_version__.
This fixes ticket #556 at least well enough for tahoe-1.3.0 release.
2009-02-12 00:18:16 +00:00
|
|
|
"application-version": str(allmydata.__full_version__),
|
2008-11-22 00:43:52 +00:00
|
|
|
}
|
2008-06-18 19:24:16 +00:00
|
|
|
|
|
|
|
def __init__(self, basedir="."):
|
|
|
|
service.MultiService.__init__(self)
|
|
|
|
self.introducer_url = None
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
# 'index' is (service_name, key_s, tubid), where key_s or tubid is
|
|
|
|
# None
|
|
|
|
self._announcements = {} # dict of index ->
|
|
|
|
# (ann_t, canary, ann, timestamp)
|
|
|
|
|
|
|
|
# ann (the announcement dictionary) is cleaned up: nickname is always
|
|
|
|
# unicode, servicename is always ascii, etc, even though
|
|
|
|
# simplejson.loads sometimes returns either
|
|
|
|
|
|
|
|
# self._subscribers is a dict mapping servicename to subscriptions
|
|
|
|
# 'subscriptions' is a dict mapping rref to a subscription
|
|
|
|
# 'subscription' is a tuple of (subscriber_info, timestamp)
|
|
|
|
# 'subscriber_info' is a dict, provided directly for v2 clients, or
|
|
|
|
# synthesized for v1 clients. The expected keys are:
|
|
|
|
# version, nickname, app-versions, my-version, oldest-supported
|
|
|
|
self._subscribers = {}
|
|
|
|
|
|
|
|
# self._stub_client_announcements contains the information provided
|
|
|
|
# by v1 clients. We stash this so we can match it up with their
|
|
|
|
# subscriptions.
|
|
|
|
self._stub_client_announcements = {} # maps tubid to sinfo # for_v1
|
|
|
|
|
2009-06-23 02:10:47 +00:00
|
|
|
self._debug_counts = {"inbound_message": 0,
|
|
|
|
"inbound_duplicate": 0,
|
2012-06-11 02:10:22 +00:00
|
|
|
"inbound_no_seqnum": 0,
|
|
|
|
"inbound_old_replay": 0,
|
2009-06-23 02:10:47 +00:00
|
|
|
"inbound_update": 0,
|
|
|
|
"outbound_message": 0,
|
|
|
|
"outbound_announcements": 0,
|
|
|
|
"inbound_subscribe": 0}
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self._debug_outstanding = 0 # also covers WrapV1SubscriberInV2Interface
|
|
|
|
|
|
|
|
def _debug_retired(self, res):
|
|
|
|
self._debug_outstanding -= 1
|
|
|
|
return res
|
2008-06-18 19:24:16 +00:00
|
|
|
|
|
|
|
def log(self, *args, **kwargs):
|
|
|
|
if "facility" not in kwargs:
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
kwargs["facility"] = "tahoe.introducer.server"
|
2008-06-18 19:24:16 +00:00
|
|
|
return log.msg(*args, **kwargs)
|
|
|
|
|
2012-04-23 22:02:22 +00:00
|
|
|
def get_announcements(self, include_stub_clients=True):
|
|
|
|
"""Return a list of AnnouncementDescriptor for all announcements"""
|
|
|
|
announcements = []
|
|
|
|
for (index, (_, canary, ann, when)) in self._announcements.items():
|
|
|
|
if ann["service-name"] == "stub_client":
|
|
|
|
if not include_stub_clients:
|
|
|
|
continue
|
|
|
|
ad = AnnouncementDescriptor(when, index, canary, ann)
|
|
|
|
announcements.append(ad)
|
|
|
|
return announcements
|
|
|
|
|
2008-06-18 19:24:16 +00:00
|
|
|
def get_subscribers(self):
|
2012-04-23 22:02:22 +00:00
|
|
|
"""Return a list of SubscriberDescriptor objects for all subscribers"""
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
s = []
|
|
|
|
for service_name, subscriptions in self._subscribers.items():
|
|
|
|
for rref,(subscriber_info,when) in subscriptions.items():
|
2012-04-23 22:02:22 +00:00
|
|
|
# note that if the subscriber didn't do Tub.setLocation,
|
|
|
|
# tubid will be None. Also, subscribers do not tell us which
|
|
|
|
# pubkey they use; only publishers do that.
|
|
|
|
tubid = rref.getRemoteTubID() or "?"
|
|
|
|
advertised_addresses = rrefutil.hosts_for_rref(rref)
|
|
|
|
remote_address = rrefutil.stringify_remote_address(rref)
|
|
|
|
# these three assume subscriber_info["version"]==0, but
|
|
|
|
# should tolerate other versions
|
|
|
|
if not subscriber_info:
|
|
|
|
# V1 clients that haven't yet sent their stub_info data
|
|
|
|
subscriber_info = {}
|
|
|
|
nickname = subscriber_info.get("nickname", u"?")
|
|
|
|
version = subscriber_info.get("my-version", u"?")
|
|
|
|
app_versions = subscriber_info.get("app-versions", {})
|
|
|
|
# 'when' is the time they subscribed
|
|
|
|
sd = SubscriberDescriptor(service_name, when,
|
|
|
|
nickname, version, app_versions,
|
|
|
|
advertised_addresses, remote_address,
|
|
|
|
tubid)
|
|
|
|
s.append(sd)
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
return s
|
2008-06-18 19:24:16 +00:00
|
|
|
|
2008-11-22 00:43:52 +00:00
|
|
|
def remote_get_version(self):
|
|
|
|
return self.VERSION
|
|
|
|
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
def remote_publish(self, ann_t): # for_v1
|
|
|
|
lp = self.log("introducer: old (v1) announcement published: %s"
|
|
|
|
% (ann_t,), umid="6zGOIw")
|
|
|
|
ann_v2 = convert_announcement_v1_to_v2(ann_t)
|
|
|
|
return self.publish(ann_v2, None, lp)
|
|
|
|
|
|
|
|
def remote_publish_v2(self, ann_t, canary):
|
|
|
|
lp = self.log("introducer: announcement (v2) published", umid="L2QXkQ")
|
|
|
|
return self.publish(ann_t, canary, lp)
|
|
|
|
|
|
|
|
def publish(self, ann_t, canary, lp):
|
2009-06-23 02:10:47 +00:00
|
|
|
try:
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self._publish(ann_t, canary, lp)
|
2009-06-23 02:10:47 +00:00
|
|
|
except:
|
|
|
|
log.err(format="Introducer.remote_publish failed on %(ann)s",
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
ann=ann_t,
|
|
|
|
level=log.UNUSUAL, parent=lp, umid="620rWA")
|
2009-06-23 02:10:47 +00:00
|
|
|
raise
|
|
|
|
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
def _publish(self, ann_t, canary, lp):
|
2009-06-23 02:10:47 +00:00
|
|
|
self._debug_counts["inbound_message"] += 1
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self.log("introducer: announcement published: %s" % (ann_t,),
|
|
|
|
umid="wKHgCw")
|
|
|
|
ann, key = unsign_from_foolscap(ann_t) # might raise BadSignatureError
|
|
|
|
index = make_index(ann, key)
|
2009-06-23 02:10:47 +00:00
|
|
|
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
service_name = str(ann["service-name"])
|
|
|
|
if service_name == "stub_client": # for_v1
|
|
|
|
self._attach_stub_client(ann, lp)
|
|
|
|
return
|
2009-06-23 02:10:47 +00:00
|
|
|
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
old = self._announcements.get(index)
|
|
|
|
if old:
|
|
|
|
(old_ann_t, canary, old_ann, timestamp) = old
|
|
|
|
if old_ann == ann:
|
|
|
|
self.log("but we already knew it, ignoring", level=log.NOISY,
|
|
|
|
umid="myxzLw")
|
2009-06-23 02:10:47 +00:00
|
|
|
self._debug_counts["inbound_duplicate"] += 1
|
2008-06-18 19:24:16 +00:00
|
|
|
return
|
|
|
|
else:
|
2012-06-11 02:10:22 +00:00
|
|
|
if "seqnum" in old_ann:
|
|
|
|
# must beat previous sequence number to replace
|
2013-03-19 00:40:56 +00:00
|
|
|
if ("seqnum" not in ann
|
|
|
|
or not isinstance(ann["seqnum"], (int,long))):
|
|
|
|
self.log("not replacing old ann, no valid seqnum",
|
2012-06-11 02:10:22 +00:00
|
|
|
level=log.NOISY, umid="ySbaVw")
|
|
|
|
self._debug_counts["inbound_no_seqnum"] += 1
|
|
|
|
return
|
|
|
|
if ann["seqnum"] <= old_ann["seqnum"]:
|
|
|
|
self.log("not replacing old ann, new seqnum is too old"
|
|
|
|
" (%s <= %s) (replay attack?)"
|
|
|
|
% (ann["seqnum"], old_ann["seqnum"]),
|
|
|
|
level=log.UNUSUAL, umid="sX7yqQ")
|
|
|
|
self._debug_counts["inbound_old_replay"] += 1
|
|
|
|
return
|
|
|
|
# ok, seqnum is newer, allow replacement
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self.log("old announcement being updated", level=log.NOISY,
|
|
|
|
umid="304r9g")
|
2009-06-23 02:10:47 +00:00
|
|
|
self._debug_counts["inbound_update"] += 1
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self._announcements[index] = (ann_t, canary, ann, time.time())
|
|
|
|
#if canary:
|
|
|
|
# canary.notifyOnDisconnect ...
|
|
|
|
# use a CanaryWatcher? with cw.is_connected()?
|
|
|
|
# actually we just want foolscap to give rref.is_connected(), since
|
|
|
|
# this is only for the status display
|
2009-06-23 02:10:47 +00:00
|
|
|
|
2008-06-18 19:24:16 +00:00
|
|
|
for s in self._subscribers.get(service_name, []):
|
2009-06-23 02:10:47 +00:00
|
|
|
self._debug_counts["outbound_message"] += 1
|
|
|
|
self._debug_counts["outbound_announcements"] += 1
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
self._debug_outstanding += 1
|
|
|
|
d = s.callRemote("announce_v2", set([ann_t]))
|
|
|
|
d.addBoth(self._debug_retired)
|
2009-06-23 02:10:47 +00:00
|
|
|
d.addErrback(log.err,
|
|
|
|
format="subscriber errored on announcement %(ann)s",
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
ann=ann_t, facility="tahoe.introducer",
|
2009-06-23 02:10:47 +00:00
|
|
|
level=log.UNUSUAL, umid="jfGMXQ")
|
2008-06-18 19:24:16 +00:00
|
|
|
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
def _attach_stub_client(self, ann, lp):
|
|
|
|
# There might be a v1 subscriber for whom this is a stub_client.
|
|
|
|
# We might have received the subscription before the stub_client
|
|
|
|
# announcement, in which case we now need to fix up the record in
|
|
|
|
# self._subscriptions .
|
|
|
|
|
|
|
|
# record it for later, in case the stub_client arrived before the
|
|
|
|
# subscription
|
|
|
|
subscriber_info = self._get_subscriber_info_from_ann(ann)
|
|
|
|
ann_tubid = get_tubid_string_from_ann(ann)
|
|
|
|
self._stub_client_announcements[ann_tubid] = subscriber_info
|
|
|
|
|
|
|
|
lp2 = self.log("stub_client announcement, "
|
|
|
|
"looking for matching subscriber",
|
|
|
|
parent=lp, level=log.NOISY, umid="BTywDg")
|
|
|
|
|
|
|
|
for sn in self._subscribers:
|
|
|
|
s = self._subscribers[sn]
|
|
|
|
for (subscriber, info) in s.items():
|
|
|
|
# we correlate these by looking for a subscriber whose tubid
|
|
|
|
# matches this announcement
|
|
|
|
sub_tubid = subscriber.getRemoteTubID()
|
|
|
|
if sub_tubid == ann_tubid:
|
|
|
|
self.log(format="found a match, nodeid=%(nodeid)s",
|
|
|
|
nodeid=sub_tubid,
|
|
|
|
level=log.NOISY, parent=lp2, umid="xsWs1A")
|
|
|
|
# found a match. Does it need info?
|
|
|
|
if not info[0]:
|
|
|
|
self.log(format="replacing info",
|
|
|
|
level=log.NOISY, parent=lp2, umid="m5kxwA")
|
|
|
|
# yup
|
|
|
|
s[subscriber] = (subscriber_info, info[1])
|
|
|
|
# and we don't remember or announce stub_clients beyond what we
|
|
|
|
# need to get the subscriber_info set up
|
|
|
|
|
|
|
|
def _get_subscriber_info_from_ann(self, ann): # for_v1
|
|
|
|
sinfo = { "version": ann["version"],
|
|
|
|
"nickname": ann["nickname"],
|
|
|
|
"app-versions": ann["app-versions"],
|
|
|
|
"my-version": ann["my-version"],
|
|
|
|
"oldest-supported": ann["oldest-supported"],
|
|
|
|
}
|
|
|
|
return sinfo
|
|
|
|
|
|
|
|
def remote_subscribe(self, subscriber, service_name): # for_v1
|
|
|
|
self.log("introducer: old (v1) subscription[%s] request at %s"
|
|
|
|
% (service_name, subscriber), umid="hJlGUg")
|
|
|
|
return self.add_subscriber(WrapV1SubscriberInV2Interface(subscriber),
|
|
|
|
service_name, None)
|
|
|
|
|
|
|
|
def remote_subscribe_v2(self, subscriber, service_name, subscriber_info):
|
|
|
|
self.log("introducer: subscription[%s] request at %s"
|
|
|
|
% (service_name, subscriber), umid="U3uzLg")
|
|
|
|
return self.add_subscriber(subscriber, service_name, subscriber_info)
|
|
|
|
|
|
|
|
def add_subscriber(self, subscriber, service_name, subscriber_info):
|
2009-06-23 02:10:47 +00:00
|
|
|
self._debug_counts["inbound_subscribe"] += 1
|
2008-06-18 19:24:16 +00:00
|
|
|
if service_name not in self._subscribers:
|
|
|
|
self._subscribers[service_name] = {}
|
|
|
|
subscribers = self._subscribers[service_name]
|
|
|
|
if subscriber in subscribers:
|
|
|
|
self.log("but they're already subscribed, ignoring",
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
level=log.UNUSUAL, umid="Sy9EfA")
|
2008-06-18 19:24:16 +00:00
|
|
|
return
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
|
|
|
|
if not subscriber_info: # for_v1
|
|
|
|
# v1 clients don't provide subscriber_info, but they should
|
|
|
|
# publish a 'stub client' record which contains the same
|
|
|
|
# information. If we've already received this, it will be in
|
|
|
|
# self._stub_client_announcements
|
|
|
|
tubid = subscriber.getRemoteTubID()
|
|
|
|
if tubid in self._stub_client_announcements:
|
|
|
|
subscriber_info = self._stub_client_announcements[tubid]
|
|
|
|
|
|
|
|
subscribers[subscriber] = (subscriber_info, time.time())
|
2008-06-18 19:24:16 +00:00
|
|
|
def _remove():
|
|
|
|
self.log("introducer: unsubscribing[%s] %s" % (service_name,
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
subscriber),
|
|
|
|
umid="vYGcJg")
|
2008-06-18 19:24:16 +00:00
|
|
|
subscribers.pop(subscriber, None)
|
|
|
|
subscriber.notifyOnDisconnect(_remove)
|
|
|
|
|
new introducer: signed extensible dictionary-based messages! refs #466
This introduces new client and server halves to the Introducer (renaming the
old one with a _V1 suffix). Both have fallbacks to accomodate talking to a
different version: the publishing client switches on whether the server's
.get_version() advertises V2 support, the server switches on which
subscription method was invoked by the subscribing client.
The V2 protocol sends a three-tuple of (serialized announcement dictionary,
signature, pubkey) for each announcement. The V2 server dispatches messages
to subscribers according to the service-name, and throws errors for invalid
signatures, but does not otherwise examine the messages. The V2 receiver's
subscription callback will receive a (serverid, ann_dict) pair. The
'serverid' will be equal to the pubkey if all of the following are true:
the originating client is V2, and was told a privkey to use
the announcement went through a V2 server
the signature is valid
If not, 'serverid' will be equal to the tubid portion of the announced FURL,
as was the case for V1 receivers.
Servers will create a keypair if one does not exist yet, stored in
private/server.privkey .
The signed announcement dictionary puts the server FURL in a key named
"anonymous-storage-FURL", which anticipates upcoming Accounting-related
changes in the server advertisements. It also provides a key named
"permutation-seed-base32" to tell clients what permutation seed to use. This
is computed at startup, using tubid if there are existing shares, otherwise
the pubkey, to retain share-order compatibility for existing servers.
2011-11-20 10:21:32 +00:00
|
|
|
# now tell them about any announcements they're interested in
|
|
|
|
announcements = set( [ ann_t
|
|
|
|
for idx,(ann_t,canary,ann,when)
|
|
|
|
in self._announcements.items()
|
|
|
|
if idx[0] == service_name] )
|
|
|
|
if announcements:
|
|
|
|
self._debug_counts["outbound_message"] += 1
|
|
|
|
self._debug_counts["outbound_announcements"] += len(announcements)
|
|
|
|
self._debug_outstanding += 1
|
|
|
|
d = subscriber.callRemote("announce_v2", announcements)
|
|
|
|
d.addBoth(self._debug_retired)
|
|
|
|
d.addErrback(log.err,
|
|
|
|
format="subscriber errored during subscribe %(anns)s",
|
|
|
|
anns=announcements, facility="tahoe.introducer",
|
|
|
|
level=log.UNUSUAL, umid="mtZepQ")
|
|
|
|
return d
|