GNUnet  0.10.x
gnunet-daemon-hostlist.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2007, 2008, 2009, 2014 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 
26 #include "platform.h"
28 #include "gnunet_core_service.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_protocols.h"
32 
33 #if HAVE_MHD
34 
36 
40 static int advertising;
41 
45 static int provide_hostlist;
46 
50 static GNUNET_CORE_ConnectEventHandler server_ch;
51 
52 #endif
53 
58 static int bootstrapping;
59 
64 static int learning;
65 
70 
74 static struct GNUNET_CORE_Handle *core;
75 
80 
85 
90 
92 
110 
115 };
117 
118 
122 static struct GNUNET_PeerIdentity me;
123 
124 
131 static void
132 core_init(void *cls,
133  const struct GNUNET_PeerIdentity *my_identity)
134 {
135  me = *my_identity;
136 }
137 
138 
146 static int
148  const struct GNUNET_MessageHeader *message)
149 {
150  size_t size;
151  size_t uri_size;
152  const char *uri;
153 
154  size = ntohs(message->size);
155  if (size <= sizeof(struct GNUNET_MessageHeader))
156  {
157  GNUNET_break_op(0);
158  return GNUNET_SYSERR;
159  }
160  uri = (const char *)&message[1];
161  uri_size = size - sizeof(struct GNUNET_MessageHeader);
162  if (uri[uri_size - 1] != '\0')
163  {
164  GNUNET_break_op(0);
165  return GNUNET_SYSERR;
166  }
167  return GNUNET_OK;
168 }
169 
170 
178 static void
180  const struct GNUNET_MessageHeader *message)
181 {
182  const char *uri = (const char *)&message[1];
183 
185  (void)(*client_adv_handler)(uri);
186 }
187 
188 
198 static void *
199 connect_handler(void *cls,
200  const struct GNUNET_PeerIdentity *peer,
201  struct GNUNET_MQ_Handle *mq)
202 {
203  if (0 == GNUNET_memcmp(&me,
204  peer))
205  return NULL;
207  "A new peer connected, notifying client and server\n");
208  if (NULL != client_ch)
209  GNUNET_assert(NULL ==
210  (*client_ch)(cls,
211  peer,
212  mq));
213 #if HAVE_MHD
214  if (NULL != server_ch)
215  GNUNET_assert(NULL ==
216  (*server_ch)(cls,
217  peer,
218  mq));
219 #endif
220  return (void *)peer;
221 }
222 
223 
231 static void
233  const struct GNUNET_PeerIdentity *peer,
234  void *internal_cls)
235 {
236  if (0 == GNUNET_memcmp(&me,
237  peer))
238  return;
239  /* call hostlist client disconnect handler */
240  if (NULL != client_dh)
241  (*client_dh)(cls,
242  peer,
243  NULL);
244 }
245 
246 
253 static void
254 cleaning_task(void *cls)
255 {
257  "Hostlist daemon is shutting down\n");
258  if (NULL != core)
259  {
261  core = NULL;
262  }
263  if (bootstrapping)
264  {
266  }
267 #if HAVE_MHD
268  if (provide_hostlist)
269  {
271  }
272 #endif
273  if (NULL != stats)
274  {
276  GNUNET_NO);
277  stats = NULL;
278  }
279 }
280 
281 
290 static void
291 run(void *cls,
292  char *const *args,
293  const char *cfgfile,
294  const struct GNUNET_CONFIGURATION_Handle *cfg)
295 {
296  struct GNUNET_MQ_MessageHandler learn_handlers[] = {
297  GNUNET_MQ_hd_var_size(advertisement,
299  struct GNUNET_MessageHeader,
300  NULL),
302  };
303  struct GNUNET_MQ_MessageHandler no_learn_handlers[] = {
305  };
306 
307  if ((!bootstrapping) && (!learning)
308 #if HAVE_MHD
309  && (!provide_hostlist)
310 #endif
311  )
312  {
314  _("None of the functions for the hostlist daemon were enabled. I have no reason to run!\n"));
315  return;
316  }
317  stats = GNUNET_STATISTICS_create("hostlist", cfg);
318  if (NULL == stats)
319  {
320  GNUNET_break(0);
321  return;
322  }
323  if (bootstrapping)
325  stats,
326  &client_ch,
327  &client_dh,
329  learning);
330  core =
332  NULL,
333  &core_init,
336  learning ? learn_handlers : no_learn_handlers);
337 
338 
339 #if HAVE_MHD
340  if (provide_hostlist)
342  stats,
343  core,
344  &server_ch,
345  advertising);
346 #endif
348  NULL);
349 
350  if (NULL == core)
351  {
353  _("Failed to connect to `%s' service.\n"), "core");
355  return;
356  }
357 }
358 
359 
367 int
368 main(int argc, char *const *argv)
369 {
370  struct GNUNET_GETOPT_CommandLineOption options[] = {
371 #if HAVE_MHD
373  "advertise",
374  gettext_noop("advertise our hostlist to other peers"),
375  &advertising),
376 #endif
378  "bootstrap",
379  gettext_noop("bootstrap using hostlists (it is highly recommended that you always use this option)"),
380  &bootstrapping),
382  "enable-learning",
383  gettext_noop("enable learning about hostlist servers from other peers"),
384  &learning),
385 #if HAVE_MHD
387  "provide-hostlist",
388  gettext_noop("provide a hostlist server"),
389  &provide_hostlist),
390 #endif
392  };
393 
394  int ret;
395 
396  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
397  return 2;
398 
399  GNUNET_log_setup("hostlist", "WARNING", NULL);
400  ret =
401  (GNUNET_OK ==
402  GNUNET_PROGRAM_run(argc, argv,
403  "hostlist",
404  _("GNUnet hostlist server and client"),
405  options,
406  &run, NULL)) ? 0 : 1;
407  GNUNET_free((void*)argv);
408  return ret;
409 }
410 
411 /* end of gnunet-daemon-hostlist.c */
static GNUNET_NETWORK_STRUCT_END struct GNUNET_PeerIdentity me
Our own peer identity.
void GNUNET_HOSTLIST_client_stop()
Stop downloading hostlists from hostlist servers as necessary.
Context for the core service connection.
Definition: core_api.c:76
static void handle_advertisement(void *cls, const struct GNUNET_MessageHeader *message)
Core handler for p2p hostlist advertisements.
int GNUNET_HOSTLIST_server_start(const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_STATISTICS_Handle *st, struct GNUNET_CORE_Handle *co, GNUNET_CORE_ConnectEventHandler *server_ch, int advertise)
Start server offering our hostlist.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1284
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1439
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void(* GNUNET_CORE_DisconnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
Method called whenever a peer disconnects.
static void disconnect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a given peer disconnects.
#define GNUNET_NO
Definition: gnunet_common.h:78
static void * connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static void core_init(void *cls, const struct GNUNET_PeerIdentity *my_identity)
Callback invoked once our connection to CORE service is up.
Definition of a command line option.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
static int ret
Final status code.
Definition: gnunet-arm.c:89
Handle for the service.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
static void cleaning_task(void *cls)
Last task run during shutdown.
void *(* GNUNET_CORE_ConnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
int main(int argc, char *const *argv)
The main function for the hostlist daemon.
A HOSTLIST_ADV message is used to exchange information about hostlist advertisements.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static int advertising
Set if we are allowed to advertise our hostlist to others.
void(* GNUNET_HOSTLIST_UriHandler)(const char *uri)
Function that handles an advertised URI.
static GNUNET_CORE_DisconnectEventHandler client_dh
Handle to hostlist client&#39;s disconnect handler.
static int check_advertisement(void *cls, const struct GNUNET_MessageHeader *message)
Core handler for p2p hostlist advertisements.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static int learning
Set if the user allows us to learn about new hostlists from the network.
Message handler for a specific message type.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
uint32_t reserved
Always zero (for alignment).
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:690
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:728
int GNUNET_HOSTLIST_client_start(const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_STATISTICS_Handle *st, GNUNET_CORE_ConnectEventHandler *ch, GNUNET_CORE_DisconnectEventHandler *dh, GNUNET_HOSTLIST_UriHandler *msgh, int learn)
Start downloading hostlists from hostlist servers as necessary.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
Handle to a message queue.
Definition: mq.c:84
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
static struct GNUNET_CORE_Handle * core
Handle to the core service (NULL until we&#39;ve connected to it).
The identity of the host (wraps the signing key of the peer).
static int bootstrapping
Set if we are allowed to learn about peers by accessing hostlist servers.
static GNUNET_HOSTLIST_UriHandler client_adv_handler
Handle to the hostlist client&#39;s advertisement handler.
#define GNUNET_PACKED
gcc-ism to get packed structs.
configuration data
Definition: configuration.c:83
void GNUNET_HOSTLIST_server_stop()
Stop server offering our hostlist.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT
Further X-VINE DHT messages continued from 880.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
Header for all communications.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT.
static struct GNUNET_STATISTICS_Handle * stats
Statistics handle.
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
static GNUNET_CORE_ConnectEventHandler client_ch
Handle to hostlist client&#39;s connect handler.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run.