aboutsummaryrefslogtreecommitdiff
path: root/src/hostlist
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-07-31 15:42:37 +0000
committerChristian Grothoff <christian@grothoff.org>2016-07-31 15:42:37 +0000
commit406c7d2d2d126c994a1fff13470b1f96439c6f9d (patch)
treedc5e7c62a706d03cee32734a19e183b9eddf88e2 /src/hostlist
parent8b2a3260e6aafc2ad31c8b7bff5f7d25b57bfc14 (diff)
downloadgnunet-406c7d2d2d126c994a1fff13470b1f96439c6f9d.tar.gz
gnunet-406c7d2d2d126c994a1fff13470b1f96439c6f9d.zip
convering more services to new core MQ API
Diffstat (limited to 'src/hostlist')
-rw-r--r--src/hostlist/gnunet-daemon-hostlist.c129
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_client.c123
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_client.h15
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_server.c151
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_server.h6
-rw-r--r--src/hostlist/test_gnunet_daemon_hostlist_learning.c224
6 files changed, 347 insertions, 301 deletions
diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c
index 21fab323b..44db59949 100644
--- a/src/hostlist/gnunet-daemon-hostlist.c
+++ b/src/hostlist/gnunet-daemon-hostlist.c
@@ -47,12 +47,7 @@ static int provide_hostlist;
47/** 47/**
48 * Handle to hostlist server's connect handler 48 * Handle to hostlist server's connect handler
49 */ 49 */
50static GNUNET_CORE_ConnectEventHandler server_ch; 50static GNUNET_CORE_ConnecTEventHandler server_ch;
51
52/**
53 * Handle to hostlist server's disconnect handler
54 */
55static GNUNET_CORE_DisconnectEventHandler server_dh;
56 51
57#endif 52#endif
58 53
@@ -81,17 +76,17 @@ static struct GNUNET_CORE_Handle *core;
81/** 76/**
82 * Handle to the hostlist client's advertisement handler 77 * Handle to the hostlist client's advertisement handler
83 */ 78 */
84static GNUNET_CORE_MessageCallback client_adv_handler; 79static GNUNET_HOSTLIST_UriHandler client_adv_handler;
85 80
86/** 81/**
87 * Handle to hostlist client's connect handler 82 * Handle to hostlist client's connect handler
88 */ 83 */
89static GNUNET_CORE_ConnectEventHandler client_ch; 84static GNUNET_CORE_ConnecTEventHandler client_ch;
90 85
91/** 86/**
92 * Handle to hostlist client's disconnect handler 87 * Handle to hostlist client's disconnect handler
93 */ 88 */
94static GNUNET_CORE_DisconnectEventHandler client_dh; 89static GNUNET_CORE_DisconnecTEventHandler client_dh;
95 90
96GNUNET_NETWORK_STRUCT_BEGIN 91GNUNET_NETWORK_STRUCT_BEGIN
97 92
@@ -146,17 +141,49 @@ core_init (void *cls,
146 * Core handler for p2p hostlist advertisements 141 * Core handler for p2p hostlist advertisements
147 * 142 *
148 * @param cls closure 143 * @param cls closure
149 * @param peer identity of the sender
150 * @param message advertisement message we got 144 * @param message advertisement message we got
151 * @return #GNUNET_OK on success 145 * @return #GNUNET_OK if message is well-formed
152 */ 146 */
153static int 147static int
154advertisement_handler (void *cls, 148check_advertisement (void *cls,
155 const struct GNUNET_PeerIdentity *peer, 149 const struct GNUNET_MessageHeader *message)
156 const struct GNUNET_MessageHeader *message)
157{ 150{
151 size_t size;
152 size_t uri_size;
153 const char *uri;
154
155 size = ntohs (message->size);
156 if (size <= sizeof (struct GNUNET_MessageHeader))
157 {
158 GNUNET_break_op (0);
159 return GNUNET_SYSERR;
160 }
161 uri = (const char *) &message[1];
162 uri_size = size - sizeof (struct GNUNET_MessageHeader);
163 if (uri[uri_size - 1] != '\0')
164 {
165 GNUNET_break_op (0);
166 return GNUNET_SYSERR;
167 }
168 return GNUNET_OK;
169}
170
171
172/**
173 * Core handler for p2p hostlist advertisements
174 *
175 * @param cls closure
176 * @param message advertisement message we got
177 * @return #GNUNET_OK on success
178 */
179static void
180handle_advertisement (void *cls,
181 const struct GNUNET_MessageHeader *message)
182{
183 const char *uri = (const char *) &message[1];
184
158 GNUNET_assert (NULL != client_adv_handler); 185 GNUNET_assert (NULL != client_adv_handler);
159 return (*client_adv_handler) (cls, peer, message); 186 (void) (*client_adv_handler) (uri);
160} 187}
161 188
162 189
@@ -166,20 +193,33 @@ advertisement_handler (void *cls,
166 * 193 *
167 * @param cls closure 194 * @param cls closure
168 * @param peer peer identity this notification is about 195 * @param peer peer identity this notification is about
196 * @param mq queue for sending messages to @a peer
197 * @return peer
169 */ 198 */
170static void 199static void *
171connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer) 200connect_handler (void *cls,
201 const struct GNUNET_PeerIdentity *peer,
202 struct GNUNET_MQ_Handle *mq)
172{ 203{
173 if (0 == memcmp (&me, peer, sizeof (struct GNUNET_PeerIdentity))) 204 if (0 == memcmp (&me,
174 return; 205 peer,
206 sizeof (struct GNUNET_PeerIdentity)))
207 return NULL;
175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
176 "A new peer connected, notifying client and server\n"); 209 "A new peer connected, notifying client and server\n");
177 if (NULL != client_ch) 210 if (NULL != client_ch)
178 (*client_ch) (cls, peer); 211 GNUNET_assert (NULL ==
212 (*client_ch) (cls,
213 peer,
214 mq));
179#if HAVE_MHD 215#if HAVE_MHD
180 if (NULL != server_ch) 216 if (NULL != server_ch)
181 (*server_ch) (cls, peer); 217 GNUNET_assert (NULL ==
218 (*server_ch) (cls,
219 peer,
220 mq));
182#endif 221#endif
222 return (void *) peer;
183} 223}
184 224
185 225
@@ -192,18 +232,18 @@ connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer)
192 */ 232 */
193static void 233static void
194disconnect_handler (void *cls, 234disconnect_handler (void *cls,
195 const struct GNUNET_PeerIdentity *peer) 235 const struct GNUNET_PeerIdentity *peer,
236 void *internal_cls)
196{ 237{
197 if (0 == memcmp (&me, peer, sizeof (struct GNUNET_PeerIdentity))) 238 if (0 == memcmp (&me,
239 peer,
240 sizeof (struct GNUNET_PeerIdentity)))
198 return; 241 return;
199 /* call hostlist client disconnect handler */ 242 /* call hostlist client disconnect handler */
200 if (NULL != client_dh) 243 if (NULL != client_dh)
201 (*client_dh) (cls, peer); 244 (*client_dh) (cls,
202#if HAVE_MHD 245 peer,
203 /* call hostlist server disconnect handler */ 246 NULL);
204 if (NULL != server_dh)
205 (*server_dh) (cls, peer);
206#endif
207} 247}
208 248
209 249
@@ -220,7 +260,7 @@ cleaning_task (void *cls)
220 "Hostlist daemon is shutting down\n"); 260 "Hostlist daemon is shutting down\n");
221 if (NULL != core) 261 if (NULL != core)
222 { 262 {
223 GNUNET_CORE_disconnect (core); 263 GNUNET_CORE_disconnecT (core);
224 core = NULL; 264 core = NULL;
225 } 265 }
226 if (bootstrapping) 266 if (bootstrapping)
@@ -235,7 +275,8 @@ cleaning_task (void *cls)
235#endif 275#endif
236 if (NULL != stats) 276 if (NULL != stats)
237 { 277 {
238 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 278 GNUNET_STATISTICS_destroy (stats,
279 GNUNET_NO);
239 stats = NULL; 280 stats = NULL;
240 } 281 }
241} 282}
@@ -255,12 +296,15 @@ run (void *cls,
255 const char *cfgfile, 296 const char *cfgfile,
256 const struct GNUNET_CONFIGURATION_Handle *cfg) 297 const struct GNUNET_CONFIGURATION_Handle *cfg)
257{ 298{
258 static const struct GNUNET_CORE_MessageHandler learn_handlers[] = { 299 GNUNET_MQ_hd_var_size (advertisement,
259 {&advertisement_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0}, 300 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT,
260 {NULL, 0, 0} 301 struct GNUNET_MessageHeader);
302 struct GNUNET_MQ_MessageHandler learn_handlers[] = {
303 make_advertisement_handler (NULL),
304 GNUNET_MQ_handler_end ()
261 }; 305 };
262 static const struct GNUNET_CORE_MessageHandler no_learn_handlers[] = { 306 struct GNUNET_MQ_MessageHandler no_learn_handlers[] = {
263 {NULL, 0, 0} 307 GNUNET_MQ_handler_end ()
264 }; 308 };
265 if ((! bootstrapping) && (! learning) 309 if ((! bootstrapping) && (! learning)
266#if HAVE_MHD 310#if HAVE_MHD
@@ -279,24 +323,27 @@ run (void *cls,
279 return; 323 return;
280 } 324 }
281 if (bootstrapping) 325 if (bootstrapping)
282 GNUNET_HOSTLIST_client_start (cfg, stats, 326 GNUNET_HOSTLIST_client_start (cfg,
327 stats,
283 &client_ch, 328 &client_ch,
284 &client_dh, 329 &client_dh,
285 &client_adv_handler, 330 &client_adv_handler,
286 learning); 331 learning);
287 core = 332 core =
288 GNUNET_CORE_connect (cfg, NULL, 333 GNUNET_CORE_connecT (cfg,
334 NULL,
289 &core_init, 335 &core_init,
290 &connect_handler, 336 &connect_handler,
291 &disconnect_handler, 337 &disconnect_handler,
292 NULL, GNUNET_NO,
293 NULL, GNUNET_NO,
294 learning ? learn_handlers : no_learn_handlers); 338 learning ? learn_handlers : no_learn_handlers);
295 339
296 340
297#if HAVE_MHD 341#if HAVE_MHD
298 if (provide_hostlist) 342 if (provide_hostlist)
299 GNUNET_HOSTLIST_server_start (cfg, stats, core, &server_ch, &server_dh, 343 GNUNET_HOSTLIST_server_start (cfg,
344 stats,
345 core,
346 &server_ch,
300 advertising); 347 advertising);
301#endif 348#endif
302 GNUNET_SCHEDULER_add_shutdown (&cleaning_task, 349 GNUNET_SCHEDULER_add_shutdown (&cleaning_task,
diff --git a/src/hostlist/gnunet-daemon-hostlist_client.c b/src/hostlist/gnunet-daemon-hostlist_client.c
index 9f6413898..c1a2c2721 100644
--- a/src/hostlist/gnunet-daemon-hostlist_client.c
+++ b/src/hostlist/gnunet-daemon-hostlist_client.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2010, 2014 GNUnet e.V. 3 Copyright (C) 2001-2010, 2014, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -1187,14 +1187,20 @@ task_hostlist_saving (void *cls)
1187 * 1187 *
1188 * @param cls closure 1188 * @param cls closure
1189 * @param peer peer identity this notification is about 1189 * @param peer peer identity this notification is about
1190 * @param mq message queue for transmissions to @a peer
1190 */ 1191 */
1191static void 1192static void *
1192handler_connect (void *cls, const struct GNUNET_PeerIdentity *peer) 1193handler_connect (void *cls,
1194 const struct GNUNET_PeerIdentity *peer,
1195 struct GNUNET_MQ_Handle *mq)
1193{ 1196{
1194 GNUNET_assert (stat_connection_count < UINT_MAX); 1197 GNUNET_assert (stat_connection_count < UINT_MAX);
1195 stat_connection_count++; 1198 stat_connection_count++;
1196 GNUNET_STATISTICS_update (stats, gettext_noop ("# active connections"), 1, 1199 GNUNET_STATISTICS_update (stats,
1200 gettext_noop ("# active connections"),
1201 1,
1197 GNUNET_NO); 1202 GNUNET_NO);
1203 return NULL;
1198} 1204}
1199 1205
1200 1206
@@ -1205,11 +1211,15 @@ handler_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
1205 * @param peer peer identity this notification is about 1211 * @param peer peer identity this notification is about
1206 */ 1212 */
1207static void 1213static void
1208handler_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) 1214handler_disconnect (void *cls,
1215 const struct GNUNET_PeerIdentity *peer,
1216 void *internal_cls)
1209{ 1217{
1210 GNUNET_assert (stat_connection_count > 0); 1218 GNUNET_assert (stat_connection_count > 0);
1211 stat_connection_count--; 1219 stat_connection_count--;
1212 GNUNET_STATISTICS_update (stats, gettext_noop ("# active connections"), -1, 1220 GNUNET_STATISTICS_update (stats,
1221 gettext_noop ("# active connections"),
1222 -1,
1213 GNUNET_NO); 1223 GNUNET_NO);
1214} 1224}
1215 1225
@@ -1217,63 +1227,44 @@ handler_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
1217/** 1227/**
1218 * Method called whenever an advertisement message arrives. 1228 * Method called whenever an advertisement message arrives.
1219 * 1229 *
1220 * @param cls closure (always NULL) 1230 * @param uri the advertised URI
1221 * @param peer the peer sending the message
1222 * @param message the actual message
1223 * @return #GNUNET_OK to keep the connection open,
1224 * #GNUNET_SYSERR to close it (signal serious error)
1225 */ 1231 */
1226static int 1232static void
1227handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer, 1233handler_advertisement (const char *uri)
1228 const struct GNUNET_MessageHeader *message)
1229{ 1234{
1230 size_t size;
1231 size_t uri_size; 1235 size_t uri_size;
1232 const struct GNUNET_MessageHeader *incoming;
1233 const char *uri;
1234 struct Hostlist *hostlist; 1236 struct Hostlist *hostlist;
1235 1237
1236 GNUNET_assert (ntohs (message->type) == 1238 uri_size = strlen (uri) + 1;
1237 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT);
1238 size = ntohs (message->size);
1239 if (size <= sizeof (struct GNUNET_MessageHeader))
1240 {
1241 GNUNET_break_op (0);
1242 return GNUNET_SYSERR;
1243 }
1244 incoming = (const struct GNUNET_MessageHeader *) message;
1245 uri = (const char *) &incoming[1];
1246 uri_size = size - sizeof (struct GNUNET_MessageHeader);
1247 if (uri[uri_size - 1] != '\0')
1248 {
1249 GNUNET_break_op (0);
1250 return GNUNET_SYSERR;
1251 }
1252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1253 "Hostlist client recieved advertisement from `%s' containing URI `%s'\n", 1240 "Hostlist client recieved advertisement containing URI `%s'\n",
1254 GNUNET_i2s (peer), uri); 1241 uri);
1255 if (GNUNET_NO != linked_list_contains (uri)) 1242 if (GNUNET_NO != linked_list_contains (uri))
1256 { 1243 {
1257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URI `%s' is already known\n", uri); 1244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1258 return GNUNET_OK; 1245 "URI `%s' is already known\n",
1246 uri);
1247 return;
1259 } 1248 }
1260 1249
1261 if (GNUNET_NO == stat_testing_allowed) 1250 if (GNUNET_NO == stat_testing_allowed)
1262 { 1251 {
1263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1264 "Currently not accepting new advertisements: interval between to advertisements is not reached\n"); 1253 "Currently not accepting new advertisements: interval between to advertisements is not reached\n");
1265 return GNUNET_SYSERR; 1254 return;
1266 } 1255 }
1267 if (GNUNET_YES == stat_testing_hostlist) 1256 if (GNUNET_YES == stat_testing_hostlist)
1268 { 1257 {
1269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1258 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1270 "Currently not accepting new advertisements: we are already testing a hostlist\n"); 1259 "Currently not accepting new advertisements: we are already testing a hostlist\n");
1271 return GNUNET_SYSERR; 1260 return;
1272 } 1261 }
1273 1262
1274 hostlist = GNUNET_malloc (sizeof (struct Hostlist) + uri_size); 1263 hostlist = GNUNET_malloc (sizeof (struct Hostlist) + uri_size);
1275 hostlist->hostlist_uri = (const char *) &hostlist[1]; 1264 hostlist->hostlist_uri = (const char *) &hostlist[1];
1276 GNUNET_memcpy (&hostlist[1], uri, uri_size); 1265 GNUNET_memcpy (&hostlist[1],
1266 uri,
1267 uri_size);
1277 hostlist->time_creation = GNUNET_TIME_absolute_get (); 1268 hostlist->time_creation = GNUNET_TIME_absolute_get ();
1278 hostlist->quality = HOSTLIST_INITIAL; 1269 hostlist->quality = HOSTLIST_INITIAL;
1279 hostlist_to_test = hostlist; 1270 hostlist_to_test = hostlist;
@@ -1282,7 +1273,8 @@ handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer,
1282 stat_testing_allowed = GNUNET_NO; 1273 stat_testing_allowed = GNUNET_NO;
1283 ti_testing_intervall_task = 1274 ti_testing_intervall_task =
1284 GNUNET_SCHEDULER_add_delayed (TESTING_INTERVAL, 1275 GNUNET_SCHEDULER_add_delayed (TESTING_INTERVAL,
1285 &task_testing_intervall_reset, NULL); 1276 &task_testing_intervall_reset,
1277 NULL);
1286 1278
1287 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1288 "Testing new hostlist advertisements is locked for the next %s\n", 1280 "Testing new hostlist advertisements is locked for the next %s\n",
@@ -1290,9 +1282,8 @@ handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer,
1290 GNUNET_YES)); 1282 GNUNET_YES));
1291 1283
1292 ti_download_dispatcher_task = 1284 ti_download_dispatcher_task =
1293 GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL); 1285 GNUNET_SCHEDULER_add_now (&task_download_dispatcher,
1294 1286 NULL);
1295 return GNUNET_OK;
1296} 1287}
1297 1288
1298 1289
@@ -1557,9 +1548,9 @@ save_hostlist_file (int shutdown)
1557int 1548int
1558GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, 1549GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1559 struct GNUNET_STATISTICS_Handle *st, 1550 struct GNUNET_STATISTICS_Handle *st,
1560 GNUNET_CORE_ConnectEventHandler *ch, 1551 GNUNET_CORE_ConnecTEventHandler *ch,
1561 GNUNET_CORE_DisconnectEventHandler *dh, 1552 GNUNET_CORE_DisconnecTEventHandler *dh,
1562 GNUNET_CORE_MessageCallback *msgh, 1553 GNUNET_HOSTLIST_UriHandler *msgh,
1563 int learn) 1554 int learn)
1564{ 1555{
1565 char *filename; 1556 char *filename;
@@ -1578,23 +1569,31 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1578 /* Read proxy configuration */ 1569 /* Read proxy configuration */
1579 if (GNUNET_OK == 1570 if (GNUNET_OK ==
1580 GNUNET_CONFIGURATION_get_value_string (cfg, 1571 GNUNET_CONFIGURATION_get_value_string (cfg,
1581 "HOSTLIST", "PROXY", &proxy)) 1572 "HOSTLIST",
1573 "PROXY",
1574 &proxy))
1582 { 1575 {
1583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1576 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1584 "Found proxy host: `%s'\n", 1577 "Found proxy host: `%s'\n",
1585 proxy); 1578 proxy);
1586 /* proxy username */ 1579 /* proxy username */
1587 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, 1580 if (GNUNET_OK ==
1588 "HOSTLIST", "PROXY_USERNAME", &proxy_username)) 1581 GNUNET_CONFIGURATION_get_value_string (cfg,
1582 "HOSTLIST",
1583 "PROXY_USERNAME",
1584 &proxy_username))
1589 { 1585 {
1590 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1591 "Found proxy username name: `%s'\n", 1587 "Found proxy username name: `%s'\n",
1592 proxy_username); 1588 proxy_username);
1593 } 1589 }
1594 1590
1595 /* proxy password */ 1591 /* proxy password */
1596 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, 1592 if (GNUNET_OK ==
1597 "HOSTLIST", "PROXY_PASSWORD", &proxy_password)) 1593 GNUNET_CONFIGURATION_get_value_string (cfg,
1594 "HOSTLIST",
1595 "PROXY_PASSWORD",
1596 &proxy_password))
1598 { 1597 {
1599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1598 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1600 "Found proxy password name: `%s'\n", 1599 "Found proxy password name: `%s'\n",
@@ -1659,7 +1658,8 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1659 load_hostlist_file (); 1658 load_hostlist_file ();
1660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1661 "Hostlists will be saved to file again in %s\n", 1660 "Hostlists will be saved to file again in %s\n",
1662 GNUNET_STRINGS_relative_time_to_string (SAVING_INTERVAL, GNUNET_YES)); 1661 GNUNET_STRINGS_relative_time_to_string (SAVING_INTERVAL,
1662 GNUNET_YES));
1663 ti_saving_task = 1663 ti_saving_task =
1664 GNUNET_SCHEDULER_add_delayed (SAVING_INTERVAL, 1664 GNUNET_SCHEDULER_add_delayed (SAVING_INTERVAL,
1665 &task_hostlist_saving, 1665 &task_hostlist_saving,
@@ -1671,8 +1671,10 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1671 _("Learning is not enabled on this peer\n")); 1671 _("Learning is not enabled on this peer\n"));
1672 *msgh = NULL; 1672 *msgh = NULL;
1673 if (GNUNET_OK == 1673 if (GNUNET_OK ==
1674 GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", 1674 GNUNET_CONFIGURATION_get_value_filename (cfg,
1675 "HOSTLISTFILE", &filename)) 1675 "HOSTLIST",
1676 "HOSTLISTFILE",
1677 &filename))
1676 { 1678 {
1677 if (GNUNET_YES == GNUNET_DISK_file_test (filename)) 1679 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
1678 { 1680 {
@@ -1706,9 +1708,10 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1706 } 1708 }
1707 else 1709 else
1708 { 1710 {
1709 ti_check_download = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 1711 ti_check_download
1710 &stat_timeout_task, 1712 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1711 NULL); 1713 &stat_timeout_task,
1714 NULL);
1712 } 1715 }
1713 return GNUNET_OK; 1716 return GNUNET_OK;
1714} 1717}
diff --git a/src/hostlist/gnunet-daemon-hostlist_client.h b/src/hostlist/gnunet-daemon-hostlist_client.h
index 15e913adb..dd80d4a48 100644
--- a/src/hostlist/gnunet-daemon-hostlist_client.h
+++ b/src/hostlist/gnunet-daemon-hostlist_client.h
@@ -31,6 +31,15 @@
31 31
32 32
33/** 33/**
34 * Function that handles an advertised URI.
35 *
36 * @param uri 0-termianted URI of a hostlist
37 */
38typedef void
39(*GNUNET_HOSTLIST_UriHandler)(const char *uri);
40
41
42/**
34 * Start downloading hostlists from hostlist servers as necessary. 43 * Start downloading hostlists from hostlist servers as necessary.
35 * 44 *
36 * @param c configuration to use 45 * @param c configuration to use
@@ -44,9 +53,9 @@
44int 53int
45GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, 54GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
46 struct GNUNET_STATISTICS_Handle *st, 55 struct GNUNET_STATISTICS_Handle *st,
47 GNUNET_CORE_ConnectEventHandler *ch, 56 GNUNET_CORE_ConnecTEventHandler *ch,
48 GNUNET_CORE_DisconnectEventHandler *dh, 57 GNUNET_CORE_DisconnecTEventHandler *dh,
49 GNUNET_CORE_MessageCallback *msgh, 58 GNUNET_HOSTLIST_UriHandler *msgh,
50 int learn); 59 int learn);
51 60
52 61
diff --git a/src/hostlist/gnunet-daemon-hostlist_server.c b/src/hostlist/gnunet-daemon-hostlist_server.c
index 40820e557..b01dbc09e 100644
--- a/src/hostlist/gnunet-daemon-hostlist_server.c
+++ b/src/hostlist/gnunet-daemon-hostlist_server.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2008, 2009, 2010, 2014 GNUnet e.V. 3 Copyright (C) 2008, 2009, 2010, 2014, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -101,12 +101,6 @@ static int advertising;
101 */ 101 */
102static char *hostlist_uri; 102static char *hostlist_uri;
103 103
104/**
105 * Map of peer identities to `struct GNUNET_CORE_TransmitHandle *` for
106 * pending hostlist server advertisements.
107 */
108static struct GNUNET_CONTAINER_MultiPeerMap *advertisements;
109
110 104
111/** 105/**
112 * Context for #host_processor(). 106 * Context for #host_processor().
@@ -436,47 +430,34 @@ access_handler_callback (void *cls,
436 * @param buf buffer to copy message to 430 * @param buf buffer to copy message to
437 * @return number of bytes copied to @a buf 431 * @return number of bytes copied to @a buf
438 */ 432 */
439static size_t 433static void
440adv_transmit_ready (void *cls, 434adv_transmit (struct GNUNET_MQ_Handle *mq)
441 size_t size,
442 void *buf)
443{ 435{
444 const struct GNUNET_PeerIdentity *peer = cls;
445 static uint64_t hostlist_adv_count; 436 static uint64_t hostlist_adv_count;
446 size_t transmission_size; 437 const void *extra;
438 uint64_t flags;
447 size_t uri_size; /* Including \0 termination! */ 439 size_t uri_size; /* Including \0 termination! */
448 struct GNUNET_MessageHeader header; 440 struct GNUNET_MessageHeader *header;
449 char *cbuf; 441 struct GNUNET_MQ_Envelope *env;
450 struct GNUNET_CORE_TransmitHandle *th; 442
451 443 extra = GNUNET_CORE_get_mq_options (GNUNET_YES,
452 th = GNUNET_CONTAINER_multipeermap_get (advertisements, 444 GNUNET_CORE_PRIO_BEST_EFFORT,
453 peer); 445 &flags);
454 GNUNET_assert (NULL != th);
455 GNUNET_assert (GNUNET_YES ==
456 GNUNET_CONTAINER_multipeermap_remove (advertisements,
457 peer,
458 th));
459 if (NULL == buf)
460 {
461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
462 "Transmission failed, buffer invalid!\n");
463 return 0;
464 }
465 uri_size = strlen (hostlist_uri) + 1; 446 uri_size = strlen (hostlist_uri) + 1;
466 transmission_size = sizeof (struct GNUNET_MessageHeader) + uri_size; 447 env = GNUNET_MQ_msg_extra (header,
467 header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); 448 uri_size,
468 header.size = htons (transmission_size); 449 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT);
469 GNUNET_assert (size >= transmission_size); 450 GNUNET_memcpy (&header[1],
470 GNUNET_memcpy (buf, 451 hostlist_uri,
471 &header, 452 uri_size);
472 sizeof (struct GNUNET_MessageHeader)); 453 GNUNET_MQ_env_set_options (env,
473 cbuf = buf; 454 flags,
474 GNUNET_memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], 455 extra);
475 hostlist_uri, 456 GNUNET_MQ_send (mq,
476 uri_size); 457 env);
477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
478 "Sent advertisement message: Copied %u bytes into buffer!\n", 459 "Sent advertisement message: Copied %u bytes into buffer!\n",
479 (unsigned int) transmission_size); 460 (unsigned int) uri_size);
480 hostlist_adv_count++; 461 hostlist_adv_count++;
481 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 462 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
482 " # Sent advertisement message: %llu\n", 463 " # Sent advertisement message: %llu\n",
@@ -484,7 +465,6 @@ adv_transmit_ready (void *cls,
484 GNUNET_STATISTICS_update (stats, 465 GNUNET_STATISTICS_update (stats,
485 gettext_noop ("# hostlist advertisements send"), 1, 466 gettext_noop ("# hostlist advertisements send"), 1,
486 GNUNET_NO); 467 GNUNET_NO);
487 return transmission_size;
488} 468}
489 469
490 470
@@ -493,78 +473,39 @@ adv_transmit_ready (void *cls,
493 * 473 *
494 * @param cls closure 474 * @param cls closure
495 * @param peer peer identity this notification is about 475 * @param peer peer identity this notification is about
476 * @param mq queue for transmission to @a peer
477 * @return NULL (must!)
496 */ 478 */
497static void 479static void *
498connect_handler (void *cls, 480connect_handler (void *cls,
499 const struct GNUNET_PeerIdentity *peer) 481 const struct GNUNET_PeerIdentity *peer,
482 struct GNUNET_MQ_Handle *mq)
500{ 483{
501 size_t size; 484 size_t size;
502 struct GNUNET_CORE_TransmitHandle *th;
503 485
504 if (! advertising) 486 if (! advertising)
505 return; 487 return NULL;
506 if (NULL == hostlist_uri) 488 if (NULL == hostlist_uri)
507 return; 489 return NULL;
508 size = strlen (hostlist_uri) + 1; 490 size = strlen (hostlist_uri) + 1;
509 if (size + sizeof (struct GNUNET_MessageHeader) >= 491 if (size + sizeof (struct GNUNET_MessageHeader) >=
510 GNUNET_SERVER_MAX_MESSAGE_SIZE) 492 GNUNET_SERVER_MAX_MESSAGE_SIZE)
511 { 493 {
512 GNUNET_break (0); 494 GNUNET_break (0);
513 return; 495 return NULL;
514 } 496 }
515 size += sizeof (struct GNUNET_MessageHeader); 497 size += sizeof (struct GNUNET_MessageHeader);
516 if (NULL == core) 498 if (NULL == core)
517 { 499 {
518 GNUNET_break (0); 500 GNUNET_break (0);
519 return; 501 return NULL;
520 } 502 }
521 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
522 "Asked CORE to transmit advertisement message with a size of %u bytes to peer `%s'\n", 504 "Asked CORE to transmit advertisement message with a size of %u bytes to peer `%s'\n",
523 (unsigned int) size, 505 (unsigned int) size,
524 GNUNET_i2s (peer)); 506 GNUNET_i2s (peer));
525 if (NULL == 507 adv_transmit (mq);
526 (th = GNUNET_CORE_notify_transmit_ready (core, GNUNET_YES, 508 return NULL;
527 GNUNET_CORE_PRIO_BEST_EFFORT,
528 GNUNET_ADV_TIMEOUT,
529 peer,
530 size,
531 &adv_transmit_ready,
532 (void *) peer)) )
533 {
534 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
535 _("Advertisement message could not be queued by core\n"));
536 }
537 GNUNET_assert (GNUNET_YES ==
538 GNUNET_CONTAINER_multipeermap_put (advertisements,
539 peer,
540 th,
541 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
542}
543
544
545/**
546 * Method called whenever a given peer disconnects.
547 *
548 * @param cls closure
549 * @param peer peer identity this notification is about
550 */
551static void
552disconnect_handler (void *cls,
553 const struct GNUNET_PeerIdentity *peer)
554{
555 struct GNUNET_CORE_TransmitHandle *th;
556
557 if (! advertising)
558 return;
559 th = GNUNET_CONTAINER_multipeermap_get (advertisements,
560 peer);
561 if (NULL == th)
562 return;
563 GNUNET_assert (GNUNET_YES ==
564 GNUNET_CONTAINER_multipeermap_remove (advertisements,
565 peer,
566 th));
567 GNUNET_CORE_notify_transmit_ready_cancel (th);
568} 509}
569 510
570 511
@@ -696,7 +637,6 @@ prepare_daemon (struct MHD_Daemon *daemon_handle)
696 * @param st statistics handle to use 637 * @param st statistics handle to use
697 * @param co core handle to use 638 * @param co core handle to use
698 * @param[out] server_ch set to handler for CORE connect events 639 * @param[out] server_ch set to handler for CORE connect events
699 * @param[out] server_dh set to handler for CORE disconnect events
700 * @param advertise #GNUNET_YES if we should advertise our hostlist 640 * @param advertise #GNUNET_YES if we should advertise our hostlist
701 * @return #GNUNET_OK on success 641 * @return #GNUNET_OK on success
702 */ 642 */
@@ -704,8 +644,7 @@ int
704GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, 644GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
705 struct GNUNET_STATISTICS_Handle *st, 645 struct GNUNET_STATISTICS_Handle *st,
706 struct GNUNET_CORE_Handle *co, 646 struct GNUNET_CORE_Handle *co,
707 GNUNET_CORE_ConnectEventHandler *server_ch, 647 GNUNET_CORE_ConnecTEventHandler *server_ch,
708 GNUNET_CORE_DisconnectEventHandler *server_dh,
709 int advertise) 648 int advertise)
710{ 649{
711 unsigned long long port; 650 unsigned long long port;
@@ -730,8 +669,6 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
730 { 669 {
731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 670 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
732 "Advertising enabled on this hostlist server\n"); 671 "Advertising enabled on this hostlist server\n");
733 advertisements = GNUNET_CONTAINER_multipeermap_create (8,
734 GNUNET_NO);
735 } 672 }
736 cfg = c; 673 cfg = c;
737 stats = st; 674 stats = st;
@@ -797,11 +734,15 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
797 } 734 }
798 else 735 else
799 ipv4 = NULL; 736 ipv4 = NULL;
800 if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6")) 737 if (GNUNET_CONFIGURATION_have_value (cfg,
738 "HOSTLIST",
739 "BINDTOIPV6"))
801 { 740 {
802 if (GNUNET_OK != 741 if (GNUNET_OK !=
803 GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", 742 GNUNET_CONFIGURATION_get_value_string (cfg,
804 "BINDTOIP", &ipv6)) 743 "HOSTLIST",
744 "BINDTOIP",
745 &ipv6))
805 { 746 {
806 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 747 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
807 _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n")); 748 _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n"));
@@ -892,7 +833,6 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
892 833
893 core = co; 834 core = co;
894 *server_ch = &connect_handler; 835 *server_ch = &connect_handler;
895 *server_dh = &disconnect_handler;
896 if (NULL != daemon_handle_v4) 836 if (NULL != daemon_handle_v4)
897 hostlist_task_v4 = prepare_daemon (daemon_handle_v4); 837 hostlist_task_v4 = prepare_daemon (daemon_handle_v4);
898 if (NULL != daemon_handle_v6) 838 if (NULL != daemon_handle_v6)
@@ -958,13 +898,6 @@ GNUNET_HOSTLIST_server_stop ()
958 GNUNET_PEERINFO_disconnect (peerinfo); 898 GNUNET_PEERINFO_disconnect (peerinfo);
959 peerinfo = NULL; 899 peerinfo = NULL;
960 } 900 }
961 if (NULL != advertisements)
962 {
963 GNUNET_break (0 ==
964 GNUNET_CONTAINER_multipeermap_size (advertisements));
965 GNUNET_CONTAINER_multipeermap_destroy (advertisements);
966 advertisements = NULL;
967 }
968 cfg = NULL; 901 cfg = NULL;
969 stats = NULL; 902 stats = NULL;
970 core = NULL; 903 core = NULL;
diff --git a/src/hostlist/gnunet-daemon-hostlist_server.h b/src/hostlist/gnunet-daemon-hostlist_server.h
index f70e22fd9..f18ad0ca2 100644
--- a/src/hostlist/gnunet-daemon-hostlist_server.h
+++ b/src/hostlist/gnunet-daemon-hostlist_server.h
@@ -39,7 +39,6 @@
39 * @param st statistics handle to use 39 * @param st statistics handle to use
40 * @param co core handle to use 40 * @param co core handle to use
41 * @param[out] server_ch set to handler for CORE connect events 41 * @param[out] server_ch set to handler for CORE connect events
42 * @param[out] server_dh set to handler for CORE disconnect events
43 * @param advertise #GNUNET_YES if we should advertise our hostlist 42 * @param advertise #GNUNET_YES if we should advertise our hostlist
44 * @return #GNUNET_OK on success 43 * @return #GNUNET_OK on success
45 */ 44 */
@@ -47,9 +46,8 @@ int
47GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, 46GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
48 struct GNUNET_STATISTICS_Handle *st, 47 struct GNUNET_STATISTICS_Handle *st,
49 struct GNUNET_CORE_Handle *core, 48 struct GNUNET_CORE_Handle *core,
50 GNUNET_CORE_ConnectEventHandler *server_ch, 49 GNUNET_CORE_ConnecTEventHandler *server_ch,
51 GNUNET_CORE_DisconnectEventHandler *server_dh, 50 int advertise);
52 int advertise);
53 51
54 52
55/** 53/**
diff --git a/src/hostlist/test_gnunet_daemon_hostlist_learning.c b/src/hostlist/test_gnunet_daemon_hostlist_learning.c
index 54f219ad8..041898abd 100644
--- a/src/hostlist/test_gnunet_daemon_hostlist_learning.c
+++ b/src/hostlist/test_gnunet_daemon_hostlist_learning.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2009, 2010, 2011, 2012 GNUnet e.V. 3 Copyright (C) 2009, 2010, 2011, 2012, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -63,9 +63,9 @@ static char *current_adv_uri;
63 63
64static const struct GNUNET_CONFIGURATION_Handle *cfg; 64static const struct GNUNET_CONFIGURATION_Handle *cfg;
65 65
66static struct GNUNET_SCHEDULER_Task * timeout_task; 66static struct GNUNET_SCHEDULER_Task *timeout_task;
67 67
68static struct GNUNET_SCHEDULER_Task * check_task; 68static struct GNUNET_SCHEDULER_Task *check_task;
69 69
70static struct PeerContext adv_peer; 70static struct PeerContext adv_peer;
71 71
@@ -81,8 +81,9 @@ static struct GNUNET_STATISTICS_GetHandle *advsent_stat;
81static void 81static void
82shutdown_testcase () 82shutdown_testcase ()
83{ 83{
84 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown testcase....\n"); 84 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
85 if (timeout_task != NULL) 85 "Shutdown testcase....\n");
86 if (NULL != timeout_task)
86 { 87 {
87 GNUNET_SCHEDULER_cancel (timeout_task); 88 GNUNET_SCHEDULER_cancel (timeout_task);
88 timeout_task = NULL; 89 timeout_task = NULL;
@@ -112,7 +113,7 @@ shutdown_testcase ()
112 GNUNET_STATISTICS_destroy (learn_peer.stats, GNUNET_NO); 113 GNUNET_STATISTICS_destroy (learn_peer.stats, GNUNET_NO);
113 learn_peer.stats = NULL; 114 learn_peer.stats = NULL;
114 } 115 }
115 if (check_task != NULL) 116 if (NULL != check_task)
116 { 117 {
117 GNUNET_SCHEDULER_cancel (check_task); 118 GNUNET_SCHEDULER_cancel (check_task);
118 check_task = NULL; 119 check_task = NULL;
@@ -124,20 +125,24 @@ shutdown_testcase ()
124 } 125 }
125 if (NULL != adv_peer.core) 126 if (NULL != adv_peer.core)
126 { 127 {
127 GNUNET_CORE_disconnect (adv_peer.core); 128 GNUNET_CORE_disconnecT (adv_peer.core);
128 adv_peer.core = NULL; 129 adv_peer.core = NULL;
129 } 130 }
130 if (NULL != learn_peer.core) 131 if (NULL != learn_peer.core)
131 { 132 {
132 GNUNET_CORE_disconnect (learn_peer.core); 133 GNUNET_CORE_disconnecT (learn_peer.core);
133 learn_peer.core = NULL; 134 learn_peer.core = NULL;
134 } 135 }
135 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
136 "Killing hostlist server ARM process.\n"); 137 "Killing hostlist server ARM process.\n");
137 if (0 != GNUNET_OS_process_kill (adv_peer.arm_proc, GNUNET_TERM_SIG)) 138 if (0 != GNUNET_OS_process_kill (adv_peer.arm_proc,
138 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 139 GNUNET_TERM_SIG))
139 if (GNUNET_OS_process_wait (adv_peer.arm_proc) != GNUNET_OK) 140 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
140 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); 141 "kill");
142 if (GNUNET_OK !=
143 GNUNET_OS_process_wait (adv_peer.arm_proc))
144 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
145 "waitpid");
141 GNUNET_OS_process_destroy (adv_peer.arm_proc); 146 GNUNET_OS_process_destroy (adv_peer.arm_proc);
142 adv_peer.arm_proc = NULL; 147 adv_peer.arm_proc = NULL;
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -156,6 +161,7 @@ shutdown_testcase ()
156 "Shutdown complete....\n"); 161 "Shutdown complete....\n");
157} 162}
158 163
164
159/** 165/**
160 * Timeout, give up. 166 * Timeout, give up.
161 */ 167 */
@@ -185,10 +191,14 @@ do_shutdown (void *cls)
185 191
186 192
187static int 193static int
188process_downloads (void *cls, const char *subsystem, const char *name, 194process_downloads (void *cls,
189 uint64_t value, int is_persistent) 195 const char *subsystem,
196 const char *name,
197 uint64_t value,
198 int is_persistent)
190{ 199{
191 if ((value >= 2) && (learned_hostlist_downloaded == GNUNET_NO)) 200 if ( (value >= 2) &&
201 (GNUNET_NO == learned_hostlist_downloaded) )
192 { 202 {
193 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 203 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
194 "Peer has successfully downloaded advertised URI\n"); 204 "Peer has successfully downloaded advertised URI\n");
@@ -210,18 +220,25 @@ process_uris_recv_done (void *cls, int success)
210 220
211 221
212static int 222static int
213process_uris_recv (void *cls, const char *subsystem, const char *name, 223process_uris_recv (void *cls,
214 uint64_t value, int is_persistent) 224 const char *subsystem,
225 const char *name,
226 uint64_t value,
227 int is_persistent)
215{ 228{
216 if (((struct PeerContext *) cls == &learn_peer) && (value == 1) && 229 struct PeerContext *pc = cls;
217 (learned_hostlist_saved == GNUNET_NO)) 230 if ( (pc == &learn_peer) &&
231 (value == 1) &&
232 (learned_hostlist_saved == GNUNET_NO) )
218 { 233 {
219 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 234 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
220 "Peer has successfully saved advertised URI\n"); 235 "Peer has successfully saved advertised URI\n");
221 learned_hostlist_saved = GNUNET_YES; 236 learned_hostlist_saved = GNUNET_YES;
222 if ((learned_hostlist_downloaded == GNUNET_YES) && (adv_sent == GNUNET_YES)) 237 if ( (learned_hostlist_downloaded == GNUNET_YES) &&
238 (adv_sent == GNUNET_YES) )
223 { 239 {
224 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 240 GNUNET_SCHEDULER_add_now (&do_shutdown,
241 NULL);
225 } 242 }
226 } 243 }
227 return GNUNET_OK; 244 return GNUNET_OK;
@@ -239,7 +256,8 @@ static int
239process_adv_sent (void *cls, 256process_adv_sent (void *cls,
240 const char *subsystem, 257 const char *subsystem,
241 const char *name, 258 const char *name,
242 uint64_t value, int is_persistent) 259 uint64_t value,
260 int is_persistent)
243{ 261{
244 if ((value >= 1) && (adv_sent == GNUNET_NO)) 262 if ((value >= 1) && (adv_sent == GNUNET_NO))
245 { 263 {
@@ -249,7 +267,8 @@ process_adv_sent (void *cls,
249 if ((learned_hostlist_downloaded == GNUNET_YES) && 267 if ((learned_hostlist_downloaded == GNUNET_YES) &&
250 (learned_hostlist_saved == GNUNET_YES)) 268 (learned_hostlist_saved == GNUNET_YES))
251 { 269 {
252 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 270 GNUNET_SCHEDULER_add_now (&do_shutdown,
271 NULL);
253 } 272 }
254 } 273 }
255 return GNUNET_OK; 274 return GNUNET_OK;
@@ -273,8 +292,11 @@ check_statistics (void *cls)
273 if (NULL != download_stats) 292 if (NULL != download_stats)
274 GNUNET_STATISTICS_get_cancel (download_stats); 293 GNUNET_STATISTICS_get_cancel (download_stats);
275 download_stats = 294 download_stats =
276 GNUNET_STATISTICS_get (learn_peer.stats, "hostlist", stat, 295 GNUNET_STATISTICS_get (learn_peer.stats,
277 &process_downloads_done, &process_downloads, 296 "hostlist",
297 stat,
298 &process_downloads_done,
299 &process_downloads,
278 &learn_peer); 300 &learn_peer);
279 if (NULL != urisrecv_stat) 301 if (NULL != urisrecv_stat)
280 GNUNET_STATISTICS_get_cancel (urisrecv_stat); 302 GNUNET_STATISTICS_get_cancel (urisrecv_stat);
@@ -293,55 +315,64 @@ check_statistics (void *cls)
293 GNUNET_STATISTICS_get (adv_peer.stats, "hostlist", 315 GNUNET_STATISTICS_get (adv_peer.stats, "hostlist",
294 gettext_noop ("# hostlist advertisements send"), 316 gettext_noop ("# hostlist advertisements send"),
295 &process_adv_sent_done, 317 &process_adv_sent_done,
296 &process_adv_sent, NULL); 318 &process_adv_sent,
319 NULL);
297 } 320 }
298 check_task = 321 check_task =
299 GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL, &check_statistics, NULL); 322 GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL,
323 &check_statistics,
324 NULL);
300} 325}
301 326
302 327
303/**
304 * Core handler for p2p hostlist advertisements
305 */
306static int 328static int
307ad_arrive_handler (void *cls, 329check_ad_arrive (void *cls,
308 const struct GNUNET_PeerIdentity *peer, 330 const struct GNUNET_MessageHeader *message)
331{
332 const char *end = (const char *) &message[1];
333 if ('\0' != end[ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - 1])
334 {
335 GNUNET_break (0);
336 return GNUNET_SYSERR;
337 }
338 return GNUNET_OK;
339}
340
341
342static void
343handle_ad_arrive (void *cls,
309 const struct GNUNET_MessageHeader *message) 344 const struct GNUNET_MessageHeader *message)
310{ 345{
311 char *hostname; 346 char *hostname;
312 char *expected_uri; 347 char *expected_uri;
313 unsigned long long port; 348 unsigned long long port;
314 const struct GNUNET_MessageHeader *incoming;
315 const char *end; 349 const char *end;
316 350
317 if (-1 == 351 if (GNUNET_SYSERR ==
318 GNUNET_CONFIGURATION_get_value_number (adv_peer.cfg, "HOSTLIST", 352 GNUNET_CONFIGURATION_get_value_number (adv_peer.cfg,
319 "HTTPPORT", &port)) 353 "HOSTLIST",
354 "HTTPPORT",
355 &port))
320 { 356 {
321 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 357 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
322 "Could not read advertising server's configuration\n"); 358 "Could not read advertising server's configuration\n");
323 return GNUNET_SYSERR; 359 return;
324 } 360 }
325 361
326 if (GNUNET_SYSERR == 362 if (GNUNET_SYSERR ==
327 GNUNET_CONFIGURATION_get_value_string (adv_peer.cfg, "HOSTLIST", 363 GNUNET_CONFIGURATION_get_value_string (adv_peer.cfg,
328 "EXTERNAL_DNS_NAME", &hostname)) 364 "HOSTLIST",
365 "EXTERNAL_DNS_NAME",
366 &hostname))
329 hostname = GNUNET_RESOLVER_local_fqdn_get (); 367 hostname = GNUNET_RESOLVER_local_fqdn_get ();
330 GNUNET_asprintf (&expected_uri, "http://%s:%u/", 368 GNUNET_asprintf (&expected_uri,
369 "http://%s:%u/",
331 hostname != NULL ? hostname : "localhost", 370 hostname != NULL ? hostname : "localhost",
332 (unsigned int) port); 371 (unsigned int) port);
333 incoming = (const struct GNUNET_MessageHeader *) message; 372 end = (const char *) &message[1];
334 end = (const char *) &incoming[1];
335 if ('\0' !=
336 end[ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - 1])
337 {
338 GNUNET_break (0);
339 GNUNET_free (expected_uri);
340 GNUNET_free_non_null (hostname);
341 return GNUNET_SYSERR;
342 }
343 current_adv_uri = GNUNET_strdup (end); 373 current_adv_uri = GNUNET_strdup (end);
344 if (0 == strcmp (expected_uri, current_adv_uri)) 374 if (0 == strcmp (expected_uri,
375 current_adv_uri))
345 { 376 {
346 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 377 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
347 "Received hostlist advertisement with URI `%s' as expected\n", 378 "Received hostlist advertisement with URI `%s' as expected\n",
@@ -352,25 +383,24 @@ ad_arrive_handler (void *cls,
352 else 383 else
353 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 384 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
354 "Expected URI `%s' and received URI `%s' differ\n", 385 "Expected URI `%s' and received URI `%s' differ\n",
355 expected_uri, current_adv_uri); 386 expected_uri,
387 current_adv_uri);
356 GNUNET_free (expected_uri); 388 GNUNET_free (expected_uri);
357 GNUNET_free_non_null (hostname); 389 GNUNET_free_non_null (hostname);
358 return GNUNET_OK;
359} 390}
360 391
361 392
362/**
363 * List of handlers if we are learning.
364 */
365static struct GNUNET_CORE_MessageHandler learn_handlers[] = {
366 {&ad_arrive_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0},
367 {NULL, 0, 0}
368};
369
370
371static void 393static void
372setup_learn_peer (struct PeerContext *p, const char *cfgname) 394setup_learn_peer (struct PeerContext *p,
395 const char *cfgname)
373{ 396{
397 GNUNET_MQ_hd_var_size (ad_arrive,
398 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT,
399 struct GNUNET_MessageHeader);
400 struct GNUNET_MQ_MessageHandler learn_handlers[] = {
401 make_ad_arrive_handler (NULL),
402 GNUNET_MQ_handler_end ()
403 };
374 char *filename; 404 char *filename;
375 unsigned int result; 405 unsigned int result;
376 char *binary; 406 char *binary;
@@ -383,9 +413,13 @@ setup_learn_peer (struct PeerContext *p, const char *cfgname)
383 binary, 413 binary,
384 "gnunet-service-arm", 414 "gnunet-service-arm",
385 "-c", cfgname, NULL); 415 "-c", cfgname, NULL);
386 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); 416 GNUNET_assert (GNUNET_OK ==
417 GNUNET_CONFIGURATION_load (p->cfg,
418 cfgname));
387 if (GNUNET_OK == 419 if (GNUNET_OK ==
388 GNUNET_CONFIGURATION_get_value_string (p->cfg, "HOSTLIST", "HOSTLISTFILE", 420 GNUNET_CONFIGURATION_get_value_string (p->cfg,
421 "HOSTLIST",
422 "HOSTLISTFILE",
389 &filename)) 423 &filename))
390 { 424 {
391 if (GNUNET_YES == GNUNET_DISK_file_test (filename)) 425 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
@@ -393,34 +427,43 @@ setup_learn_peer (struct PeerContext *p, const char *cfgname)
393 result = UNLINK (filename); 427 result = UNLINK (filename);
394 if (result == 0) 428 if (result == 0)
395 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 429 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
396 _("Hostlist file `%s' was removed\n"), filename); 430 _("Hostlist file `%s' was removed\n"),
431 filename);
397 } 432 }
398 GNUNET_free (filename); 433 GNUNET_free (filename);
399 } 434 }
400 p->core = 435 p->core = GNUNET_CORE_connecT (p->cfg,
401 GNUNET_CORE_connect (p->cfg, NULL, NULL, NULL, NULL, NULL, GNUNET_NO, 436 NULL,
402 NULL, GNUNET_NO, learn_handlers); 437 NULL,
438 NULL,
439 NULL,
440 learn_handlers);
403 GNUNET_assert (NULL != p->core); 441 GNUNET_assert (NULL != p->core);
404 p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg); 442 p->stats = GNUNET_STATISTICS_create ("hostlist",
443 p->cfg);
405 GNUNET_assert (NULL != p->stats); 444 GNUNET_assert (NULL != p->stats);
406 GNUNET_free (binary); 445 GNUNET_free (binary);
407} 446}
408 447
409 448
410static void 449static void
411setup_adv_peer (struct PeerContext *p, const char *cfgname) 450setup_adv_peer (struct PeerContext *p,
451 const char *cfgname)
412{ 452{
413 char *binary; 453 char *binary;
414 454
415 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm"); 455 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
416 p->cfg = GNUNET_CONFIGURATION_create (); 456 p->cfg = GNUNET_CONFIGURATION_create ();
417 p->arm_proc = 457 p->arm_proc =
418 GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 458 GNUNET_OS_start_process (GNUNET_YES,
459 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
419 NULL, NULL, NULL, 460 NULL, NULL, NULL,
420 binary, 461 binary,
421 "gnunet-service-arm", 462 "gnunet-service-arm",
422 "-c", cfgname, NULL); 463 "-c", cfgname, NULL);
423 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); 464 GNUNET_assert (GNUNET_OK ==
465 GNUNET_CONFIGURATION_load (p->cfg,
466 cfgname));
424 p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg); 467 p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg);
425 GNUNET_assert (NULL != p->stats); 468 GNUNET_assert (NULL != p->stats);
426 GNUNET_free (binary); 469 GNUNET_free (binary);
@@ -428,7 +471,9 @@ setup_adv_peer (struct PeerContext *p, const char *cfgname)
428 471
429 472
430static void 473static void
431run (void *cls, char *const *args, const char *cfgfile, 474run (void *cls,
475 char *const *args,
476 const char *cfgfile,
432 const struct GNUNET_CONFIGURATION_Handle *c) 477 const struct GNUNET_CONFIGURATION_Handle *c)
433{ 478{
434 timeout = GNUNET_NO; 479 timeout = GNUNET_NO;
@@ -440,12 +485,17 @@ run (void *cls, char *const *args, const char *cfgfile,
440 485
441 cfg = c; 486 cfg = c;
442 487
443 setup_adv_peer (&adv_peer, "test_learning_adv_peer.conf"); 488 setup_adv_peer (&adv_peer,
444 setup_learn_peer (&learn_peer, "test_learning_learn_peer.conf"); 489 "test_learning_adv_peer.conf");
445 timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_error, NULL); 490 setup_learn_peer (&learn_peer,
446 491 "test_learning_learn_peer.conf");
492 timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
493 &timeout_error,
494 NULL);
447 check_task = 495 check_task =
448 GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL, &check_statistics, NULL); 496 GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL,
497 &check_statistics,
498 NULL);
449} 499}
450 500
451 501
@@ -463,13 +513,18 @@ check ()
463 GNUNET_GETOPT_OPTION_END 513 GNUNET_GETOPT_OPTION_END
464 }; 514 };
465 515
466 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, 516 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
467 "test-gnunet-daemon-hostlist-learning", "nohelp", options, 517 argv,
468 &run, NULL); 518 "test-gnunet-daemon-hostlist-learning",
519 "nohelp",
520 options,
521 &run,
522 NULL);
469 failed = GNUNET_NO; 523 failed = GNUNET_NO;
470 if (timeout == GNUNET_YES) 524 if (timeout == GNUNET_YES)
471 { 525 {
472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Testcase timeout\n"); 526 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
527 "Testcase timeout\n");
473 failed = GNUNET_YES; 528 failed = GNUNET_YES;
474 } 529 }
475 if (adv_arrived != GNUNET_YES) 530 if (adv_arrived != GNUNET_YES)
@@ -522,7 +577,8 @@ main (int argc, char *argv[])
522 ret = check (); 577 ret = check ();
523 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); 578 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1");
524 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); 579 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2");
525 if (GNUNET_YES == GNUNET_DISK_file_test ("hostlists_learn_peer.file")) 580 if (GNUNET_YES ==
581 GNUNET_DISK_file_test ("hostlists_learn_peer.file"))
526 { 582 {
527 if (0 == UNLINK ("hostlists_learn_peer.file")) 583 if (0 == UNLINK ("hostlists_learn_peer.file"))
528 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 584 GNUNET_log (GNUNET_ERROR_TYPE_INFO,