Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / dht / gnunet-service-dht.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file dht/gnunet-service-dht.c
23  * @brief GNUnet DHT service
24  * @author Christian Grothoff
25  * @author Nathan Evans
26  */
27 #include "platform.h"
28 #include "gnunet_block_lib.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_transport_service.h"
31 #include "gnunet_transport_hello_service.h"
32 #include "gnunet_hello_lib.h"
33 #include "gnunet_dht_service.h"
34 #include "gnunet_statistics_service.h"
35 #include "gnunet-service-dht.h"
36 #include "gnunet-service-dht_datacache.h"
37 #include "gnunet-service-dht_hello.h"
38 #include "gnunet-service-dht_neighbours.h"
39 #include "gnunet-service-dht_nse.h"
40 #include "gnunet-service-dht_routing.h"
41
42 /**
43  * Our HELLO
44  */
45 struct GNUNET_MessageHeader *GDS_my_hello;
46
47 /**
48  * Handle to get our current HELLO.
49  */
50 static struct GNUNET_TRANSPORT_HelloGetHandle *ghh;
51
52 /**
53  * Hello address expiration
54  */
55 struct GNUNET_TIME_Relative hello_expiration;
56
57
58 /* Code shared between different DHT implementations */
59 #include "gnunet-service-dht_clients.c"
60
61
62 /**
63  * Receive the HELLO from transport service, free current and replace
64  * if necessary.
65  *
66  * @param cls NULL
67  * @param message HELLO message of peer
68  */
69 static void
70 process_hello (void *cls,
71                const struct GNUNET_MessageHeader *message)
72 {
73   GNUNET_free_non_null (GDS_my_hello);
74   GDS_my_hello = GNUNET_malloc (ntohs (message->size));
75   GNUNET_memcpy (GDS_my_hello,
76                  message,
77                  ntohs (message->size));
78 }
79
80
81 /**
82  * Task run during shutdown.
83  *
84  * @param cls unused
85  */
86 static void
87 shutdown_task (void *cls)
88 {
89   if (NULL != ghh)
90   {
91     GNUNET_TRANSPORT_hello_get_cancel (ghh);
92     ghh = NULL;
93   }
94   GDS_NEIGHBOURS_done ();
95   GDS_DATACACHE_done ();
96   GDS_ROUTING_done ();
97   GDS_HELLO_done ();
98   GDS_NSE_done ();
99   if (NULL != GDS_block_context)
100   {
101     GNUNET_BLOCK_context_destroy (GDS_block_context);
102     GDS_block_context = NULL;
103   }
104   if (NULL != GDS_stats)
105   {
106     GNUNET_STATISTICS_destroy (GDS_stats,
107                                GNUNET_YES);
108     GDS_stats = NULL;
109   }
110   GNUNET_free_non_null (GDS_my_hello);
111   GDS_my_hello = NULL;
112   GDS_CLIENTS_stop ();
113 }
114
115
116 /**
117  * Process dht requests.
118  *
119  * @param cls closure
120  * @param c configuration to use
121  * @param service the initialized service
122  */
123 static void
124 run (void *cls,
125      const struct GNUNET_CONFIGURATION_Handle *c,
126      struct GNUNET_SERVICE_Handle *service)
127 {
128   GDS_cfg = c;
129   GDS_service = service;
130   if (GNUNET_OK !=
131       GNUNET_CONFIGURATION_get_value_time (c,
132                                            "transport",
133                                            "HELLO_EXPIRATION",
134                                            &hello_expiration))
135   {
136     hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION;
137   }
138   GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg);
139   GDS_stats = GNUNET_STATISTICS_create ("dht",
140                                         GDS_cfg);
141   GNUNET_SERVICE_suspend (GDS_service);
142   GDS_CLIENTS_init ();
143   GDS_ROUTING_init ();
144   GDS_NSE_init ();
145   GDS_DATACACHE_init ();
146   GDS_HELLO_init ();
147   if (GNUNET_OK != GDS_NEIGHBOURS_init ())
148   {
149     shutdown_task (NULL);
150     return;
151   }
152   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
153                                  NULL);
154   ghh = GNUNET_TRANSPORT_hello_get (GDS_cfg,
155                                     GNUNET_TRANSPORT_AC_GLOBAL,
156                                     &process_hello,
157                                     NULL);
158 }
159
160
161 /* Finally, define the main method */
162 GDS_DHT_SERVICE_INIT("dht", &run);
163
164
165
166
167 /* end of gnunet-service-dht.c */