PEERINFO — Persistent HELLO storage
The PEERINFO subsystem is used to store verified (validated) information about known peers in a persistent way. It obtains these addresses for example from TRANSPORT service which is in charge of address validation. Validation means that the information in the HELLO message are checked by connecting to the addresses and performing a cryptographic handshake to authenticate the peer instance stating to be reachable with these addresses. Peerinfo does not validate the HELLO messages itself but only stores them and gives them to interested clients.
As future work, we think about moving from storing just HELLO messages to providing a generic persistent per-peer information store. More and more subsystems tend to need to store per-peer information in persistent way. To not duplicate this functionality we plan to provide a PEERSTORE service providing this functionality.
PEERINFO - Features
Persistent storage
Client notification mechanism on update
Periodic clean up for expired information
Differentiation between public and friend-only HELLO
PEERINFO - Limitations
Does not perform HELLO validation
DeveloperPeer Information
The PEERINFO subsystem stores these information in the form of HELLO messages you can think of as business cards. These HELLO messages contain the public key of a peer and the addresses a peer can be reached under. The addresses include an expiration date describing how long they are valid. This information is updated regularly by the TRANSPORT service by revalidating the address. If an address is expired and not renewed, it can be removed from the HELLO message.
Some peer do not want to have their HELLO messages distributed to other
peers, especially when GNUnet’s friend-to-friend modus is enabled. To
prevent this undesired distribution. PEERINFO distinguishes between
public and friend-only HELLO messages. Public HELLO messages can be
freely distributed to other (possibly unknown) peers (for example using
the hostlist, gossiping, broadcasting), whereas friend-only HELLO
messages may not be distributed to other peers. Friend-only HELLO
messages have an additional flag friend_only
set internally. For
public HELLO message this flag is not set. PEERINFO does and cannot not
check if a client is allowed to obtain a specific HELLO type.
The HELLO messages can be managed using the GNUnet HELLO library. Other GNUnet systems can obtain these information from PEERINFO and use it for their purposes. Clients are for example the HOSTLIST component providing these information to other peers in form of a hostlist or the TRANSPORT subsystem using these information to maintain connections to other peers.
Startup
During startup the PEERINFO services loads persistent HELLOs from disk.
First PEERINFO parses the directory configured in the HOSTS value of the
PEERINFO
configuration section to store PEERINFO information. For
all files found in this directory valid HELLO messages are extracted. In
addition it loads HELLO messages shipped with the GNUnet distribution.
These HELLOs are used to simplify network bootstrapping by providing
valid peer information with the distribution. The use of these HELLOs
can be prevented by setting the USE_INCLUDED_HELLOS
in the
PEERINFO
configuration section to NO
. Files containing invalid
information are removed.
Managing Information
The PEERINFO services stores information about known PEERS and a single HELLO message for every peer. A peer does not need to have a HELLO if no information are available. HELLO information from different sources, for example a HELLO obtained from a remote HOSTLIST and a second HELLO stored on disk, are combined and merged into one single HELLO message per peer which will be given to clients. During this merge process the HELLO is immediately written to disk to ensure persistence.
PEERINFO in addition periodically scans the directory where information are stored for empty HELLO messages with expired TRANSPORT addresses. This periodic task scans all files in the directory and recreates the HELLO messages it finds. Expired TRANSPORT addresses are removed from the HELLO and if the HELLO does not contain any valid addresses, it is discarded and removed from the disk.
Obtaining Information
When a client requests information from PEERINFO, PEERINFO performs a lookup for the respective peer or all peers if desired and transmits this information to the client. The client can specify if friend-only HELLOs have to be included or not and PEERINFO filters the respective HELLO messages before transmitting information.
To notify clients about changes to PEERINFO information, PEERINFO maintains a list of clients interested in this notifications. Such a notification occurs if a HELLO for a peer was updated (due to a merge for example) or a new peer was added.
The PEERINFO Client-Service Protocol
To connect and disconnect to and from the PEERINFO Service PEERINFO utilizes the util client/server infrastructure, so no special messages types are used here.
To add information for a peer, the plain HELLO message is transmitted to the service without any wrapping. All pieces of information required are stored within the HELLO message. The PEERINFO service provides a message handler accepting and processing these HELLO messages.
When obtaining PEERINFO information using the iterate functionality
specific messages are used. To obtain information for all peers, a
struct ListAllPeersMessage
with message type
GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL
and a flag include_friend_only
to indicate if friend-only HELLO messages should be included are
transmitted. If information for a specific peer is required a
struct ListAllPeersMessage
with GNUNET_MESSAGE_TYPE_PEERINFO_GET
containing the peer identity is used.
For both variants the PEERINFO service replies for each HELLO message it
wants to transmit with a struct ListAllPeersMessage
with type
GNUNET_MESSAGE_TYPE_PEERINFO_INFO
containing the plain HELLO. The
final message is struct GNUNET_MessageHeader
with type
GNUNET_MESSAGE_TYPE_PEERINFO_INFO
. If the client receives this
message, it can proceed with the next request if any is pending.
libgnunetpeerinfo libgnunetpeerinfo —————–
The PEERINFO API consists mainly of three different functionalities:
maintaining a connection to the service
adding new information to the PEERINFO service
retrieving information from the PEERINFO service
Connecting to the PEERINFO Service
To connect to the PEERINFO service the function
GNUNET_PEERINFO_connect
is used, taking a configuration handle as an
argument, and to disconnect from PEERINFO the function
GNUNET_PEERINFO_disconnect
, taking the PEERINFO handle returned from
the connect function has to be called.
Adding Information to the PEERINFO Service
GNUNET_PEERINFO_add_peer
adds a new peer to the PEERINFO subsystem
storage. This function takes the PEERINFO handle as an argument, the
HELLO message to store and a continuation with a closure to be called
with the result of the operation. The GNUNET_PEERINFO_add_peer
returns a handle to this operation allowing to cancel the operation with
the respective cancel function GNUNET_PEERINFO_add_peer_cancel
. To
retrieve information from PEERINFO you can iterate over all information
stored with PEERINFO or you can tell PEERINFO to notify if new peer
information are available.
Obtaining Information from the PEERINFO Service
To iterate over information in PEERINFO you use
GNUNET_PEERINFO_iterate
. This function expects the PEERINFO handle,
a flag if HELLO messages intended for friend only mode should be
included, a timeout how long the operation should take and a callback
with a callback closure to be called for the results. If you want to
obtain information for a specific peer, you can specify the peer
identity, if this identity is NULL, information for all peers are
returned. The function returns a handle to allow to cancel the operation
using GNUNET_PEERINFO_iterate_cancel
.
To get notified when peer information changes, you can use
GNUNET_PEERINFO_notify
. This function expects a configuration handle
and a flag if friend-only HELLO messages should be included. The
PEERINFO service will notify you about every change and the callback
function will be called to notify you about changes. The function
returns a handle to cancel notifications with
GNUNET_PEERINFO_notify_cancel
.