gnunet-android

GNUnet for Android
Log | Files | Refs | README

gnunet_core_service.h (19964B)


      1 /*
      2      This file is part of GNUnet.
      3      Copyright (C) 2009-2017 GNUnet e.V.
      4 
      5      GNUnet is free software: you can redistribute it and/or modify it
      6      under the terms of the GNU Affero General Public License as published
      7      by the Free Software Foundation, either version 3 of the License,
      8      or (at your option) any later version.
      9 
     10      GNUnet is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      Affero General Public License for more details.
     14 
     15      You should have received a copy of the GNU Affero General Public License
     16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18      SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 /**
     21  * @author Christian Grothoff
     22  *
     23  * @addtogroup Backbone
     24  * @{
     25  *
     26  * @file include/gnunet_core_service.h
     27  * Core service; the main API for encrypted P2P communications
     28  *
     29  * @defgroup core  Core service
     30  * Encrypted direct communication between peers
     31  *
     32  * @see [Documentation](https://gnunet.org/gnunet-core-subsystem)
     33  *
     34  * @{
     35  */
     36 #ifndef GNUNET_CORE_SERVICE_H
     37 #define GNUNET_CORE_SERVICE_H
     38 
     39 #ifdef __cplusplus
     40 extern "C" {
     41 #if 0 /* keep Emacsens' auto-indent happy */
     42 }
     43 #endif
     44 #endif
     45 
     46 
     47 #include "gnunet_util_lib.h"
     48 
     49 /**
     50  * Size of the services info field in the cake handshake
     51  * TODO
     52  */
     53 #define GNUNET_CORE_SVC_INFO_LEN 64
     54 
     55 /**
     56  * The peer class gives a hint about the capabilities of a peer. The general
     57  * idea is to signal capabilities like connectivity/bandwidth, computational
     58  * and storage capabilities and stability in the network.
     59  *
     60  * TODO
     61  *  - this might move out of core to a more generic place
     62  *  - for now it is static, but it could in the future also include more
     63  *    detailed and dynamic attributes like 'battery-bound', 'behind more
     64  *    expensive mobile-bandwidth-connection', ...
     65  *  - it is only a general idea and it needs to be seen in the future how this
     66  *    will be used. With it's usage it will probably evolve into whatever seems
     67  *    to be useful
     68  */
     69 enum GNUNET_CORE_PeerClass
     70 {
     71   /**
     72    * The device's capabilities are currently unknown.
     73    */
     74   GNUNET_CORE_CLASS_UNKNOWN,
     75 
     76   /**
     77    * This device is currently unwilling to spend more then the absolutely
     78    * necessary resources.
     79    */
     80   GNUNET_CORE_CLASS_UNWILLING,
     81 
     82   /**
     83    * This is a mobile device. A smartphone or laptop. Could be battery bound,
     84    * could be behind a costly mobile broadband connection.
     85    */
     86   GNUNET_CORE_CLASS_MOBILE,
     87 
     88   /**
     89    * This is a desktop computer. Probably on continuous power supply and a
     90    * decent, rather stable internet connection. Probably not online 24/7.
     91    * Probably behind NAT.
     92    */
     93   GNUNET_CORE_CLASS_DESKTOP,
     94 
     95   /**
     96    * This is a piece of network infrastructure. General computational and
     97    * storage capabilities not overly high. Good placement in a network.
     98    * Probably online 24/7
     99    */
    100   GNUNET_CORE_CLASS_ROUTER,
    101 
    102   /**
    103    * This is something like a server. Has good computational and storage
    104    * capabilities. Has a stable connection with decent bandwidth. Is online
    105    * 24/7. Might not be behind NAT.
    106    */
    107   GNUNET_CORE_CLASS_SERVER
    108 };
    109 
    110 
    111 /**
    112  * Identifiers for services that communicate over CORE.
    113  */
    114 enum GNUNET_CORE_Service
    115 {
    116   /**
    117    * Identifier for cadet service
    118    */
    119   GNUNET_CORE_SERVICE_CADET,
    120 
    121   /**
    122    * Identifier for fs (file sharing) service
    123    */
    124   GNUNET_CORE_SERVICE_FS,
    125 
    126   /**
    127    * Identifier for dht (distributed hash table) service
    128    */
    129   GNUNET_CORE_SERVICE_DHT,
    130 
    131   /**
    132    * Identifier for nse (network size estimation) service
    133    */
    134   GNUNET_CORE_SERVICE_NSE,
    135 
    136   /**
    137    * Identifier for revocation service
    138    */
    139   GNUNET_CORE_SERVICE_REVOCATION,
    140 
    141   /**
    142    * Identifier for hostlist service
    143    */
    144   GNUNET_CORE_SERVICE_HOSTLIST,
    145 
    146   /**
    147    * Identifier for topology service
    148    */
    149   GNUNET_CORE_SERVICE_TOPOLOGY,
    150 
    151   /**
    152    * Identifier for rps (random peer sampling) service
    153    */
    154   GNUNET_CORE_SERVICE_RPS,
    155 
    156   // Note: Services using core need to define their own Identifier here
    157 
    158   /**
    159    * Identifier for testing the api
    160    */
    161   GNUNET_CORE_SERVICE_TEST
    162 };
    163 
    164 /**
    165  * A gnunet service version for services above CORE
    166  * TODO we might want to be compatible with https://semver.org
    167  */
    168 struct GNUNET_CORE_ServiceVersion
    169 {
    170   /**
    171    * Major version number
    172    */
    173   uint32_t major;
    174 
    175   /**
    176    * Minor version number
    177    */
    178   uint32_t minor;
    179 
    180   /**
    181    * Patch level
    182    * Will probably not be needed
    183    */
    184   // uint32_t patch;
    185 };
    186 
    187 
    188 /**
    189  * Gnunet service info - identifying compatibility with a range of version of a
    190  * service communicating over CORE.
    191  *
    192  * Note: This will replace some parts of src/include/gnunet_protocols.h
    193  */
    194 struct GNUNET_CORE_ServiceInfo
    195 {
    196   /**
    197    * Identifier of the service on top of CORE
    198    */
    199   enum GNUNET_CORE_Service service;
    200 
    201   /**
    202    * Version of this service implementation
    203    */
    204   struct GNUNET_CORE_ServiceVersion version;
    205 
    206   /**
    207    * Maximal compatible version number of @a service
    208    */
    209   struct GNUNET_CORE_ServiceVersion version_max;
    210 
    211   /**
    212    * Minimal compatible version number of @a service
    213    */
    214   struct GNUNET_CORE_ServiceVersion version_min;
    215 };
    216 
    217 
    218 /**
    219  * Version number of GNUnet-core API.
    220  */
    221 #define GNUNET_CORE_VERSION 0x00000001
    222 /**
    223  * Enable XChaCha20-Poly1305 crypto https://bugs.gnunet.org/view.php?id=8630
    224  */
    225 #define CONG_CRYPTO_ENABLED 0
    226 
    227 GNUNET_NETWORK_STRUCT_BEGIN
    228 
    229 
    230 /**
    231  * Message transmitted with the signed ephemeral key of a peer.  The
    232  * session key is then derived from the two ephemeral keys (ECDHE).
    233  */
    234 struct EphemeralKeyMessage
    235 {
    236   /**
    237    * Message type is #GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY.
    238    */
    239   struct GNUNET_MessageHeader header;
    240 
    241   /**
    242    * Status of the sender (should be in `enum PeerStateMachine`), nbo.
    243    */
    244   int32_t sender_status GNUNET_PACKED;
    245 
    246   /**
    247    * An ECC signature of the @e origin_identity asserting the validity
    248    * of the given ephemeral key.
    249    */
    250   struct GNUNET_CRYPTO_EddsaSignature signature;
    251 
    252   /**
    253    * Information about what is being signed.
    254    */
    255   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    256 
    257   /**
    258    * At what time was this key created (beginning of validity).
    259    */
    260   struct GNUNET_TIME_AbsoluteNBO creation_time;
    261 
    262   /**
    263    * When does the given ephemeral key expire (end of validity).
    264    */
    265   struct GNUNET_TIME_AbsoluteNBO expiration_time;
    266 
    267   /**
    268    * Ephemeral public ECC key.
    269    */
    270   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
    271 
    272   /**
    273    * Public key of the signing peer (persistent version, not the
    274    * ephemeral public key).
    275    */
    276   struct GNUNET_PeerIdentity origin_identity;
    277 };
    278 
    279 #if CONG_CRYPTO_ENABLED
    280 /**
    281  * We're sending an (encrypted) PING to the other peer to check if it
    282  * can decrypt.  The other peer should respond with a PONG with the
    283  * same content, except this time encrypted with the responder's key.
    284  */
    285 struct PingMessage
    286 {
    287   /**
    288    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PING.
    289    */
    290   struct GNUNET_MessageHeader header;
    291 
    292   /**
    293    * XChaCha20 nonce
    294    */
    295   unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES];
    296 
    297   /**
    298    * The Poly1305 tag of the encrypted message
    299    * (which is starting at @e target),
    300    * used to verify message integrity. Everything after this value
    301    * (excluding this value itself) will be encrypted and
    302    * authenticated.
    303    */
    304   unsigned char tag[crypto_aead_xchacha20poly1305_ietf_ABYTES];
    305 
    306   /**
    307    * Intended target of the PING, used primarily to check
    308    * that decryption actually worked.
    309    */
    310   struct GNUNET_PeerIdentity target;
    311 
    312   /**
    313    * Random number chosen to make replay harder.
    314    */
    315   uint32_t challenge GNUNET_PACKED;
    316 };
    317 
    318 
    319 /**
    320  * Response to a PING.  Includes data from the original PING.
    321  */
    322 struct PongMessage
    323 {
    324   /**
    325    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PONG.
    326    */
    327   struct GNUNET_MessageHeader header;
    328 
    329   /**
    330    * XChaCha20 nonce
    331    */
    332   unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES];
    333 
    334   /**
    335    * The Poly1305 tag of the encrypted message
    336    * (which is starting at @e target),
    337    * used to verify message integrity. Everything after this value
    338    * (excluding this value itself) will be encrypted and
    339    * authenticated.
    340    */
    341   unsigned char tag[crypto_aead_xchacha20poly1305_ietf_ABYTES];
    342 
    343 
    344   /**
    345    * Random number to make replay attacks harder.
    346    */
    347   uint32_t challenge GNUNET_PACKED;
    348 
    349   /**
    350    * Reserved, always zero.
    351    */
    352   uint32_t reserved;
    353 
    354   /**
    355    * Intended target of the PING, used primarily to check
    356    * that decryption actually worked.
    357    */
    358   struct GNUNET_PeerIdentity target;
    359 
    360   /**
    361    * The peer class of the sending peer
    362    * TODO is it correct to send an enum like this?
    363    */
    364   enum GNUNET_CORE_PeerClass peer_class;
    365 };
    366 
    367 #else
    368 
    369 /**
    370  * We're sending an (encrypted) PING to the other peer to check if it
    371  * can decrypt.  The other peer should respond with a PONG with the
    372  * same content, except this time encrypted with the responder's key.
    373  */
    374 struct PingMessage
    375 {
    376   /**
    377    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PING.
    378    */
    379   struct GNUNET_MessageHeader header;
    380 
    381   /**
    382    * Seed for the IV
    383    */
    384   uint32_t iv_seed GNUNET_PACKED;
    385 
    386   /**
    387    * Intended target of the PING, used primarily to check
    388    * that decryption actually worked.
    389    */
    390   struct GNUNET_PeerIdentity target;
    391 
    392   /**
    393    * Random number chosen to make replay harder.
    394    */
    395   uint32_t challenge GNUNET_PACKED;
    396 };
    397 
    398 
    399 /**
    400  * Response to a PING.  Includes data from the original PING.
    401  */
    402 struct PongMessage
    403 {
    404   /**
    405    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PONG.
    406    */
    407   struct GNUNET_MessageHeader header;
    408 
    409   /**
    410    * Seed for the IV
    411    */
    412   uint32_t iv_seed GNUNET_PACKED;
    413 
    414   /**
    415    * Random number to make replay attacks harder.
    416    */
    417   uint32_t challenge GNUNET_PACKED;
    418 
    419   /**
    420    * Reserved, always zero.
    421    */
    422   uint32_t reserved;
    423 
    424   /**
    425    * Intended target of the PING, used primarily to check
    426    * that decryption actually worked.
    427    */
    428   struct GNUNET_PeerIdentity target;
    429 
    430   /**
    431    * The peer class of the sending peer
    432    * TODO is it correct to send an enum like this?
    433    */
    434   enum GNUNET_CORE_PeerClass peer_class;
    435 };
    436 
    437 #endif
    438 
    439 GNUNET_NETWORK_STRUCT_END
    440 
    441 /**
    442  * Opaque handle to the service.
    443  */
    444 struct GNUNET_CORE_Handle;
    445 
    446 
    447 /**
    448  * Method called whenever a given peer connects.
    449  *
    450  * TODO provide with the service info about connecting peer/service
    451  *
    452  * @param cls closure
    453  * @param peer peer identity this notification is about
    454  * @param class the class of the connecting peer
    455  * @return closure associated with @a peer. given to mq callbacks and
    456  *         #GNUNET_CORE_DisconnectEventHandler
    457  */
    458 typedef void *(*GNUNET_CORE_ConnectEventHandler) (
    459   void *cls,
    460   const struct GNUNET_PeerIdentity *peer,
    461   struct GNUNET_MQ_Handle *mq,
    462   enum GNUNET_CORE_PeerClass class);
    463 
    464 
    465 /**
    466  * Method called whenever a peer disconnects.
    467  *
    468  * @param cls closure
    469  * @param peer peer identity this notification is about
    470  * @param peer_cls closure associated with peer. given in
    471  *        #GNUNET_CORE_ConnectEventHandler
    472  */
    473 typedef void (*GNUNET_CORE_DisconnectEventHandler) (
    474   void *cls,
    475   const struct GNUNET_PeerIdentity *peer,
    476   void *peer_cls);
    477 
    478 
    479 /**
    480  * Function called after #GNUNET_CORE_connect has succeeded (or failed
    481  * for good).  Note that the private key of the peer is intentionally
    482  * not exposed here; if you need to sign something, do this via the
    483  * pils service.  Implementations of this function must not call
    484  * #GNUNET_CORE_disconnect (other than by scheduling a new task to
    485  * do this later).
    486  *
    487  * TODO we could potentially also remove the identity argument
    488  *
    489  * @param cls closure
    490  * @param my_identity ID of this peer, NULL if we failed
    491  */
    492 typedef void (*GNUNET_CORE_StartupCallback) (
    493   void *cls,
    494   const struct GNUNET_PeerIdentity *my_identity);
    495 
    496 
    497 /**
    498  * Connect to the core service.  Note that the connection may complete
    499  * (or fail) asynchronously.  This function primarily causes the given
    500  * callback notification functions to be invoked whenever the
    501  * specified event happens.  The maximum number of queued
    502  * notifications (queue length) is per client; the queue is shared
    503  * across all types of notifications.  So a slow client that registers
    504  * for @a outbound_notify also risks missing @a inbound_notify messages.
    505  * Certain events (such as connect/disconnect notifications) are not
    506  * subject to queue size limitations.
    507  *
    508  * @param cfg configuration to use
    509  * @param cls closure for the various callbacks that follow (including handlers in the handlers array)
    510  * @param init callback to call once we have successfully
    511  *        connected to the core service
    512  * @param connects function to call on peer connect, can be NULL
    513  * @param disconnects function to call on peer disconnect / timeout, can be NULL
    514  * @param handlers callbacks for messages we care about, NULL-terminated
    515  *                note that the core is allowed to drop notifications about inbound
    516  *                messages if the client does not process them fast enough (for this
    517  *                notification type, a bounded queue is used)
    518  * @param service_info information about the connecting service and its
    519  *                     compatibility with other service versions
    520  * @return handle to the core service (only useful for disconnect until @a init is called),
    521  *           NULL on error (in this case, init is never called)
    522  */
    523 struct GNUNET_CORE_Handle *
    524 GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
    525                      void *cls,
    526                      GNUNET_CORE_StartupCallback init,
    527                      GNUNET_CORE_ConnectEventHandler connects,
    528                      GNUNET_CORE_DisconnectEventHandler disconnects,
    529                      const struct GNUNET_MQ_MessageHandler *handlers,
    530                      const struct GNUNET_CORE_ServiceInfo *service_info);
    531 
    532 
    533 /**
    534  * Disconnect from the core service.
    535  *
    536  * @param handle connection to core to disconnect
    537  */
    538 void
    539 GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle);
    540 
    541 
    542 /**
    543  * Obtain the message queue for a connected peer.
    544  * Messages may only be queued with #GNUNET_MQ_send once the init callback has
    545  * been called for the given handle.
    546  *
    547  * TODO does this function in this form make sense? it's not used anywhere.
    548  * Also it probably should take a hello as argument.
    549  *
    550  * @param h the core handle
    551  * @param pid the identity of the peer
    552  * @return NULL if @a pid is not connected
    553  */
    554 struct GNUNET_MQ_Handle *
    555 GNUNET_CORE_get_mq (const struct GNUNET_CORE_Handle *h,
    556                     const struct GNUNET_PeerIdentity *pid);
    557 
    558 
    559 /**
    560  * Handle to a CORE monitoring operation.
    561  */
    562 struct GNUNET_CORE_MonitorHandle;
    563 
    564 
    565 /**
    566  * TODO how does this harmonize with CAKE_CRYPTO_ENABLED?
    567  *
    568  * State machine for our P2P encryption handshake.  Everyone starts in
    569  * #GNUNET_CORE_KX_STATE_DOWN, if we receive the other peer's key
    570  * (other peer initiated) we start in state
    571  * #GNUNET_CORE_KX_STATE_KEY_RECEIVED (since we will immediately send
    572  * our own); otherwise we start in #GNUNET_CORE_KX_STATE_KEY_SENT.  If
    573  * we get back a PONG from within either state, we move up to
    574  * #GNUNET_CORE_KX_STATE_UP (the PONG will always be sent back
    575  * encrypted with the key we sent to the other peer).  Eventually,
    576  * we will try to rekey, for this we will enter
    577  * #GNUNET_CORE_KX_STATE_REKEY_SENT until the rekey operation is
    578  * confirmed by a PONG from the other peer.
    579  */
    580 enum GNUNET_CORE_KxState
    581 {
    582   /**
    583    * No handshake yet.
    584    */
    585   GNUNET_CORE_KX_STATE_DOWN = 0,
    586 
    587   /**
    588    * We sent the initiator hello.
    589    */
    590   GNUNET_CORE_KX_STATE_INITIATOR_HELLO_SENT,
    591 
    592   /**
    593    * We are awating the initiator hello.
    594    */
    595   GNUNET_CORE_KX_STATE_AWAIT_INITIATION,
    596 
    597   /**
    598    * We've received the initiator hello.
    599    */
    600   GNUNET_CORE_KX_STATE_INITIATOR_HELLO_RECEIVED,
    601 
    602   /**
    603    * We sent the responder hello.
    604    */
    605   GNUNET_CORE_KX_STATE_RESPONDER_HELLO_SENT,
    606 
    607   /**
    608    * We've received the initiator hello.
    609    */
    610   GNUNET_CORE_KX_STATE_RESPONDER_HELLO_RECEIVED,
    611 
    612   /**
    613    * We sent initiator done.
    614    */
    615   GNUNET_CORE_KX_STATE_INITIATOR_DONE_SENT,
    616 
    617   /**
    618    * Connected as initiator.
    619    */
    620   GNUNET_CORE_KX_STATE_INITIATOR_CONNECTED,
    621 
    622   /**
    623    * Connected as responder.
    624    */
    625   GNUNET_CORE_KX_STATE_RESPONDER_CONNECTED,
    626 
    627   /**
    628    * We're rekeying (or had a timeout), so we have sent the other peer
    629    * our new ephemeral key, but we did not get a matching PONG yet.
    630    * This is equivalent to being #GNUNET_CORE_KX_STATE_KEY_RECEIVED,
    631    * except that the session is marked as 'up' with sessions (as we
    632    * don't want to drop and re-establish P2P connections simply due to
    633    * rekeying).
    634    */
    635   GNUNET_CORE_KX_STATE_REKEY_SENT,
    636 
    637   /**
    638    * Last state of a KX (when it is being terminated).  Set
    639    * just before CORE frees the internal state for this peer.
    640    */
    641   GNUNET_CORE_KX_PEER_DISCONNECT,
    642 
    643   /**
    644    * This is not a state in a peer's state machine, but a special
    645    * value used with the #GNUNET_CORE_MonitorCallback to indicate
    646    * that we finished the initial iteration over the peers.
    647    */
    648   GNUNET_CORE_KX_ITERATION_FINISHED,
    649 
    650   /**
    651    * This is not a state in a peer's state machine, but a special
    652    * value used with the #GNUNET_CORE_MonitorCallback to indicate
    653    * that we lost the connection to the CORE service (and will try
    654    * to reconnect).  If this happens, most likely the CORE service
    655    * crashed and thus all connection state should be assumed lost.
    656    */
    657   GNUNET_CORE_KX_CORE_DISCONNECT
    658 };
    659 
    660 
    661 /**
    662  * Function called by the monitor callback whenever
    663  * a peer's connection status changes.
    664  *
    665  * @param cls closure
    666  * @param pid identity of the peer this update is about
    667  * @param state current key exchange state of the peer
    668  * @param timeout when does the current state expire
    669  */
    670 typedef void (*GNUNET_CORE_MonitorCallback) (
    671   void *cls,
    672   const struct GNUNET_PeerIdentity *pid,
    673   enum GNUNET_CORE_KxState state,
    674   struct GNUNET_TIME_Absolute timeout);
    675 
    676 
    677 /**
    678  * Monitor connectivity and KX status of all peers known to CORE.
    679  * Calls @a peer_cb with the current status for each connected peer,
    680  * and then once with NULL to indicate that all peers that are
    681  * currently active have been handled.  After that, the iteration
    682  * continues until it is cancelled.  Normal users of the CORE API are
    683  * not expected to use this function.  It is different in that it
    684  * truly lists all connections (including those where the KX is in
    685  * progress), not just those relevant to the application.  This
    686  * function is used by special applications for diagnostics.
    687  *
    688  * @param cfg configuration handle
    689  * @param peer_cb function to call with the peer information
    690  * @param peer_cb_cls closure for @a peer_cb
    691  * @return NULL on error
    692  */
    693 struct GNUNET_CORE_MonitorHandle *
    694 GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
    695                            GNUNET_CORE_MonitorCallback peer_cb,
    696                            void *peer_cb_cls);
    697 
    698 
    699 /**
    700  * Stop monitoring CORE activity.
    701  *
    702  * @param mh monitor to stop
    703  */
    704 void
    705 GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh);
    706 
    707 
    708 /**
    709  * Check if the given peer is currently connected. This function is for special
    710  * circumstances (GNUNET_TESTBED uses it), normal users of the CORE API are
    711  * expected to track which peers are connected based on the connect/disconnect
    712  * callbacks from #GNUNET_CORE_connect.  This function is NOT part of the
    713  * 'versioned', 'official' API.  This function returns
    714  * synchronously after looking in the CORE API cache.
    715  *
    716  * FIXME not implemented
    717  *
    718  * @param h the core handle
    719  * @param pid the identity of the peer to check if it has been connected to us
    720  * @return #GNUNET_YES if the peer is connected to us; #GNUNET_NO if not
    721  */
    722 int
    723 GNUNET_CORE_is_peer_connected_sync (const struct GNUNET_CORE_Handle *h,
    724                                     const struct GNUNET_PeerIdentity *pid);
    725 
    726 
    727 #if 0 /* keep Emacsens' auto-indent happy */
    728 {
    729 #endif
    730 #ifdef __cplusplus
    731 }
    732 #endif
    733 
    734 /* ifndef GNUNET_CORE_SERVICE_H */
    735 #endif
    736 
    737 /** @} */ /* end of group core */
    738 
    739 /** @} */ /* end of backbone addition */
    740 
    741 /* end of gnunet_core_service.h */