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

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.