GNUnet  0.19.4
plugin_dhtu_gnunet.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2021 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 
27 #include "platform.h"
28 #include "gnunet_dhtu_plugin.h"
29 #include "gnunet_ats_service.h"
30 #include "gnunet_core_service.h"
32 #include "gnunet_hello_lib.h"
34 #include "gnunet_nse_service.h"
35 
36 
41 {
45  struct HelloHandle *next;
46 
50  struct HelloHandle *prev;
51 
55  struct Plugin *plugin;
56 
61 
62 };
63 
64 
70 {
71 
75  void *app_ctx;
76 
77 };
78 
79 
85 {
86 
90  void *app_ctx;
91 
95  struct Plugin *plugin;
96 
101 
106 
111 
116 
120  struct GNUNET_PeerIdentity pid;
121 
125  unsigned int ph_count;
126 
127 };
128 
129 
135 {
140 
145 
150 };
151 
152 
156 struct Plugin
157 {
158 
163  struct GNUNET_DHTU_Source src;
164 
169 
174 
179 
184 
189 
194 
199 
204 
205 };
206 
207 
213 static void
214 hello_offered_cb (void *cls)
215 {
216  struct HelloHandle *hh = cls;
217  struct Plugin *plugin = hh->plugin;
218 
220  plugin->hh_tail,
221  hh);
222  GNUNET_free (hh);
223 }
224 
225 
226 #include "../peerinfo-tool/gnunet-peerinfo_plugins.c"
227 
228 
236 static void
238  const struct GNUNET_PeerIdentity *pid,
239  const char *address)
240 {
241  struct Plugin *plugin = cls;
242  struct GNUNET_HELLO_Message *hello = NULL;
243  struct HelloHandle *hh;
245 
246  (void) pid; /* will be needed with future address URIs */
247  if (GNUNET_OK !=
249  &pubkey,
250  &hello,
252  return;
253  hh = GNUNET_new (struct HelloHandle);
254  hh->plugin = plugin;
256  plugin->hh_tail,
257  hh);
258  hh->ohh = GNUNET_TRANSPORT_offer_hello (plugin->env->cfg,
259  &hello->header,
261  hh);
262  GNUNET_free (hello);
263 }
264 
265 
274 static struct GNUNET_DHTU_PreferenceHandle *
275 gnunet_hold (void *cls,
276  struct GNUNET_DHTU_Target *target)
277 {
278  struct Plugin *plugin = cls;
280 
282  ph->target = target;
284  target->ph_tail,
285  ph);
286  target->ph_count++;
287  if (NULL != target->csh)
289  target->csh
291  &target->pid,
292  target->ph_count);
293  return ph;
294 }
295 
296 
303 static void
305 {
306  struct GNUNET_DHTU_Target *target = ph->target;
307  struct Plugin *plugin = target->plugin;
308 
310  target->ph_tail,
311  ph);
312  target->ph_count--;
313  GNUNET_free (ph);
314  if (NULL != target->csh)
316  if (0 == target->ph_count)
317  target->csh = NULL;
318  else
319  target->csh
321  &target->pid,
322  target->ph_count);
323 }
324 
325 
341 static void
342 gnunet_send (void *cls,
343  struct GNUNET_DHTU_Target *target,
344  const void *msg,
345  size_t msg_size,
347  void *finished_cb_cls)
348 {
349  struct GNUNET_MQ_Envelope *env;
350  struct GNUNET_MessageHeader *cmsg;
351 
352  env = GNUNET_MQ_msg_extra (cmsg,
353  msg_size,
356  finished_cb,
357  finished_cb_cls);
358  memcpy (&cmsg[1],
359  msg,
360  msg_size);
361  GNUNET_MQ_send (target->mq,
362  env);
363 }
364 
365 
374 static void *
375 core_connect_cb (void *cls,
376  const struct GNUNET_PeerIdentity *peer,
377  struct GNUNET_MQ_Handle *mq)
378 {
379  struct Plugin *plugin = cls;
380  struct GNUNET_DHTU_Target *target;
381 
382  target = GNUNET_new (struct GNUNET_DHTU_Target);
383  target->plugin = plugin;
384  target->mq = mq;
385  target->pid = *peer;
386  plugin->env->connect_cb (plugin->env->cls,
387  target,
388  &target->pid,
389  &target->app_ctx);
390  return target;
391 }
392 
393 
402 static void
404  const struct GNUNET_PeerIdentity *peer,
405  void *peer_cls)
406 {
407  struct Plugin *plugin = cls;
408  struct GNUNET_DHTU_Target *target = peer_cls;
409 
410  plugin->env->disconnect_cb (target->app_ctx);
411  if (NULL != target->csh)
413  GNUNET_free (target);
414 }
415 
416 
429 static void
430 peerinfo_cb (void *cls,
431  const struct GNUNET_PeerIdentity *peer,
432  const struct GNUNET_HELLO_Message *hello,
433  const char *err_msg)
434 {
435  struct Plugin *plugin = cls;
436  char *addr;
437 
438  if (NULL == hello)
439  return;
440  if (NULL == peer)
441  return;
442  if (0 !=
444  &plugin->my_identity))
445  return;
446  addr = GNUNET_HELLO_compose_uri (hello,
448  if (NULL == addr)
449  return;
450  plugin->env->address_add_cb (plugin->env->cls,
451  addr,
452  &plugin->src,
453  &plugin->src.app_ctx);
454  GNUNET_free (addr);
455 }
456 
457 
470 static void
471 core_init_cb (void *cls,
472  const struct GNUNET_PeerIdentity *my_identity)
473 {
474  struct Plugin *plugin = cls;
475 
476  plugin->my_identity = *my_identity;
477  plugin->nc = GNUNET_PEERINFO_notify (plugin->env->cfg,
478  GNUNET_NO,
479  &peerinfo_cb,
480  plugin);
481 }
482 
483 
491 static int
493  const struct GNUNET_MessageHeader *msg)
494 {
495  (void) cls;
496  (void) msg;
497  return GNUNET_OK;
498 }
499 
500 
508 static void
510  const struct GNUNET_MessageHeader *msg)
511 {
512  struct GNUNET_DHTU_Target *origin = cls;
513  struct Plugin *plugin = origin->plugin;
514 
515  plugin->env->receive_cb (plugin->env->cls,
516  &origin->app_ctx,
517  &plugin->src.app_ctx,
518  &msg[1],
519  ntohs (msg->size) - sizeof (*msg));
520 }
521 
522 
531 static void
532 nse_cb (void *cls,
533  struct GNUNET_TIME_Absolute timestamp,
534  double logestimate,
535  double std_dev)
536 {
537  struct Plugin *plugin = cls;
538 
539  plugin->env->network_size_cb (plugin->env->cls,
540  timestamp,
541  logestimate,
542  std_dev);
543 }
544 
545 
552 void *
554 {
555  struct GNUNET_DHTU_PluginFunctions *api = cls;
556  struct Plugin *plugin = api->cls;
557  struct HelloHandle *hh;
558 
559  while (NULL != (hh = plugin->hh_head))
560  {
562  plugin->hh_tail,
563  hh);
565  GNUNET_free (hh);
566  }
567  if (NULL != plugin->nse)
569  plugin->env->network_size_cb (plugin->env->cls,
571  0.0,
572  0.0);
573  if (NULL != plugin->core)
575  if (NULL != plugin->ats)
577  if (NULL != plugin->nc)
581  GNUNET_free (api);
582  return NULL;
583 }
584 
585 
592 void *
594 {
596  struct GNUNET_DHTU_PluginFunctions *api;
597  struct Plugin *plugin;
599  GNUNET_MQ_hd_var_size (core_message,
601  struct GNUNET_MessageHeader,
602  NULL),
604  };
605 
606  plugin = GNUNET_new (struct Plugin);
607  plugin->env = env;
609  api->cls = plugin;
611  api->hold = &gnunet_hold;
612  api->drop = &gnunet_drop;
613  api->send = &gnunet_send;
615  plugin->core = GNUNET_CORE_connect (env->cfg,
616  plugin,
617  &core_init_cb,
620  handlers);
621  plugin->nse = GNUNET_NSE_connect (env->cfg,
622  &nse_cb,
623  plugin);
624  if ( (NULL == plugin->ats) ||
625  (NULL == plugin->core) ||
626  (NULL == plugin->nse) )
627  {
628  GNUNET_break (0);
629  GNUNET_free (api);
631  return NULL;
632  }
633  GPI_plugins_load (env->cfg);
634  return api;
635 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static void finished_cb(enum GNUNET_GenericReturnValue rv)
struct TestcasePlugin * plugin
The process handle to the testbed service.
static char * address
GNS address for this phone.
static struct GNUNET_IDENTITY_PublicKey pubkey
Public key of the zone to look in.
static char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH]
Current origin.
struct GNUNET_TRANSPORT_PluginFunctions * GPI_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
void GPI_plugins_load(const struct GNUNET_CONFIGURATION_Handle *cfg)
Load and initialize all plugins.
void GPI_plugins_unload()
Unload all plugins.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
Automatic transport selection and outbound bandwidth determination.
Core service; the main API for encrypted P2P communications.
Helper library for handling HELLOs.
API to retrieve the current network size estimate.
Maintain the list of currently known hosts.
struct GNUNET_ATS_ConnectivityHandle * GNUNET_ATS_connectivity_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the ATS connectivity suggestion client handle.
struct GNUNET_ATS_ConnectivitySuggestHandle * GNUNET_ATS_connectivity_suggest(struct GNUNET_ATS_ConnectivityHandle *ch, const struct GNUNET_PeerIdentity *peer, uint32_t strength)
We would like to receive address suggestions for a peer.
void GNUNET_ATS_connectivity_done(struct GNUNET_ATS_ConnectivityHandle *ch)
Client is done with ATS connectivity management, release resources.
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Connect to the core service.
Definition: core_api.c:691
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:729
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int GNUNET_HELLO_parse_uri(const char *uri, struct GNUNET_CRYPTO_EddsaPublicKey *pubkey, struct GNUNET_HELLO_Message **hello, GNUNET_HELLO_TransportPluginsFind plugins_find)
Parse a hello URI string to a hello message.
Definition: hello.c:1195
char * GNUNET_HELLO_compose_uri(const struct GNUNET_HELLO_Message *hello, GNUNET_HELLO_TransportPluginsFind plugins_find)
Compose a hello URI string from a hello message.
Definition: hello.c:1007
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ GNUNET_OK
@ GNUNET_NO
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:62
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition: mq.c:638
void GNUNET_NSE_disconnect(struct GNUNET_NSE_Handle *h)
Disconnect from network size estimation service.
Definition: nse_api.c:193
struct GNUNET_NSE_Handle * GNUNET_NSE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_NSE_Callback func, void *func_cls)
Connect to the network size estimation service.
Definition: nse_api.c:165
struct GNUNET_PEERINFO_NotifyContext * GNUNET_PEERINFO_notify(const struct GNUNET_CONFIGURATION_Handle *cfg, int include_friend_only, GNUNET_PEERINFO_Processor callback, void *callback_cls)
Call a method whenever our known information about peers changes.
void GNUNET_PEERINFO_notify_cancel(struct GNUNET_PEERINFO_NotifyContext *nc)
Stop notifying about changes.
#define GNUNET_MESSAGE_TYPE_DHT_CORE
Encapsulation of DHT messages in CORE service.
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
void GNUNET_TRANSPORT_offer_hello_cancel(struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
Cancel the request to transport to offer the HELLO message.
struct GNUNET_TRANSPORT_OfferHelloHandle * GNUNET_TRANSPORT_offer_hello(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_MessageHeader *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Offer the transport service the HELLO of another peer.
static void handle_core_message(void *cls, const struct GNUNET_MessageHeader *msg)
Handle message from CORE for the DHT.
void * libgnunet_plugin_dhtu_gnunet_done(void *cls)
Exit point from the plugin.
static int check_core_message(void *cls, const struct GNUNET_MessageHeader *msg)
Anything goes, always return GNUNET_OK.
static void * core_connect_cb(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
static void gnunet_drop(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no long request underlay to keep the connection alive.
static void peerinfo_cb(void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg)
Find the hello for our identity and then pass it to the DHT as a URL.
static void core_disconnect_cb(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
Method called whenever a peer disconnects.
static void gnunet_try_connect(void *cls, const struct GNUNET_PeerIdentity *pid, const char *address)
Request creation of a session with a peer at the given address.
static struct GNUNET_DHTU_PreferenceHandle * gnunet_hold(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
static void hello_offered_cb(void *cls)
Function called once a hello offer is completed.
void * libgnunet_plugin_dhtu_gnunet_init(void *cls)
Entry point for the plugin.
static void nse_cb(void *cls, struct GNUNET_TIME_Absolute timestamp, double logestimate, double std_dev)
Callback to call when network size estimate is updated.
static void gnunet_send(void *cls, struct GNUNET_DHTU_Target *target, const void *msg, size_t msg_size, GNUNET_SCHEDULER_TaskCallback finished_cb, void *finished_cb_cls)
Send message to some other participant over the network.
static void core_init_cb(void *cls, const struct GNUNET_PeerIdentity *my_identity)
Function called after GNUNET_CORE_connect has succeeded (or failed for good).
Handle to the ATS subsystem for connectivity management.
Handle for ATS address suggestion requests.
void * cls
Closure for all of the callbacks.
Context for the core service connection.
Definition: core_api.c:78
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure to use for callbacks.
struct returned by the initialization function of the plugin
struct GNUNET_DHTU_PreferenceHandle *(* hold)(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
void(* try_connect)(void *cls, const struct GNUNET_PeerIdentity *pid, const char *address)
Request creation of a session with a peer at the given address.
void * cls
Closure to pass to all plugin functions.
void(* drop)(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no longer request underlay to keep the connection alive.
void(* send)(void *cls, struct GNUNET_DHTU_Target *target, const void *msg, size_t msg_size, GNUNET_SCHEDULER_TaskCallback finished_cb, void *finished_cb_cls)
Send message to some other participant over the network.
Opaque handle expressing a preference of the DHT to keep a particular target connected.
struct GNUNET_DHTU_PreferenceHandle * prev
Kept in a DLL.
struct GNUNET_DHTU_Target * target
Target a preference was expressed for.
struct GNUNET_DHTU_PreferenceHandle * next
Kept in a DLL.
Opaque handle that the underlay offers for our address to be used when sending messages to another pe...
void * app_ctx
Application context for this source.
Opaque handle that the underlay offers for the target peer when sending messages to another peer.
struct GNUNET_ATS_ConnectivitySuggestHandle * csh
ATS preference handle for this peer, or NULL.
struct GNUNET_DHTU_PreferenceHandle * ph_head
Head of preferences expressed for this target.
unsigned int ph_count
Preference counter, length of the ph_head DLL.
struct Plugin * plugin
Our plugin with its environment.
struct GNUNET_MQ_Handle * mq
CORE MQ to send messages to this peer.
void * app_ctx
Application context for this target.
struct GNUNET_DHTU_PreferenceHandle * ph_tail
Tail of preferences expressed for this target.
struct GNUNET_PeerIdentity pid
Identity of this peer.
A HELLO message is used to exchange information about transports with other peers.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_HELLO.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle for talking with the NSE service.
Definition: nse_api.c:41
Context for the info handler.
The identity of the host (wraps the signing key of the peer).
Time for absolute times used by GNUnet, in microseconds.
Entry in linked list for all offer-HELLO requests.
Handle for a HELLO we're offering the transport.
struct HelloHandle * next
Kept in a DLL.
struct Plugin * plugin
Our plugin.
struct GNUNET_TRANSPORT_OfferHelloHandle * ohh
Offer handle.
struct HelloHandle * prev
Kept in a DLL.
Handle for a plugin.
Definition: block.c:38
struct GNUNET_DHTU_PluginEnvironment * env
Callbacks into the DHT.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
struct HelloHandle * hh_tail
Hellos we are offering to transport.
struct GNUNET_DHTU_Source src
Our "source" address.
struct GNUNET_PeerIdentity my_identity
Identity of this peer.
struct GNUNET_PEERINFO_NotifyContext * nc
Watching for our address to change.
struct HelloHandle * hh_head
Hellos we are offering to transport.
struct GNUNET_NSE_Handle * nse
Handle to the NSE service.
struct GNUNET_ATS_ConnectivityHandle * ats
Handle to ATS service.
struct GNUNET_CORE_Handle * core
Handle to the CORE service.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.