A P2P Approach to SIP Registration and Resource Location
College of William and MaryDepartment of Computer ScienceP.O. Box 8795WilliamsburgVA23187USA+1 757 784 5601bryan@ethernot.orgCollege of William and MaryDepartment of Computer ScienceP.O. Box 8795WilliamsburgVAco
23187USAlowekamp@cs.wm.eduCisco Systems170 West Tasman DriveMS: SJC-21/3San JoseCA95134USA+1 408 421 9990fluffy@cisco.com
Transport
SIPPING WGI-DInternet-DraftMime
This document outlines the motivation and requirements for a
Peer-to-Peer (P2P) based approach for SIP registration and resource
discovery using distributed hash tables, and presents the
architectural design for such a system.
This design removes the need for central servers from SIP, while offering
full backward compatibility with SIP, allowing reuse of existing
clients, and allowing P2P enabled nodes to communicate with
conventional SIP entities. A basic introduction to the concepts of P2P
is presented, backward compatibility issues addressed, and the security
considerations are considered.
This is very early work to explore the characteristics that a P2P
system might have. It is less secure in many ways than the traditional
approach to SIP but has certain other interesting characteristics that
may make it desirable in some situations. This work is being discussed
on the p2psip@cs.columbia.edu mailing list.
As SIP and SIMPLE based Voice over IP
(VoIP) Instant Messaging (IM)
systems have increased in popularity, situations have emerged where
centralized servers are either inconvenient or undesirable. For
example, a group of users wishing to communicate between each other,
but using machines that are not consistently connected to
the network are often forced to use a central server that is outside
the control of the group. Similarly, groups wishing to establish
ephemeral networks for use in meetings, conferences, or classes often
do not wish to configure a centralized server. Organizations may also
want to allow their members to communicate with each other without
traffic flowing to third parties, but may not have the staff or
equipment to maintain a server.
Peer-to-Peer (P2P) computing has emerged as a mechanism for completely
decentralized, server-free implementations of various applications. This
draft presents a SIP based system that uses P2P mechanisms to
remove the need for central servers in SIP and SIMPLE based
communications systems. This draft derives from work done on the
SoSIMPLE P2P SIP project.
In this document, the key words "MUST", "MUST NOT", "REQUIRED",
"SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT
RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described
in RFC2119.
Terminology defined in RFC
3261 is used without definition.
Terms relating to P2P or new to this document are defined when used and
are also defined in the Definitions section
of this document.
In many places in this document, 10 hexadecimal digit values are used
in examples as SHA-1 hashes. In reality, these hashes are 40
digit. They are shortened in this document for clarity only.
The fundamental principle behind Peer-to-Peer
(P2P) Architectures is that each and every member of the
network has equal importance in the transactions that
take place on the network, and that these nodes communicate with each
other to accomplish tasks. Contrast this with the
more traditional Client-Server Architecture in which a large number of
clients communicate only with a small number of central servers
responsible for performing tasks.
Each entity that participates in a P2P
system, usually called a node or peer,
provides server-like functionality and services as well as
being a client within the system. In this way, the services or
resources that would be provided by a centralized entity are instead
available from the nodes of the system. Note that a
particular node may or may not provide a particular service, but some
node does, ensuring that collectively the nodes can provide that
particular service.
The logical network connecting the peers to one
another is referred to as an overlay network or overlay,
as it is in
some sense a new, small sub-network at a higher logical level than
lower level network connections.
Some P2P networks have
certain nodes that provide a higher level of functionality. Often
these nodes form a P2P network and connect to each other, then serve a
number of true clients. These more powerful nodes are often referred to
as super-nodes. This approach is often used to traverse NATs,
with nodes residing outside of the NATs serving as super-nodes, and to
allow nodes with more bandwidth to serve as concentrators for information.
Many P2P systems further assume that nodes are ephemeral in nature. A
node may join or leave the overlay at any time. The design of
algorithms for P2P architectures take this into account. Information is
often replicated, and the topology of the overlay can be quickly
adapted as nodes enter and leave.
Likely the best known (or perhaps most infamous) use of P2P
technology is file sharing. In these systems,
individual users store files, and join the overlay network by
connecting to a small number of nodes already in the overlay. When the
user wishes to locate a particular file they don't have, they
contact these neighbors. Several alternatives exist
for this query. In early systems, a node searching for a file would
ask their neighbors if they had the file. If one of these nodes had
the file, it would respond telling the requester they had the file.
If not, they passed the request on to their neighbors.
The search was limited to a particular depth using a Time to Live
(TTL) mechanism, but since nodes had no idea what other nodes were
doing, queries continued until the TTL was reached, even if some node
had already replied. This approach, often called the
flood search approach, proved inefficient.
To improve the efficiency, most newer systems locate resources using a
Distributed Hash Table, or DHT.
Nodes are organized using a Distributed Hash Table (DHT)
structure. In such a system, every resource has a Resource-ID, which
is obtained by hashing some keyword or value that uniquely identifies the
resource. Resources can be thought of as being stored in a
hash table at the entry corresponding to their
Resource-ID. The nodes that make up the overlay network are also
assigned an ID, called a Node-ID, which maps to the same hash space as
the Resource-IDs. A node is responsible for storing all resources that
have Resource-IDs near the node's Node-ID.
The hash space is divided up so that all of the hash space
is always the responsibility of some particular node, although as nodes enter
and leave the system a particular node's area may change. Messages are
exchanged between the nodes in the DHT as the nodes enter and leave to
preserve the
structure of the DHT and exchange stored entries.
Various DHT implementations may visualize the hash space as a grid,
circle, or line.
Nodes keep information about the location of other nodes in the hash
space and in general know about most nodes nearby in the hash space,
and progressively fewer more distant nodes.
When a user wishes
to search, they consult the list of node they are aware of and
contact the node with the Node-ID nearest the desired Resource-ID.
If that node does not know how to find the resource, it either
suggests the closest node it knows about, or asks that node itself and
returns the result.
In this fashion, the request
eventually reaches the node responsible for the resource, which then
replies to the requester.
The Chord
system is one particular popular DHT algorithm.
Chord
uses a ring-type structure for the nodes in the overlay.
In this
structure, a node with a hash of 0 would be located adjacent to a node that
hashes to the highest possible hash value. If the hash has 2^n bits
in the range, each node will keep a "finger table" of pointers to at
most n other nodes. The ith entry in the finger table contains a
pointer to a node at least 2^(i) units away in the hash space. These
highest finger table entry thus point to a range 1/2 of the way across
the hash space, the next highest 1/4, the next 1/8, and the smallest
entry points to a range only 1 away in the hash space. The set of
nodes pointed to by these finger table entries are referred to as the
neighbors of the node, since they can be reached directly.
Searching in Chord is accomplished by sending
messages to the node in the finger table that is
closest to the destination address. That neighbor will have
finer resolution detail about the area and can route the
message closer to the desired node. This process is repeated until
the message reaches the node responsible for the destination, which can
determine if the resource searched for is present.
This draft uses an algorithm derived from the Chord algorithm to
communicate between nodes in the DHT. Specifically, the algorithm
detailed in Chord Overlay Algorithm has been adapted to use
iterative searches rather than recursive searches in order to
minimize the potential for Denial-of-Service (DOS) attacks. Chord
is selected because of its simplicity, convergence properties, and
general familiarity within the P2P community. We anticipate that
other IETF working groups will be standardizing other DHT
protocols and expect that the protocol and principles described in
this draft will easily transfer to an alternative DHT algorithm.
We have included specification of the specific DHT algorithm
being used to support such transitions.
All P2P systems need to solve the problem of locating some initial
node in the overlay, often called a bootstrap node, in order to
join. Some approaches taken to solving this problem include using some
set of fixed nodes, requiring that a node be located using an offline
mechanism, or using a broadcast/multicast mechanism.
P2P architectures offer several advantages over centralized architectures. P2P
systems distribute resources across multiple machines, greatly reducing the
potential of failure due to a single node failing. This results in increased
robustness, as well as some measure of protection from Denial-of-Service (DOS)
attacks. P2P systems also have the advantage of scaling more easily as the
number of nodes increases, since each new node offers additional server-like
functionality when it joins. P2P systems have their own class of problems,
however. In particular, malicious nodes can provide incorrect information,
possibly denying access to resource in the system. Additionally, users can
sometimes create many nodes in the system, possibly using this as a mechanism
for hijacking the system. These type of attack is often referred to as a Sybil attack.
When referring to P2P systems in this document, we are referring to
what are called true P2P systems in the literature.
Some systems,
such as the original Napster system, as well as many existing SIP deployments
(which are occasionally referred to as P2P), are more properly
referred to as hybrid systems. In hybrid systems, nodes communicate
with each other to exchange information, but resource location is
still handled with a centralized server. Our goal in this document is
a system that requires no central server of any type.
In this section we provide an overview of how P2P SIP works. Protocol
details
are provided in the remainder of the document.
Unlike a conventional SIP architecture, P2P SIP systems require no
central servers.
In a
traditional SIP architecture many UAs connect to a central proxy
server. In a P2P SIP network the peers connect directly to a few
other peers, forming a virtual overlay network of peers which
communicate with each other to provide services in the overlay.
The nodes participating in the overlay not only act
as traditional SIP UAs, allowing their users to place and receive
calls, but, when viewed collectively with the other peers, perform the
roles of registrars and proxies in traditional SIP networks. These
roles include resource location, maintaining presence information, and
call routing. Each participating peer will maintain some fraction of
the information that would normally be maintained by the proxy and/or
registrar in a conventional SIP network.
P2P SIP nodes provide many functions, more than any single entity in a
traditional SIP architecture. Minimally, a participating peer must be
an active member of the overlay and must provide some SIP
"server-like" behaviors as well. The code that implements the
additional server-like and DHT behavior can be located in
several places in the network. The simplest is to have nodes that
are endpoints directly joining the overlay as peers.
In this case, these nodes provide the basic functionality
of any SIP endpoint, but additionally implement the operations
described in this document to enable self-organization and provide SIP
functionality.
The behavior can also be located in an adapter node,
which allow one or more non-P2P aware SIP UAs to
interact with the P2P overlay network. These adapters perform the
additional self-organizing and SIP server-like behavior on behalf of the
UA or UAs it supports. In this case, only the adapter node is a peer
in the overlay, the UAs are not peers themselves. All interaction
with the P2P network is carried out by the adapter node. The adapter
essentially acts as a proxy server for the unmodified SIP UAs. The
adapter can take the form of a small software shim, or may be code
within a traditional RFC 3261 server.
In most places in this document, which type of node we are discussing won't
affect the discussion. In those cases where it will, we have noted the
differences.
The P2P overlay consists of nodes, which collectively serve as a
directory service for locating resources (users, voicemail messages,
etc.).
Nodes are organized using a Distributed Hash Table (DHT) P2P
structure based on Chord.
Like Chord, the system uses consistent
hashing to a one dimensional namespace, conceptually in the form of a
circle. Unlike Chord, all the messages needed to maintain the DHT are
implemented as SIP messages. We use many Chord-like terms, which are
defined in the section Definitions and
Terminology.
Each node is assigned a Node-ID that determines the node's location
in the DHT ring and the range of resources for which it will store
location information. Node-IDs are created by hashing the IP
address and port of the node providing service. This creates some
security issues. See the Open
Issues section of this document for more information. We
allow for different algorithms to be used to calculate these hashes,
but all members of the overlay MUST use the same algorithm.
Every resource has a Resource-ID, obtained by hashing some keyword that
identifies the resource. The Resource-IDs map to the same space as the
Node-IDs. In the case of users, the unique keyword is the userid
and the resource is the registration -- a mapping between the user name and a
contact. Resources can be thought of as being stored in the distributed hash
table at a location corresponding to their Resource-ID.
Like Chord, a resource with Resource-ID k will be
stored by the first node with Node-ID equal to or greater (mod the
size of the namespace) than k,
ensuring that every Resource-ID is associated with some node.
As nodes enter and leave, resources may be stored on different nodes,
so the information related to them is exchanged as nodes enter and
leave. Redundancy is used to protect against loss of information in
the event of a node failure.
Each node keeps information about how to contact some number of other
nodes in the overlay. In terms of the overlay network, these are the
neighbors of the node, since they are reachable in one hop. The node
keeps track of its immediate predecessor node, as well as one or more
successor nodes. The node also keeps a table of information about
other neighbors called a finger table, consisting of nodes distributed
with exponential spacing around the overlay.
Messages are routed by taking advantage of a key property of these
finger tables. A node has more detailed, fine grained information
about nodes near it than further away, but it knows at least a few
more distant nodes.
When locating a resource with a particular Resource-ID, the node will
send the request to the finger table entry
with the Node-ID closest to the desired
Resource-ID. Because the node receiving the request has many
neighbors with similar Node-IDs, it will presumably know of a node
with a Node-ID closer to the Resource-ID, and suggests this node to in
response. The request is then resent
to this closer node. The process is repeated until the node
responsible for the Resource-ID is located, which can then determine
if it is storing the information.
This draft explores one possible protocol that can be used to
implement for P2P SIP. Our motivation throughout has been to preserve
the semantics of standard SIP messages to the extent possible.
All of the
messages that are needed to maintain the DHT, as well as those needed
to query for information are
implemented using SIP messages.
Fundamentally, messages are being
exchanged for two purposes. The purpose of the first class of messages
is to maintain the DHT, such as the messages needed to join or
leave the overlay, and to transfer information between nodes.
The second
type of messages are those used to allow the users of the overlay to
communicate. This second type of message is the type most SIP users
will be familiar with -- registering users, inviting other users to a
session, etc.
As the DHT is used as a distributed registrar, the
registration and other searches are performed within the DHT. Once
the target resource has been located, further communication proceeds
directly between the UAs (or designated adapter nodes) as with
traditional SIP communications.
The messages used to manipulate the DHT are SIP REGISTER messages.
RFC 3261, Section 10.2, specifies that REGISTER messages are used to
"add, remove, and query bindings." Accordingly, we have selected
REGISTER methods to use to add, remove, and query bindings. We use
REGISTER both for the bindings of hosts as neighbors in DHT
maintanence operations as well as the bindings of resource names to
locations that are commonly maintained by SIP registrars.
The previous version of this draft utilized INVITE to perform
searches within the DHT, with the guiding principle being that the
INVITE would be redirected until it reached that actual UA of the
desired contact. After further consideration, this use of INVITE
raised the problem that it might result in a DHT-based SIP operation
being sent to a simpler SIP device unaware of the SIP extensions.
By explicitly requiring DHT operations to be performed using
REGISTER operations, and the final end-to-end connection made in the
traditional SIP manner, we allow P2P-aware agents to deliberately
separate their interactions with other P2P-aware nodes from those
interactions that require only traditional SIP messages, and can be
performed with non-P2P agents.
While this draft explores a protocol that was designed with a
modification of the Chord algorithm in mind, we have attempted to
make the SIP communication general-purpose, such that it can be used
to implement a variety of overlay algorithms. Following these
intentions, we have separated the overlay-specific algorithms into a
Chord Overlay Algorithm section,
which describes how the basic P2P SIP operations can be used to
implement an iterative Chord algorithm. Our intention and hope is
that others will design other overlay algorithms that rely on the
same basic operations and are perhaps even optimizations of the
basic Chord algorithm so that compatibility can be maintained.
Furthermore, as other IETF working groups explore ideas for
standardizing P2P algorithms, we hope that the basic SIP messages
can remain consistent while only the overlay "module" needs to be
redesigned to reflect the new protocols.
When a node sends a message within the DHT, it begins by calculating
the target ID it is attempting to locate, which might be its own
location in the DHT, obtained by hashing its own IP address, or a
user's registration, for which it hashes the user's URI to obtain
the appropriate Resource-ID. It then consults its finger table for
the closest node it is aware of to the target ID. In the trivial
case of initial startup, the application may know only of a single
bootstrap node. The message is sent to that node, which performs
the requested operation if it is responsible for that ID. If the
contacted node is not responsible for the target ID, then the
contacted node issues a 302 redirect pointing the searching node
toward the best match the contacted node has for the target ID. The
searching node then contacts the node to which it has been
redirected, and the process iterates until the responsible node is
located.
When a node (the joining node) wishes to join the overlay, it
creates its Node-ID and
sends a REGISTER message to a
bootstrap node already in the overlay, requesting to join. Any node
in the DHT may serve as a bootstrap node, although we expect
that most UAs will be configured with a small number of well-known
nodes. Following the above routing scheme, the bootstrap node
looks up the node it knows nearest to the Node-ID of the joining node and
responds with 302 redirect to this nearer node. The joining node will repeat
this process until it reaches the node currently responsible for the space it
will occupy. The joining node then exchanges additional REGISTER messages with
this node, called the admitting node, to allow the joining node to learn about
other nodes in the overlay (neighbors) and to obtain information about resources
the joining node will be responsible for maintaining. Other messages will be
exchanged later to maintain the overlay as other nodes enter and leave, as well
as to periodically verify the information about the overlay, but once the
initial messages are exchanged, a node has joined the overlay.
The node registration does not register the node's user(s) or other
resources with the
P2P SIP network -- it has only
allowed the node to join the overlay.
Once a node has joined the overlay, the user that node hosts must be registered
with the system. This process is referred to as resource registration. This
registration is analogous to the traditional SIP registration, in which a
message is sent to the registrar creating a mapping between a SIP URI and a
user's contact. The only difference is that since there is no central registrar,
some node in the overlay will maintain the registration on the users
behalf.
Resource registrations are routed similarly to node registrations.
The resource's node calculates the resource-ID and contacts the node
it is aware of closest to the resource-ID. This search process
iterates using 302 redirects until the responsible peer is located.
This node then stores the registration for that user and returns a
200 response.
For redundancy, resources should also be registered at additional
nodes within the overlay. These replicas are located by adding a
replica number to the resource name and hashing to identify a new
resource-ID for each replica. In this way, replicas are located at
unrelated points around the DHT, minimizing the risk of an attacker
compromising more than one registration for a single resource.
Sessions are established by contacting the UA identified by the
registration in the DHT. The first step in establishing a session is
locating this node, which is done by searching for a resource in the
DHT. The name of the target resource is used to calculate a
resource-ID and a REGISTER message with no Contact information (a
conventional SIP search) is sent to the closest known node
to that resource-ID. The search iterates until the responsible peer
is located. The responsible node then returns either a 200 OK with
the Contact information for the resource or a 404 Not Found. The
session is then initiated directly with the resource's UA.
We create a new option tag "dht" as described in RFC 3261.
This option tag indicates support for DHT based
P2P SIP. Nodes MUST include a Require and
Supported header with the option tag dht for all messages that are
intended to processed in a P2P method or include P2P
extensions. Clients supporting P2P and contacting another SIP entity
using a non-P2P mechanism
for a transaction that may or may later be
P2P SHOULD include a Supported header with dht.
For a typical session establishment the search within the
DHT MUST specify Require dht, whereas the actual contact with the
resource's UA SHOULD include a Supported header with dht but SHOULD
NOT include a Require header with dht.
All IDs used for an overlay must be calculated using the same
algorithm. Implementations SHOULD use the SHA-1 algorithm, which
produces a 160 bit hash value. The Hash algorithm used is specified
in the DHT-NodeID header, described below. An implementation MAY rely
on a secret initialization vector, key, or other shared secret to use
the identifier as an HMAC, from RFC 2104
such that no node may join the overlay without
knowledge of the shared secret.
Node-IDs are determined by the algorithm being used. In the case of
sha1, <40 hex digit hash>. The Node-ID MUST be formed by taking
the IP address of the node, followed by a colon, followed by the port,
and hashing this string with the appropriate algorithm.
For sha1, the resulting Node-ID looks like
a04d371e3f4078a7a8c49bb7a4ea6199fc9d5c77.
The string hashed to obtain the NodeID is formally defined below as
ipport.
ipport = IPV4address ":" port
NodeID is formally defined as:
NodeID = token
When using sha1:
NodeID = 40LHEX
No special restrictions, beyond those imposed by RFC 3261, are imposed
on the resource URIs in a P2P SIP system. Note that various security
schemes, two of which are discussed in Protecting the Namespace may place
restrictions of their own on the user's URIs.
For reliability, redundant registrations are made for resources to
avoid certain forms of DOS attacks and guard against the loss of
information in case of node failure. The primary registration is
made using the canonical form of the resource's URI, but all replica
registrations are made by attaching a replica URI parameter to the
URI, with the value indicating the replica number, counting from
1. The replica parameter MUST NOT be included for the primary
registration. The replica URI parameter is of type other-param as
defined in RFC 3261.
replica-param = "replica=" %x31-39 ; 1-9
Resource-IDs MUST be formed by hashing the resource URI after
converting it to canonical form. To do that, all URI parameters MUST
be removed (including the
user-param) except for the replica URI parameter,
Any escaped characters MUST be converted to their
unescaped form. Formally:
ResourceID = token
When using sha1:
ResourceID = 40LHEX
Because hashing URIs to produce identifiers is a non-trivial cost, P2P
SIP messages are constructed including these values already
calculated. This is strictly as a courtesy to nodes processing
messages for this node, as it prevents them from having to hash the
URI again before routing. Identifiers provided in a message are a
courtesy only and MUST NOT be used when making any changes to the data
stored in an overlay, as they may be spoofed or incorrect. If the hash
parameter is used incorrectly for routing, this only affects the
transmitting node's user. If it is used to insert or modify stored
information, it can affect the system's integrity. Nodes MUST verify
the hash of all URIs before making changes that affect the
overlay.
A P2P SIP node is represented by constructing a URI with the NodeID
as the userinfo portion and the ipport of the node as the hostport
portion. Additionally, the URI parameter "user=node" MUST be used.
NodeURI = NodeID "@" hostport ";" user-param uri-parameters
Formally, the user=node parameter is defined by using the keyword
"node" of type token, serving as "other-user" in the definition of
user-param from RFC 3261. A node receiving a NodeURI MUST verify the
hash before using it to update its neighbors or finger table.
For search operations, where an identifier is being searched for,
but the host responsible for that identifier is unknown, hostport
SHOULD be set to "0.0.0.0". All non-search operations MUST specify a
valid hostport.
P2P node URIs MUST NOT
include the resource-ID URI parameter, as it is intended to define information
about resources that are stored in the overlay, not information about the nodes
making up the overlay. P2P node URIs used in name-addr SHOULD NOT include any
display-name information, and nodes receiving name-addrs for nodes with
display-name information MUST ignore the information.
Examples (using shortened Node-ID for clarity):
To: <sip:ed57487add@10.6.5.5;user=node>
Resource URIs are no different for P2P SIP resources than for non-P2P
SIP applications. However, because calculating the ResourceID is a
significant expense, the optional URI parameter
resource-ID=<Resource-ID> SHOULD be provided. This parameter is a
courtesy only and MUST NOT be used when making any changes to the data
stored in an overlay without being recalculated, as it may be spoofed
or incorrect. The resource-ID URI parameter is of type other-param as
defined in RFC 3261.
resourceID-param = "resource-ID=" ResourceID
P2P user URIs MUST NOT include the user=node URI
parameter, because this indicate that the target of the URI is a node.
P2P user URIs MAY include other user-parameters such as user=phone.
Examples (again using shortened Node-ID for clarity):
sip:bob@p2psip.org;resource-ID=723fedaab1
To: "Alice White" <sip:alice@p2psip.org>
We introduce a new SIP header called the DHT-NodeID header. This
header is used to express the Node-ID of the sending node as well as
to identify the name and parameters of the overlay. The format of the
DHT-NodeID header is as follows:
DHT-NodeID = "DHT-NodeID" HCOLON NodeURI SEMI algorithm SEMI
dht-param SEMI overlay-param *(SEMI generic-param)
Examples:
DHT-NodeID: <sip:a04d371e@192.168.1.1;user=node>;algorithm=sha1;
overlay=chat;expires=600
The hash algorithm used for the overlay is specified as a parameter
of the DHT-NodeID header. This parameter MUST appear in the
DHT-NodeID header. It MUST be the algorithm used to calculate all
NodeID and ResourceID values used in the message. It SHOULD NOT
appear in other headers in the message, but if it does it MUST match
the value in the DHT-NodeID header.
The hash algorithm is specified using the algorithm parameter from
RFC3261. The tokens used to identify the algorithm MUST be the same
as those used in other SIP documents such
as draft-ietf-sip-identity-06.
Currently, those consist of 'sha1', indicating SHA-1 as defined
in RFC 3174. Implementations SHOULD
use the SHA-1 algorithm for all implementations.
A node should reject a message with 488 Not Acceptable here if it
specifies a different hash algorithm than that used by the overlay in which the node is not participating. An
initial contact of a bootstrap node may specify the hash algorithm as the
wildcard "*", in which case the joining node indicates its
willingness to use whatever hash algorithm the bootstrap node identifies
in its response. A node responding to such a request MUST provide a
normal 302 forwarding response if all other elements of the message
are correct and the routing algorithm indicates such a response is
appropriate. If the normal response would be to allow the join with
a 200 OK, the receiving node MAY respond with a 302 redirect to
itself, in which case the joining node should reissue the message
with the proper hash algorithm specification.
Each overlay is named using a string, which SHOULD be unique to a
particular deployment environment. Nodes will use this value to
identify messages in cases where they may belong to multiple overlays
simultaneously. These are defined formally simply as a token:
overlay-name = "*" / token
The overlay-param parameter MUST appear in the DHT-NodeID header.
It SHOULD NOT appear in other headers in the message, but if it does
it MUST match the value in the DHT-NodeID header. This parameter is
defined formally as:
overlay-param = "overlay" EQUAL overlay-name
A node should reject a message with 488 Not Acceptable here if it
specifies an overlay in which the node is not participating. An
initial contact of a bootstrap node may specify overlay-name as the
wildcard "*", in which case the joining node indicates its
willingness to join whatever overlay the bootstrap node identifies
in its response. A node responding to such a request MUST provide a
normal 302 forwarding response if all other elements of the message
are correct and the routing algorithm indicates such a response is
appropriate. If the normal response would be to allow the join with
a 200 OK, the receiving node MAY respond with a 302 redirect to
itself, in which case the joining node should reissue the message
with the proper overlay specification.
The routing algorithm used to implement the overlay is specified
using a dht-param in the DHT-NodeID header. It SHOULD NOT appear in
other headers in the message, but if it does it MUST match the value
in the DHT-NodeID header. This parameter is defined formally as:
dht-name = token
dht-param = "dht" EQUAL dht-name
The behavior of a node receiving a message with a dht-param
specifying a routing algorithm other than that which it is following
is dependent on the routing algorithm. New routing algorithms
SHOULD be designed to maintain backward compatibility with previous
algorithms where possible. If the routing algorithm specified is
incompatible, a 488 Not Acceptable Here response should be returned.
The DHT-NodeID header MAY include an Expires parameter indicating
how long a recipient may keep knowledge of this node in a finger
table. If not present, a default of 3600 is assumed. Mobile nodes
may wish to specify a shorter interval.
We introduce a new SIP header called the DHT-Link header. The DHT-Link
header is used to transfer information about where in the DHT other
nodes are located. In particular, it is used by nodes to pass
information about the predecessor, successors, and finger table
information stored by a node.
DHT-Link = "DHT-Link" HCOLON NodeURI SEMI link-param SEMI
expires-param *(SEMI generic-param)
link-param = "link" EQUAL linktype-token depth-token
depth-token = 1*DIGIT
linktype-token = "P" / "F" / "S" / other-token
expires-param = "expires" EQUAL delta-seconds
and an example, the header might look like (using a shortened 10 digit
Node-ID for clarity):
DHT-Link: <sip:671a65bf22@192.168.0.1;user=node>;link=S1;expires=600
The linktype and depth values are dependent on the DHT
routing algorithm employed by the node. For the algorithm described
in Section Chord Overlay Algorithm,
the linktype MUST be one of three single characters,
P, S, or F. P MUST be used to indicate that the information provided
describes a predecessor of the sending node. S MUST indicate that
the information describes a successor node, and F MUST indicate that
it is a finger table node from the sending node.
For the algorithm in Chord Overlay Algorithm,
the depth MUST be a non-negative integer representing which
predecessor, successor, or finger table entry is being described. For
predecessors and successors, this MUST indicate numeric depth. In other words,
"P1" indicates the nodes immediate predecessor, while "S5" would indicate the
fifth successor. "P0" or "S0" would indicate the sending node itself. In the
case of finger table entries, the depth MUST indicate the exponent of the
offset. Since finger tables point to ranges in the hash table that are offset
from the current node in the hash space by a power of two. That is, finger table
entry i points to a range that begins with a node 2^i away in the hash space,
and there are a maximum of k finger table entries, where k is the size of the
hash result in bits. For an finger table entry, the depth corresponds
to this exponent i. In other words, "F0" would correspond to a finger table
entry pointing to the node for a range starting a distance 2^0 = 1 from the
Node-ID in the hash space, while "F6" would point to node used to search for
resources in a range starting 2^6 = 64 away from the Node-ID in the hash space.
Each DHT-Link header MUST contain an expires parameter. Each node
maintains an expiration time for each of its neighbor and finger
table entries. These expiration times are updated whenever the node
receives a response with a longer expiration time than it currently
maintains, most commonly in the NodeID header of a response to a
join or search. A node MUST NOT report an expired entry in a
DHT-Link header. A node MUST update the expires parameter with the
current value, adjusted for passed time, each time it generates a
DHT-Link header.
The SIP REGISTER message is used extensively in this system. REGISTER
is used to register users, as in conventional SIP systems, and we
discuss this further in the Resource Registration
section of this document. Additionally, SIP REGISTER messages are
used to register a new node with the DHT and to transmit the
information needed to maintain the DHT.
When a node wishes to join an existing overlay, it must first locate some node
that is already participating in the overlay. referred to as
the bootstrap node. Nodes MAY use any method they choose to locate the
initial bootstrap node. The following are a few of many methods that
may be used:
Some number of nodes in the overlay may be persistent, and have well
know addresses. These address could be configured into the node
application, or obtained using an out-of-band mechanism such as a web page.
While this mechanism cannot be used the first time that a node runs,
on subsequent attempts to join the overlay, a node might attempt to
use a previously contacted peer as a bootstrap node.
Nodes can use a broadcast mechanism to locate the initial
peer, for example by sending the first REGISTER message to the SIP
multicast address.
In the rest of this section, we assume that the joining node is not
the first node, and that a bootstrap node has been located.
After a node has located an initial bootstrap node, the process of joining the
overlay is started by constructing a REGISTER message and sending it
to the bootstrap node. Third party registration MAY NOT be used for
registering nodes into the overlay, and attempts to do so MUST be
rejected by the node receiving such a request. (although third party
registrations are used for other purposes, as described below)
The node MUST construct a SIP REGISTER message following
the instructions in RFC3261, section 10, with the exceptions/rules
outlined below.
The Request-URI SHOULD include only the IP address of the node that is
being contacted (initially the bootstrap node). This URI SHOULD NOT
include any of the P2P defined parameters. For example, a request
intended for node 10.3.44.2 should look like:
"REGISTER sip:10.3.44.2 SIP/2.0".
The To and From fields of the REGISTER message MUST contain the URI of
the registering node constructed according to the rules in the subsection
Node URIs in the Message Syntax
section.
While using the IP address of the sender for To and From is different
than traditional SIP registers, there
are two reasons for this. First, in a P2P network, which node the
request is sent to, and thus the domain for which the registration is
intended, is not important. Any node can process the information, and
the user name is not associated with a particular IP address or DNS
domain, but rather with the overlay name, which is encoded
elsewhere. In that sense, the IP address used is irrelevant. Choosing
the domain of the sender ensures that if a request is sent to a
non-P2P aware registrar RFC 3261 compliant registrar, it will be
rejected. RFC 3261 (section 10.3) states that a registrar
should examine the To header to determine if it presents a valid
address-of-record for the domain it serves. Since the IP address of
the sending node is unlikely to be a valid address for a non-P2P aware
registrar, the message will be rejected,
eliminating possibly erroneous handling by the registrar.
The registering node MUST also list its NodeURI in the contact field when registering so that this
may be identified as a registration/update, rather than a query.
The node MUST provide an expires parameter or expires header with a
non-zero value. As in
standard SIP registrations, Expire headers with a value of zero will
be used to remove registrations.
The registering node MUST provide a DHT-NodeID header field. It MAY
leave the overlay parameter set to "*" for its
initial registration message, but MUST set this parameter to the name
of the overlay it is joining as soon as it receives a response from
the bootstrap node.
The registering node MUST include Require and Supported headers with the option
tag "dht".
Assume that a node running on IP address 10.4.1.2 on port 5060
attempts to join
the network by contacting a bootstrap node at address
10.7.8.129. Further assume that 10.4.5.23:5060 hashes to 463ac4b449
under sha1 (using a 10 digit hash for example simplicity), and
that the overlay name is chat.
An example message would look like this (neglecting tags):
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;
overlay=chat;expires=600
Require: dht
Supported: dht
]]>
The receiving node determines that this is a P2P SIP message
based on the presence of the dht Require and Supported fields. In the
event that the node does not support P2P extensions, it MUST reply
with a 5xx class response such as 501 Not Implemented.
If the node examines the overlay parameters and determines that this
is not an overlay the node participates in, the node MUST reject the
message with a 488 Not Acceptable Here response. In the event a P2P
node receives a non-P2P request, it SHOULD reject it with a message
such as 421 Extension Required.
The
presence of user=node URI parameter in the To and Contact headers and a valid expiration time
indicate that this
message is a node registration and the receiving node MUST process this
as a DHT level request.
The bootstrap node SHOULD verify that the hashed Node-ID
corresponds to the IP address specified in the URI by hashing the IP
address and port and comparing it to the Node-ID. If these do not
match, the message should be rejected with a response of 493 Undecipherable.
The bootstrap
node examines the Node-ID to determine if it corresponds to the
portion of the overlay the bootstrap node is responsible for. If it
does, the node will handle the REGISTER request itself, if not, it
will provide the joining node with information about a node closer to
the area of the overlay where the joining nodes Node-ID is stored.
If the receiving node is not responsible for the area of the hash
table where Node-ID should be stored, the node MUST generate a 302
message. Nodes SHOULD NOT proxy the request, as described in
RFC3261:10.3, item1. (although they could, it would place undue burden
on a peer to ask it to do so, so we advise against it)
The 302 is constructed following the rules of RFC 3261 with the
following rules. The receiving node MUST look up
the node in its finger table nearest the joining node's Node-ID, and
use it to create a contact field in the form of a node URI, as
specified in the P2P Node URIs
section of this document, including appropriate URI parameters. The
response MUST contain a valid DHT-NodeID header. This response is sent to
the joining node.
Using our example register from the previous section, assume that
bootstrap node 10.7.8.129 receives the message, determines it is not
responsible for that area of the overlay, and redirects the joining
node to a node with Node-ID 47e46fa2cd at IP address 10.3.1.7. The 302
response, again neglecting tags, is shown below. Note that the node
creating the response uses its information to construct the DHT-NodeID header.
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;
overlay=chat;expires=600
Require: dht
Supported: dht
]]>
Upon receiving the 302, the joining node uses the contact
address as the new bootstrap node. The process is repeated until
the node contacted is currently responsible for the area of the DHT in
which the new node will reside.
The receiving
node that is responsible for that portion of the overlay is
referred to as the admitting node.
The admitting node MUST verify that the Node-ID hash of the IP address
is valid, as described above. If these do not
match, the message should be rejected with a response of 493 Undecipherable.
The admitting node
recognizes that it is presently responsible for this region of the hash
space -- that is, it is currently the node storing the information
that this Node-Id will eventually be responsible for. The admitting
node knows this because the joining node's Node-ID falls between the
Node-ID of the admitting node and its predecessor.
The admitting node is responsible for helping the joining
node become a member of the overlay. In addition to verifying that the
Node-ID was properly calculated, the admitting node MAY require an
authentication challenge to the REGISTER message. Once any challenge
has been met, the admitting will reply with a 200 OK message to the joining
node. As in a traditional registration, the Contact in the 200 OK will
be the same as in the request, and the expiry time MUST be provided.
The admitting node MUST reply with a 200 response if the joining node
has a Node-ID between the admitting node's Node-ID and the admitting
node's predecessor's Node-ID. The admitting node must populate the
DHT-Link headers with all values required by the routing protocol so
that the joining node can initialize its neighbors and finger table
entries. Additionally, the admitting node MUST include its DHT-NodeID
header containing the admitting node's Node-ID and IP.
For further details of the contents of the link headers and the
joining node processing, see Chord
Admission Processing.
Continuing the example register from the previous sections, assume now
that the node with Node-ID 47e46fa2cd and IP address 10.3.1.7 is
currently responsible for 463ac4b449 in the namespace. The admitting
node here does send the fingertable, but we show only the first entry
entry for clarity. We also omit the additional successors used to
support redundancy for clarity. The response would look something like:
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;
overlay=chat;expires=600
DHT-Link: ;link=P1;expires=412
DHT-Link: ;link=S1;expires=816
DHT-Link: ;link=F2;expires=121
Require: dht
Supported: dht
]]>
Both the admitting node and joining node SHOULD immediately perform
both a stabilize and fix fingers
operation to stabilize the overlay.
As with traditional SIP, REGISTER messages that are sent without a
Contact: header are assumed to be queries, as described in Section 10
of RFC3261. This corresponds to the find_successor operation in Chord.
The node looks for the finger table entry that covers the range they
wish to search. If the finger table entry has not yet been filled (and
the node was not provided another finger table to use to get started),
then the node may send the request to any node it has available,
including their successor, predecessor, or even some bootstrap
node. While these initial searches may be less efficient, they will
succeed. The Request-URI SHOULD include only the IP address of the
node that the search is intended for. This URI SHOULD NOT
include any of the P2P defined parameters. For example, a request
intended for node 10.3.44.2 should look like:
"REGISTER sip:10.3.44.2 SIP/2.0".
Because this is a query, the sending node MUST NOT include a contact
header. The sender MUST NOT include an expires header.
The node MUST provide a DHT-NodeID header.
The node MUST include Require and Supported headers with the option
tag "dht".
Assume that a node running on IP address 10.4.1.2 on port 5060 wants
to determine who is responsible for Node-ID 4823affe45, and asks the
node with IP address 10.5.6.211
Further assume that the node uses sha1 (using a 10 digit hash for
example simplicity), and that the overlay name is chat.
An example message would look like this (neglecting tags):
From:
DHT-NodeID: ;algorithm=sha1;
overlay=chat;expires=600
Require: dht
Supported: dht
]]>
The To field of the REGISTER message MUST contain the NodeURI of the
identifier being search for, constructed according to the rules in the subsection
P2P node URIs in the Message Syntax
section. If a specific node is being sought, the NodeURI must specify
that IP address. If only the identifier is being searched for, then
hostport MUST be set to "0.0.0.0". The From URI MUST use the
searching node's NodeURI.
The receiving node determines that this is a P2P SIP message
based on the presence of the dht Require and Supported fields. In the
event that the node does not support P2P extensions, it MUST reply
with a 5xx class response such as 501 Not Implemented.
If the node examines the overlay parameters and determines that this
is not an overlay the node participates in, the node MUST reject the
message with a 488 Not Acceptable Here response. In the event a P2P
node receives a non-P2P request, it SHOULD reject it with a message
such as 421 Extension Required.
The
presence of user=node URI parameter and lack of an expiration time
indicate that this
message is a node query and the receiving node MUST process this
as a DHT level request. The receiving node SHOULD NOT alter any of its
internal values such as successor or predecessor in response to this
message, since it is a query. Otherwise, the message is processed
and routed as a node registration until the responsible node is
reached.
If the receiving node is responsible for the region that the search key
lies within, it MUST respond to the query.
If the receiving node's
Node-ID exactly matches the search key, it MUST respond with a 200 OK
message. If it is responsible for that region, but its Node-ID is not
the search key, it MUST respond with a 404 Not Found message. The
node MAY verify the Node-ID and IP address presented by the
querying node in the message.
If these do not
match, the message should be rejected with a response of 493 Undecipherable.
The reply that is constructed MUST provide information about the
receiving node's neighbors and finger table entries. For further
details of the contents of the link headers and the joining node
processing, see Chord Query
Processing.
Once admitted, the joining node MUST populate its finger table by
issuing queries for nodes with the appropriate identifiers. If the
admitting node provided finger table information, the joining node MAY
use this information to construct a temporary finger table, and use
this temporary table in the queries to populate the table. For more
information on populating the table,
see Chord Finger Table.
Because the joining node has split the area in the
hash space that the admitting node was responsible for, some portion of
these user registrations are now the responsibility of the joining
node, and these user registrations are handed to the joining node by
means of these user registrations.
These are third party registration. Third party registrations are
allowed for user registrations and arbitrary searches, but are
not allowed for node
registrations. These registrations are exactly the same as those
discussed in Registering and Removing User
Registrations, except that as they are third party
registration from a node, the From header contains the NodeURI of the
admitting node.
Nodes MUST send their registrations to their successor before leaving
the overlay, as described in the section above. Additionally, nodes
MUST unregister themselves with both their successor and predecessor. This
REGISTER is constructed exactly the same as one used to join, with
the following exceptions. The expires parameter or header MUST be
provided, and MUST be set to 0. DHT-Link headers must be provided, as
specified in Chord Graceful
Leaving.
When a request sent to any node fails, the user MUST perform searches
to update their pointers. If the failed request was sent to a node in
the finger table, than the searches discussed in Populating the Joining Node's Finger Table
should be performed for all intervals that rely on the failed node. If
the predecessor or successor node fails, a search for the predecessor
or successor's ID should be performed, and requests should should be
repeated, based on the predecessors and successors returned by these,
until the correct successor or predecessors are determined.
The DHT routing algorithm used in this protocol is based on Chord,
with adaptations to rely on iterative operations rather than recursive
operations. As this places the burden of an operation on the
searching or joining node, rather than on intermediate nodes, it is
more appropriate for an Internet protocol.
We anticipate other routing algorithms being developed that may
improve the performance, locality, or security of this algorithm.
For this reason, the Chord-specific portions of the protocol are
confined to this Section. The other elements of the protocl should
be equally relevant to any DHT-based P2P routing algorithm.
For this protocol, the dht-param token must be set to "ChordIter1.0"
A node starting an overlay for the first time need not do anything
special in order to construct the overlay. The node MUST initalize its
finger table such that all entries point to itself. The node MUST set
its successor (which is also the first entry of the finger table) to
itself, and MUST set its predecessor to NULL.
Chord recommends keeping a number of finger table entries equal to the
size in bits of the hash space, for example 160 for SHA-1.
These entries point to the first node at least
2^i away from the node, for 0 <= i <= 159, mod 2^160.
Essentially, the node divides the overlay hash circle up into
segments, the first being the segment from [0-2^0) away from the node,
the second being from [2^0-2^1), the third being from [2^1-2^2), etc.,
all the way to the segment from [2^158-2^159) away from node. It then
stores an entry in the finger table for the first node with a Node-ID
greater than or equal to the start of this interval. In this way, the
node has many entries pointing to nearby nodes, and less and less
entries about more remote nodes. These tables are populated when the
node joins the overlay, and are kept up to date by periodically
updating them.
We recommend that, while using the full SHA-1 hash algorithm, nodes
maintain less than the full 160 entries in the finger table, perhaps
16 entries for small networks, 32 for larger networks. As this effects
only the efficiency of the client, it is left to the implementor to
determine a useful value. Note that a client can easily store enough
finger table entries to exceed the maximum MTU size when transmitting
the full finger table. In this case, a client may need to reduce the
number of finger table entries reported in DHT-Link headers.
When handling an initial join from a node,
the admitting node MUST reply with a 200 response if the joining node
has a Node-ID between the admitting node's Node-ID and the admitting
node's predecessor's Node-ID. The admitting node MUST provide the
joining node with its current predecessor and successor in the
200. These MUST be placed placed in DHT-Link headers, as described in
The DHT-Link Header section of this
document. The predecessor MUST be transmitted in a DHT-Link header
using a type of P and a depth of 1.
The successor MUST be transmitted in a DHT-Link header
using a type of S and a depth of 1. All nodes SHOULD maintain 4
successors at all times for redundancy. The 200 SHOULD contain the next 4
successor nodes, for use in redundancy.
The joining node obtains the Node-ID and address of the admitting node
from the DHT-Node header, and the information about the admitting
node's predecessor from the DHT-Link P 1 header. The joining node MUST
set its successor to be the admitting node, and its predecessor to be
the admitting node's predecessor. The admitting node MUST set its
predecessor to be the joining node, and MUST obtain the information
from the DHT-Node header in the register request. The admitting node's
successor is unchanged.
The admitting node SHOULD send a copy of the entries in their
finger table to the joining node, using DHT-Link headers of the F
type. As the joining node will likely be nearby the
admitting node in the hash space (at least for an overlay with a
reasonable number of nodes), this finger table information can likely
improve the performance of the queries required to obtain a correct
finger table information. It is the responsibility of the joining node
to calculate and reconstruct the
intervals that the admitting would have based on the F parameters and
the Node-ID supplied in the 200. Note that providing the first finger
is optional, as it is (by definition) identical to the required
successor field.
A reply that is constructed to a query by the responsible node MUST provide the
current predecessor and successor in the 200 or 404 message.
These MUST be placed placed in DHT-Link headers, as described in
The DHT-Link Header section of this
document. The predecessor MUST be transmitted in a DHT-Link header
using a type of P and a depth of 1.
The successor MUST be transmitted in a DHT-Link header
using a type of S and a depth of 1. The 200 or 404 SHOULD contain the next 4
successor nodes, for use in redundancy.
Additionally, the replying node MUST include its DHT-NodeID header.
To populate the
finger table, a node must take its Node-ID and, by applying the
exponential offsets for each finger, calculate the
Resource-IDs corresponding to the start of each finger interval. See
the P2P Overlay Structure
subsection in the Overview
section of this document. The joining node then performs
a search for each of these start intervals, as described above.
The resulting Node-IDs/IPs are entered into the corresponding finger
table entries. This is analogous to the fix_fingers procedure in Chord.
When a node sends its unregister message to its successor and
predecessor, it MUST include DHT-Link headers
listing its predecessor and 4 successor nodes. This allows the nodes
receiving the requests to obtain the information needed to correct
their predecessor and successor nodes, as well as keep their successor
lists needed for redundancy current.
In order to keep the overlay stable, nodes must periodically perform
book keeping operations to take into account node
failures. Periodically (we suggest 60-360 seconds), nodes MUST perform
an arbitrary query for their current successor's Node-ID. The node
should examine the response from their successor. The predecessor
reported should be the node that made the request. If it is not, the
node MUST update their own successor with the predecessor returned,
and additionally MUST send a REGISTER to this node, structured as if the
stabilizing node had just entered the system. This will serve to
properly update the overlay. This is analogous to the notify procedure
in Chord.
Additionally, when this periodic stabilization takes place, the node
should perform searches as discussed in Populating the Joining Node's Finger Table
to ensure that the finger table is up to date.
Node failure is handled by the periodic stabilization and responses to
failed requests discussed above. 4-way redundancy registrations
ensures that unless 4 sequential nodes fail, registrations will not be lost.
When a resource is registered, the registering node SHOULD create
at least 2 redundant replicas to ensure the registry information is
secure in the DHT. The registering node is responsible for
maintaining these replicas along with the primary entry.
The most important element of resource operations within the P2P SIP
DHT is that they are performed exactly as if using a traditional SIP
registrar, except that the registrar responsibilities are
distributed among the DHT members.
When a node is in the overlay, it must register the contacts for users
and other resources
for which it
is responsible into the overlay. This differs from the
registrations described above in that these registrations are
responsible for entering a URI name to URI location mapping (with a specific
IP address) into the overlay as
data, rather than joining a node into the overlay. These registrations
are very similar to those outlined in section 10 of RFC3261.
The Request-URI that is constructed for the REGISTER MUST be addressed to the
node the request is sent to. The To and From fields of the REGISTER message
MUST contain the Resource URI of the resource being registered, as
described in Resource URIs.
The request MUST include the value dht in Require and Supported
headers. The request MUST include a DHT-NodeID header and MAY include
one or more DHT-Link headers.
The resource registration must include at least one Contact header
containing a location of the resource and allowing this
to be identified as a registration/update, rather than a query. The
node MUST provide an expires parameter or an
Expire header with a non-zero value. As in
standard SIP registrations, Expires parameters with a value of zero will
be used to remove registrations. Any valid Contact for RFC 3261 is
valid Contact for P2P SIP. Most users will register a Contact with
the address of the user's UA (which may or may not be the IP
address of the node, since the node could be an adaptor node). The
Contact URI does not need to include the ResourceID or other P2P SIP
parameters as it is stored in the DHT but not processed or routed
by it in any way.
The message is routed in a fashion exactly analogous to that described in
the section on node registration. 302 messages
are sent to indicate that the message is to be redirected to another node (this
contact should contain the URI parameter user=node). Once the message arrives at
a destination that is responsible for that portion of the hash namespace, the
node recognizes it as a resource registration, rather than a node wishing to join
the system, based upon the fact that the To and From fields do not contain
user=node parameters. The node responds with a 200 indicating a
successful registration. The response is constructed as dictated by
RFC3261.
The registering node SHOULD construct and register replica
registrations using the same Contact headers, but with the replica URI
parameter used in the To and From headers.
Resource registrations are refreshed exactly as described in RFC 3261,
Section 10. Responsible nodes should send a new registration with a valid
expiration time prior to the time that the registration is set to
expire.
Agents MAY cache the address where they previously registered and
attempt to send refreshes to this node, but they are not guaranteed
success, as a new node may have registered and may now be responsible
for this are of the space. In such a case, the node will receive a 302
from the node with which they previously registered, and should follow
the same procedure for locating the node they used in the initial
registration.
As with initial registrations, the sending node should use the
successors provided in the 200 to send these updates to the redundant
nodes as well.
Resource registrations are removed exactly as described in RFC 3261,
Section 10. Responsible nodes MUST send a registration with expiration time of
zero.
As with initial registrations, the sending node SHOULD construct
replica unregister messages and use these to unregister the replicas.
Resource queries are constructed as described in RFC 3261,
Section 10. Querying nodes should send a registration with no contact
header. As described in Node
Search, this mechanism can also be used to locate the
node responsible for a particular Resource-ID.
A P2P environment can do little to protect against an individual node
compromising the registrations it is responsible for. Accordingly, a
UA cannot trust a response from a single node, whether it indicates a
successful search or an error. In the absence of other methods of
verifying the response (such as having a certificate of the user being
searched for and a signed registration that can be verified with the
certificate) a UA should search for the primary registration and at
least one replica. Because the locations the replicas are stored are
unrelated to the location of the primary registration, a single
attacker is unlikely to be able to compromise both entries. As the
overlay gains more nodes and more replicas are searched for, the odds
of a compromise are reduced.
When a caller wishes to send a SIP message (such as an INVITE or MESSAGE
message to start a conversation, or a subscribe message to create a
presence relationship with another user), the user must first locate the
node where this called's information resides using the resource search
procedure described in the section titled Resource Location.
Establishing a session is done entirely in the normal SIP fashion
after the user is located using the P2P resource query.
Once the node responsible for the Resource-ID is located, it will
provide either a 200, providing a contact for the users UA, or will
provide a 404 if the user is not registered. If a 200 with a valid
contact is received, the call will then be initiated directly with the
UAS of the called using the standard RFC 3261
fashion for methods such as INVITE or MESSAGE.
We use SUBSCRIBE/NOTIFY for this. We subscribe to every node on our
buddy list when we come online. If the user's are online, that means
that we know exactly where they are. Nodes SHOULD use their buddies as
additional "finger table" entries (essentially, cached values),
consulting these first, as
connections are likely to be made to people on the users buddy
list. These should also be periodically checked, as described in the
Periodic Stabilization section.
If buddies are offline, one should periodically try to make the connection.
Alternately, we use the same register mechanism that is used at node-join time
to let nodes we are here, rather than forcing them to do periodic subscribes.
If a UA receives a SUBSCRIBE from some buddy that is currently offline, it
SHOULD attempt to subscribe to that buddy. This will allow people that are
reciprocally on each others buddy lists to rapidly be notified when one or the
other comes online.
Delivery of messages to offline users, or voicemail for voice
applications, requires storing that information for later retrieval.
Storing user configuration information in a format accessible from
the network also will allow a user to retrieve their profile from
any computer. Cao et al,
describe an approach that
separates the storage of resource location information from the
actual storage of the offline research. We believe that this
approach is in agreement with the approach taken by the rest of this
document, which relies on the DHT overlay to store the registrar's
location information, but relies on external, traditional methods
for the actual connection. For offline storage, it also allows the
use of other standard protocols to store and retrieve the offline
information, keeping the P2P SIP scope restricted to storing
resource mappings.
For our examples, we use a simplified network. Rather
than use a full SHA-1 hash, and the resulting 2^160 namespace, we
instead use a smaller 4 bit hash, leading to a namespace of size
16. All hash results in our examples are contrived. We list the
Node-ID and Resource-IDs as xx, where xx is a number between 0
and 15 (2^4 namespace). In a real situation, the full 40 hex chars
would be used. Additionally, because the number of finger table
entries is so small in this case, we use the full 4 entries, where in
a real case we suggest that one uses less than the number of bits in
the namespace.
The empty overlay can be visualized as a circle with 16 possible
vacant points, each corresponding to one possible location in the hash
space. On the left, we have labeled these locations in the hash space as 0-15,
starting in the upper left, and have used 0s to indicate vacant spaces
in the hash space. On the right, we show the same network with 3
operating nodes, denoted by capital Ns, with Node-IDs of 3,
5, and 10. We will use this
sample network state as the starting point for all our networks:
Further, for the sake of example simplicity, assume the node Node-ID 3 has IP
address 10.0.0.3, the node node with Node-ID 5 has IP address 10.0.0.5,
etc.
Data that hashes to a Resource-ID is stored by the next node whose
Node-ID is equal to or larger than the Resource-ID, mod the size of
the hash. As such, Node 3 is responsible for any resources hashing
from 11-15, as well as 0-3. Node 5 is responsible for resources with
Resource-IDs from 4-5, and Node 10 is responsible for resources with
Resource-IDs from 6-10. From this illustration, you follow a location
clockwise until you encounter a node, and this is the node responsible
for storing the information. This is illustrated below:
Finger tables give pointers to nearby nodes. For our system, with 4
bit identifiers, we have 4 finger table entries. These finger tables
point to the node nearest to Node-ID + 2^0, Node-ID + 2^1, Node-ID +
2^2 and Node-ID + 2^3. If no node is present at that location, the
next available node will be used. Thus, for our 3 nodes, the finger
tables look like the following, with ranges (indicated in traditional
mathematical form) mapping to the node those requests will be sent to:
5 [6,7) -> 10 [11,12) -> 3
2^1 Entry [5,7) -> 5 [7,9) -> 10 [12,14) -> 3
2^2 Entry [7,11) -> 10 [9,13) -> 10 [14,2) -> 3
2^3 Entry [11.3) -> 3 [13,5) -> 3 [2,10) -> 3
]]>
Assume further our sample network is called sipchat, and that 2 users
are currently registered. User alice has a Resource-ID of 5, so her
registration information is stored at node 5. User bob is also
registered, and has a Resource-ID of 12, so his registration
information is stored by node 3. Assume further that bob's UA is
co-located with Node 10, so his contact is sipchat/bob@10.10.10.10, and that
alice is running a UA on a completely separate IP of 10.99.99.99, but
is using an adapter node running on Node 3, therefore Node 3 will send
messages on alice's behalf, but alice's contact is sipchat/alice@10.99.99.99.
In each of the examples below, we assume we start from the network
described above. Changes to the example network from previous examples
are discarded.
Note that for simplicity we do not show user registration redundancy
in any examples. This includes responses -- we only send predecessor
and successor, as well as finger table -- not redundant successors.
Assume a new node wishes to join the system. The node has an IP
address of 10.0.0.14, which we shall assume hashes to a Node-ID of
14. From an out of band mechanism, this node discovers node 5. This
node constructs a REGISTER as described in Node Registration , and sends it to
node 5. Node 5 verifies that 10.0.0.14 hashes to 14, then checks to
see if it controls that portion of the namespace. Since it does not,
it looks up in its finger table where it would route a search for 14,
and determines it would send it to node 3. The node then sends a 302
back to node 14, with a contact of node 3.
Node 14 the constructs a new REGISTER and sends it to Node 3. Again,
Node 3 verifies the hash, and determines it is currently responsible
for 14 in the hash space. After an optional challenge, it replies with
a 200 OK message to admit the node to the system. Finally, Node 3
sends a third party registration on behalf of bob to Node 14,
transferring bob's registration to the new node.
| |
| | |
|(2) 302 | |
|<------------------| |
| | |
|(3) REGISTER | |
|-------------------------------------->|
| | |
|(4) 200 | |
|<--------------------------------------|
| | |
|(5) REGISTER | |
|<--------------------------------------|
| | |
|(6) 200 | |
|-------------------------------------->|
| | |
Node 14 -> Node 5
REGISTER sip:10.0.0.5 SIP/2.0
To:
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=600
Require: dht
Supported: dht
Node 5 -> Node 14
SIP/2.0 302 Moved Temporarily
To:
From:
Contact:
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=1200
DHT-Link: ;link=P1;expires=427
DHT-Link: ;link=S1;expires=387
Require: dht
Supported: dht
Node 14 -> Node 3
REGISTER sip:10.0.0.3 SIP/2.0
To:
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=600
Require: dht
Supported: dht
Node 3 -> Node 14
SIP/2.0 200 OK
To:
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=600
DHT-Link: ;link=P1;expires=125
DHT-Link: ;link=S1;expires=919
DHT-Link: ;link=F0;expires=919
DHT-Link: ;link=F1;expires=919
DHT-Link: ;link=F2;expires=125
DHT-Link: ;link=F3;expires=600
Require: dht
Supported: dht
Node 3 -> Node 14
REGISTER sip:10.0.0.14 SIP/2.0
To:
From:
Contact:
Expires: 201
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=600
Require: dht
Supported: dht
Node 14 -> Node 3
SIP/2.0 200 OK
To:
From:
Contact:
Expires: 201
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=600
Require: dht
Supported: dht
]]>
Assume user Carl starts a UA co-located with node 5. Carl's contact
will be carl@10.0.0.5, and his user name will be
carl@p2psip.org. Carl's Node hashes his user id and determines that
the corresponding Resource-ID will be 11 -- that is, Carl's
registration will be stored by by the node responsible for Resource-ID
11 -- ultimately Node 3 in our example.
Carl's UA begins by constructing a SIP REGISTER message as described
in Resource Registrations. Carl's UA
consults its finger table, and determines that it should route
requests pertaining to a Resource-ID of 11 to Node 10. The REGISTER is
sent to Node 10, which observes that it is not responsible for that
portion of the namespace, and consults the finger table, finding Node
3 in the appropriate entry. Node 10 sends a 302 containing Node 3 as a
contact.
Node 5 constructs a new REGISTER on behalf of carl, and sends it to
Node 3. Node 3 recognizes that it is responsible for storing
this registration, and replies with a 200 OK (although in reality it
might challenge in some way). The 200 contains some number of
successor nodes -- in this case 2 (although in our contrived example,
one is node 5 itself) that Carl's node could send redundant
registrations to. In our example, we do not show these. The 200 also
(like 302s) must contain successors/predecessors in case the request is
being used for stabilization. Again, in the tiny contrived example it
looks odd since the second successor is the same as the predecessor. In
a larger example this would not be the case.
[To Do: Maybe use a bigger example to fix these problems? That might
be to big and ugly. Need a good way to show this]
| |
| | |
|(2) 302 | |
|<------------------| |
| | |
|(3) REGISTER | |
|-------------------------------------->|
| | |
|(4) 200 | |
|<--------------------------------------|
| | |
Node 5 -> Node 10
REGISTER sip:10.0.0.10 SIP/2.0
To:
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=1200
Require: dht
Supported: dht
Node 10 -> Node 5
SIP/2.0 302 Moved Temporarily
Contact:
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=800
DHT-Link: ;link=P1;expires=1200
DHT-Link: ;link=S1;expires=412
Require: dht
Supported: dht
Node 5 -> Node 3
REGISTER sip:10.0.0.3 SIP/2.0
To:
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=1200
Require: dht
Supported: dht
Node 3 -> Node 5
SIP/2.0 200 OK
To:
From:
Contact:
Expires: 600
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=600
DHT-Link: ;link=P1;expires=405
DHT-Link: ;link=S1;expires=1200
DHT-Link: ;link=S2;expires=405
Require: dht
Supported: dht
]]>
Assume user Bob wishes to call user Alice. Bob's node hashes Alice's
user id, resulting in a Resource-ID of 5. Bob's node (recall that
Bob's UA is co-located with node 10) consults it's finger table, and
determines that a request for Resource-ID 5 should be routed to Node
3. A REGISTER query message is constructed and routed to Node 3. Node 3
determines it is not responsible for a Resource-ID of 5, looks up the
ID in it's finger table and determines it should be routed to Node 5,
so it returns a 302 referring to Node 5. Bob's node resends the REGISTER
to Node 5, which stores Alice's information. It sends a 200 with
Alice's contact -- sipchat/alice@10.99.99.99. Bob finally sends an
INVITE to Alice's UA, and session establishment is completed as
normal.
| | |
| | | |
|(2) 302 | | |
|<------------------| | |
| | | |
|(3) REGISTER | | |
|----------------------------------->| |
| | | |
|(4) 200 | | |
|<-----------------------------------| |
| | | |
|(5) INVITE | | |
|------------------------------------------------------>|
| | | |
|(6) 180 | | |
|<------------------------------------------------------|
| | | |
|(7) 200 | | |
|<------------------------------------------------------|
| | | |
|(8) ACK | | |
|------------------------------------------------------>|
| | | |
Node 10 -> Node 3
REGISTER sip:10.0.0.3 SIP/2.0
To:
From:
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=800
Require: dht
Supported: dht
Node 3 -> Node 10
SIP/2.0 302 Moved Temporarily
To:
From:
Contact:
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=600
DHT-Link: ;link=P1;expires=421
DHT-Link: ;link=S1;expires=1004
Require: dht
Supported: dht
Node 10 -> Node 5
REGISTER sip:10.0.0.5 SIP/2.0
To:
From:
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=800
Require: dht
Supported: dht
Node 5 -> Node 10
SIP/2.0 200 OK
To:
From:
Contact:
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=1200
DHT-Link: ;link=P1;expires=108
DHT-Link: ;link=S1;expires=492
Require: dht
Supported: dht
Node 10 -> Alice UA
INVITE sip:alice@p2psip.org SIP/2.0
To:
From:
Contact:
DHT-NodeID: ;algorithm=sha1;overlay=chat;
expires=800
Supported: dht
]]>
The remainder of the call is completed as any other SIP call. Note
that if Alice's UA is DHT-compliant, then it will recognize the
Supported field and DHT-NodeID header, and may respond with similar
fields. However, if it does not support DHT extensions, it will
simply ignore those values and complete the call as any normal non-P2P
SIP UA.
[To Do: Add an example here]
[To Do: Add an example here]
[To Do: Add an example here]
To Do: Still a lots of work to be done here.
There are many inherent security issues in a system such as this, and it is
clearly not the solution for everyone. It trades off some security for certain
other properties such as functioning without a centralized server or owner of
the namespace.
The attacker is assumed to be able to generate an identity and become a valid
node in the system. They can see other nodes and process certain
queries. Attackers may wish to receive communications intended for other
participants, prevent other users from receiving their messages, prevent large
portions of the users from receiving messages, or send messages that appear to
be from others. Users would like to be sure they are communicating with the same
person they have previously talked to, to be able to verify identity via some
out of band mechanism. Attackers may try to squat on all the good names. Users
would like names that are meaningful to them. Attackers may have computers that
are many times faster than the average user's. Attackers may be able to DOS
other particular nodes and make them fail. To make a robust DHT, many nodes need
to store information on behalf of the community. Nodes may lie about this and
not store the information. Attackers may wish to see who is communicating with
whom and how much data is getting communicated.
Key requirements of the system are that there is no centralized naming authority
and users can pick names. If two users pick the same name, the system must be
able to determine which of them should be allowed to use the name. At some level
this is tricky, because different clients could pick the same new name at the
same time on opposite sides of the ring. Any local mechanism would let that
happen, whereas a global mechanism is very difficult to implement efficiently on
a P2P network that is dynamically changing.
The goal of this approach is to end up with a security environment comparable to
ssh, which in the opinion of the authors is excellent even though it is less
than perfect. This approach tries to limit the damage produced by the theft of
a person's identity instead of directly stopping the theft in the first
place. The system requires each user to have a self signed certificate and use
S/MIME and AIBs for signing the messages. When users first contact each other,
they can store the certificates, and each user can warn the other user if they
change on future communications.
UAs SHOULD be able to
display the sha1 hash of the certificate to the user for out of band
verification. Address books SHOULD store these certificates, and UAs should
trust the
information in users' address books at a higher level than information contained
in messages they receive over the wire. As described earlier, if the nodes and users desiring to join an
overlay can establish a shared secret, they can use that secret as a
seed to the Identifier algorithm, thus prohibiting anyone unaware of
that secret from joining the overlay because they will be unable to
construct valid identifiers.
The DHT forms a complex routing table. When a node joins, it may accidentally
contact a subversive node that lies about the finger table information it
provides. The subversive node could do this to try to trick the joining node to
route all the traffic to a subversive group of nodes.
The goal here is to stop the attacker from knowing who is signaling what to
whom. Ultimately this will be impossible if a large percentage of the ring is
compromised. It it possible to make it statistically hard for a user to figure
out what some specific other user is doing. This is done by forcing the hash
locations to be bound to the contact information via the crypto hash. In many
cases, the attacker does not have wide control over the range and number of IPs
available to them to attempt these attacks. IPv6 will
expand this and this work will have to look at perhaps hashing
the upper bits separately from the lower bits to again force the attacker into a
position where it is harder to control their IP address and thus the hash
function result that determines where they are inserted into the DHT.
Interactive systems mean that nodes only see the queries. Clients can randomly
generate these to obfuscate who they are tying to connect to. Cached results
localize the area in the DHT where an attacker's node would have to be located
to see an attempted connection to a given node.
All the media needs to be S/MIME encrypted. Doing so reduces the value of
intercepting others' communications, because the media cannot be seen in the
message. This is critical.
Very loosely synchronized time is fairly easy to maintain on modern devices
using only the internal clock. This is used in the SIP Date header field value
along with random Call-ID and to and from tags, resulting in a fair amount of
protection against replay attacks.
Using the AIB to protect the message with S/MIME makes cut and paste attacks
on of fields other than the VIA headers very
difficult.
A node can always re-sign the whole thing using a different self sided
certificate but new certificate would likely be caused by the receiver if a
previous communication had been made.
The lack of central authority to resolve name disputes in the namespace means
that at some level this problem is unsolved. The approach has tended to be to
allow everyone to call themselves Wally then let the certificates sort them
out. Users with names that are often "stolen" by others will learn that theirs
is a poor choice of name because it is too valuable, and they will select a
less valuable name. Equilibrium will prevail, or chaos.
The limitations of the security revolve around the intrinsic characteristic that
anyone can create a name - names are not unique and routing to a particular name
does not guarantee reaching a unique user.
There are certainly many open issues. Here are a few.
Still to be worked out are details of what names look like, how they are
allocated and protected, and how they are disambiguated from traditional names
that use DNS based routing.
Using routable IP addresses for the Node-ID is problematic. Using them solves a
big problem with preventing the Sybil attack and preventing people from simply
making tons of nodes that join the network and pollute the space; but on the
other hand, this will be a BIG problem with NATs. If home users' machines are
used, some large fraction probably have IP addresses in the 192.168.0.x and
192.168.1.x families. These addresses will all hash to the same ID. I used IP
addresses for now in the draft, but we need a better way to generate Node-IDs
that works for NATs and preserves all the protection against P2P attacks that
comes from using them.
We have had various thoughts on this issue. One thought is to require the use of
mechanisms such as STUN and require that actual IP addresses be placed in the
messages. This works well but permits only one node to be behind each
NAT. Appending a port does NOT solve the problem, as users then, by selecting
arbitrary port numbers can create a very large number of Node-IDs, and in a
network with a small number of nodes, could likely find a Node-ID that would
place them between any pair of nodes they desired, causing disruption to the
network. One possibility we have considered is to append the port number --
unmodified -- to the hash. This would still allow users behind a NAT to have
different Node-IDs, but the range of addresses within the hash would be very
limited -- the user would only be able to insert themselves between other nodes
behind the same NAT they are behind. There would still be issues with being able
to control an arbitrary number of successors, but they seem less serious than
the other alternative. This issue needs to be explored.
The following people provided useful feedback, commentary, advice,
design ideas, criticism, or proofreading during the course of writing this
draft:
Adam Roach, Robert Sparks,
Kundan Singh, Henning Schulzrinne, Marcia Zangrilli.
Thank you for your help!
There are several different implementations of P2P SIP. To date, they
each follow different, mutually incompatible protocols.
This document would require registering the following:
Option tag "DHT""DHT-Link" as a Header Field"DHT-NodeID" as a Header Field"node" as a valid value for parameter user (?)"Resource-ID" as a valid URI parameter (?)
[ToDo: This section needs to be revamped to include all the new BNF introduced]
An architecture in which nodes cooperate together to perform tasks. Each
node has essentially equal importance and performs the same tasks
within the network. Additionally, nodes communicate directly with one
another to perform tasks. Contrast this to a Client-Server architecture.
An architecture in which some small number of nodes (servers) provide
services to a larger number of nodes (clients). Client nodes connect
to servers, but typically do not communicate among themselves.
Any entity that participates in the overlay network, understanding the
p2p extensions described in this in document, is a "node" or "peer".
For P2P SIP, the term "node" usually refers to P2P-enabled UAs and to
adapter nodes that serve to connect non-P2P SIP devices.
A resource is an object for which a pointer is stored in the DHT.
Resources include user registrations, voicemail messages, etc.
This document refers to the virtual network created by the
interconnection between the nodes participating in the P2P SIP network
as the "overlay network", in keeping with the terminology used in the
P2P community.
A mechanism in which resources are given a unique key produced by
hashing some attribute of the resource, locating them
in a hash space (see below). Nodes located in this hash space also have
a unique id within the hash space. Nodes store information
about resources with keys that are numerically similar to the node's ID
in the hash space.
The range of values that valid results from the hash algorithm fall
into. For example, using the SHA-1 algorithm, the namespace is all 40
digit hexadecimal identifiers.
This namespace forms the set of valid values for Node-IDs and
Resource-IDs (see below).
The value resulting from hashing the a resource's unique name or
keyword. Any information about this resource will then be stored at
that location in the namespace, and
maintained by a node with a Node-ID with a value numerically similar
to the Resource-ID. In P2P SIP, User names are hashed to Resource-IDs
to determine where in hash space they should be stored.
The value resulting from hashing the unique ID of
a particular node. A node with particular Node-ID will be responsible
for maintaining information about resources with Resource-IDs that are
nearby in the hash space.
A particular algorithm/approach to implementing a DHT. Uses a circular
arrangement for the namespace.
The list of nodes that a node uses to send messages to. The finger
table contains many entries about nodes with similar IDs, and fewer
entries about more remote IDs.
A collection of nodes that a particular node can reach in one hop. In
general, note that a node's set of neighbors is equivalent to the
entries in that node's finger table. In our DHT structure, neighbor
relations are NOT symmetric.
An adapter node is a node in the overlay that acts as an adapter for
other non-P2P enabled SIP entities, allowing them to access the
resources of the overlay. The adapter node participates actively in the
overlay network, while the non-P2P enabled SIP entities it provides
service to DO
NOT participate directly in the overlay.
Compare these to the term "super node" in the P2P community, although
adapter nodes may be thin software shims intended for only one client.
A term borrowed from Chord. These terms refer to the node directly after
(before) a particular node in the address space. This does not mean
the successor/predecessor node's ID is one greater/less than the node,
it simply means that there are no other nodes in the namespace between
the node and the successor/predecessor. Note that the first node in a
finger table is typically also the first successor node.
The act of a peer joining the overlay. Registration allows a peer to
communicate with other peers, and requires (allows?) it to take on
some server-like responsibilities such as maintaining resource location
information. It DOES NOT register the user so that they can receive
phone calls, which is the traditional SIP use of the word
registration. We refer to traditional SIP registration as "user
registration".
The act of a user registering themselves with a SIP network. User registration
creates a mapping between a SIP URI and a contact for a user to be
created. This is the traditional meaning of registration in SIP. For a
P2P SIP node, this action MUST occur after node registration.
During the node registration process, this is the node that is attempting
to register -- that is, the node that is attempting to join the
overlay network.
During the process of node registration, the bootstrap node is the
node that the joining node contacts. This node may be a
well-known node, a node located using a broadcast method, a
node that the joining node previously knew about, or a node that
another bootstrap node referred the joining node to. Often, the only role
the bootstrap node plays in the node registration is to direct the
joining node to the admitting node.
During the process of node registration, this is the node that is
currently responsible for the portion of the namespace the new node
will eventually reside in. This node is responsible for generating
many of the messages exchanged during node registration.
Key words for use in RFCs to Indicate Requirement Levels
Harvard University1350 Mass. Ave.CambridgeMA 02138- +1 617 495 3864sob@harvard.edu
General
keyword
In many standards track documents several words are used to signify
the requirements in the specification. These words are often
capitalized. This document defines these words as they should be
interpreted in IETF documents. Authors who follow these guidelines
should incorporate this phrase near the beginning of their document:
The key words "MUST", "MUST NOT",
"REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT",
"RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described
in
RFC 2119.
Note that the force of these words is modified by the requirement
level of the document in which they are used.
SIP: Session Initiation ProtocolHMAC: Keyed-Hashing for Message AuthenticationIBMUCSDIBMUS Secure Hash Algorithm 1 (SHA1)Enhancements for Authenticated Identity Management in the
Session Initiation Protocol (SIP)SOSIMPLE: A Serverless, Standards-based, P2P SIP Communication System
College of William and MaryCisco SystemsCollege of William and MaryChord: A Scalable Peer-to-peer Lookup Service for Internet
Applications
MIT Laboratory for Computer ScienceMIT Laboratory for Computer ScienceMIT Laboratory for Computer ScienceMIT Laboratory for Computer ScienceMIT Laboratory for Computer ScienceMIT Laboratory for Computer ScienceMIT Laboratory for Computer ScienceThe Sybil Attack
Microsoft ResearchProviding Secure Services in Peer-to-Peer Communications Networks with Central Security ServerCisco SystemsWilliam and MaryWilliam and Mary
10:02