aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-06-29 16:09:49 +0200
committerChristian Grothoff <christian@grothoff.org>2018-06-29 16:09:49 +0200
commitb7a1d538eb03e2ac87149f2823c1e616b13bad93 (patch)
tree60d66bf6ad0f20753cafefe638d7342cdf2e0189 /src
parentb30b04c856bdf40136c5e1b39c5a455fc6c29f50 (diff)
parent06ee3c33943d100fa547624104221c282ab6f827 (diff)
downloadgnunet-b7a1d538eb03e2ac87149f2823c1e616b13bad93.tar.gz
gnunet-b7a1d538eb03e2ac87149f2823c1e616b13bad93.zip
Merge branch 'master' of git+ssh://gnunet.org/gnunet
Diffstat (limited to 'src')
-rw-r--r--src/ats/gnunet-service-ats_addresses.h2
-rw-r--r--src/cadet/cadet_api.c192
-rw-r--r--src/cadet/gnunet-cadet.c29
-rw-r--r--src/cadet/gnunet-service-cadet.c18
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c12
-rw-r--r--src/consensus/gnunet-service-consensus.c2
-rw-r--r--src/conversation/gnunet-conversation.c9
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/gnunet-service-core.c2
-rw-r--r--src/core/gnunet-service-core.h2
-rw-r--r--src/core/gnunet-service-core_kx.c6
-rw-r--r--src/core/gnunet-service-core_sessions.c2
-rw-r--r--src/core/gnunet-service-core_sessions.h2
-rw-r--r--src/datastore/perf_datastore_api.c2
-rw-r--r--src/datastore/plugin_datastore_mysql.c2
-rw-r--r--src/fs/gnunet-service-fs_cp.h2
-rw-r--r--src/gns/gnunet-bcd.c3
-rw-r--r--src/include/block_dns.h2
-rw-r--r--src/include/gnunet_common.h4
-rw-r--r--src/include/gnunet_core_service.h2
-rw-r--r--src/include/gnunet_dnsparser_lib.h53
-rw-r--r--src/include/gnunet_os_lib.h4
-rw-r--r--src/include/gnunet_psyc_service.h2
-rw-r--r--src/include/gnunet_secretsharing_service.h4
-rw-r--r--src/include/gnunet_signatures.h2
-rw-r--r--src/namestore/test_namestore_api_sqlite.conf2
-rw-r--r--src/nat/gnunet-helper-nat-server.c3
-rw-r--r--src/rps/gnunet-rps.c5
-rw-r--r--src/rps/gnunet-service-rps.c122
-rw-r--r--src/rps/gnunet-service-rps_custommap.c1
-rw-r--r--src/rps/gnunet-service-rps_sampler.c1
-rw-r--r--src/rps/rps-test_util.c6
-rw-r--r--src/rps/test_rps.c12
-rw-r--r--src/secretsharing/gnunet-service-secretsharing.c2
-rw-r--r--src/secretsharing/secretsharing_api.c4
-rw-r--r--src/secretsharing/secretsharing_protocol.h2
-rw-r--r--src/set/gnunet-service-set.h2
-rw-r--r--src/set/gnunet-service-set_intersection.c4
-rw-r--r--src/set/gnunet-service-set_union.c4
-rw-r--r--src/topology/gnunet-daemon-topology.c2
-rw-r--r--src/transport/gnunet-service-transport.c4
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c4
-rw-r--r--src/transport/transport.conf.in3
-rw-r--r--src/util/dnsparser.c116
-rw-r--r--src/util/dnsstub.c2
-rw-r--r--src/util/gnunet-service-resolver.c1173
-rw-r--r--src/util/os_priority.c6
-rw-r--r--src/util/resolver.h4
-rw-r--r--src/util/resolver_api.c26
49 files changed, 989 insertions, 883 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h
index d90ca1375..d4dc483eb 100644
--- a/src/ats/gnunet-service-ats_addresses.h
+++ b/src/ats/gnunet-service-ats_addresses.h
@@ -151,7 +151,7 @@
151 * 1.7 Address management 151 * 1.7 Address management
152 * 152 *
153 * Transport service notifies ATS about changes to the addresses known to 153 * Transport service notifies ATS about changes to the addresses known to
154 * him. 154 * it.
155 * 155 *
156 * 1.7.1 Adding an address 156 * 1.7.1 Adding an address
157 * 157 *
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index b019424f9..319279110 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -357,67 +357,52 @@ reconnect (struct GNUNET_CADET_Handle *h);
357 357
358 358
359/** 359/**
360 * Reconnect callback: tries to reconnect again after a failer previous 360 * Function called during #reconnect_cbk() to (re)open
361 * reconnecttion 361 * all ports that are still open.
362 *
363 * @param cls closure (cadet handle)
364 */
365static void
366reconnect_cbk (void *cls)
367{
368 struct GNUNET_CADET_Handle *h = cls;
369
370 h->reconnect_task = NULL;
371 reconnect (h);
372}
373
374
375/**
376 * Function called during #reconnect() to destroy
377 * all channels that are still open.
378 * 362 *
379 * @param cls the `struct GNUNET_CADET_Handle` 363 * @param cls the `struct GNUNET_CADET_Handle`
380 * @param cid chanenl ID 364 * @param id port ID
381 * @param value a `struct GNUNET_CADET_Channel` to destroy 365 * @param value a `struct GNUNET_CADET_Channel` to open
382 * @return #GNUNET_OK (continue to iterate) 366 * @return #GNUNET_OK (continue to iterate)
383 */ 367 */
384static int 368static int
385destroy_channel_on_reconnect_cb (void *cls, 369open_port_cb (void *cls,
386 uint32_t cid, 370 const struct GNUNET_HashCode *id,
387 void *value) 371 void *value)
388{ 372{
389 /* struct GNUNET_CADET_Handle *handle = cls; */ 373 struct GNUNET_CADET_Handle *h = cls;
390 struct GNUNET_CADET_Channel *ch = value; 374 struct GNUNET_CADET_Port *port = value;
375 struct GNUNET_CADET_PortMessage *msg;
376 struct GNUNET_MQ_Envelope *env;
391 377
392 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 378 (void) id;
393 "Destroying channel due to reconnect\n"); 379 env = GNUNET_MQ_msg (msg,
394 destroy_channel (ch); 380 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
381 msg->port = port->id;
382 GNUNET_MQ_send (h->mq,
383 env);
395 return GNUNET_OK; 384 return GNUNET_OK;
396} 385}
397 386
398 387
399/** 388/**
400 * Reconnect to the service, retransmit all infomation to try to restore the 389 * Reconnect callback: tries to reconnect again after a failer previous
401 * original state. 390 * reconnecttion
402 *
403 * @param h handle to the cadet
404 * 391 *
405 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...) 392 * @param cls closure (cadet handle)
406 */ 393 */
407static void 394static void
408schedule_reconnect (struct GNUNET_CADET_Handle *h) 395reconnect_cbk (void *cls)
409{ 396{
410 if (NULL != h->reconnect_task) 397 struct GNUNET_CADET_Handle *h = cls;
411 return; 398
412 GNUNET_CONTAINER_multihashmap32_iterate (h->channels, 399 h->reconnect_task = NULL;
413 &destroy_channel_on_reconnect_cb,
414 h);
415 h->reconnect_task
416 = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
417 &reconnect_cbk,
418 h);
419 h->reconnect_time 400 h->reconnect_time
420 = GNUNET_TIME_STD_BACKOFF (h->reconnect_time); 401 = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
402 reconnect (h);
403 GNUNET_CONTAINER_multihashmap_iterate (h->ports,
404 &open_port_cb,
405 h);
421} 406}
422 407
423 408
@@ -555,15 +540,16 @@ cadet_mq_error_handler (void *cls,
555{ 540{
556 struct GNUNET_CADET_Channel *ch = cls; 541 struct GNUNET_CADET_Channel *ch = cls;
557 542
558 GNUNET_break (0);
559 if (GNUNET_MQ_ERROR_NO_MATCH == error) 543 if (GNUNET_MQ_ERROR_NO_MATCH == error)
560 { 544 {
561 /* Got a message we did not understand, still try to continue! */ 545 /* Got a message we did not understand, still try to continue! */
546 GNUNET_break_op (0);
562 GNUNET_CADET_receive_done (ch); 547 GNUNET_CADET_receive_done (ch);
563 } 548 }
564 else 549 else
565 { 550 {
566 schedule_reconnect (ch->cadet); 551 GNUNET_break (0);
552 GNUNET_CADET_channel_destroy (ch);
567 } 553 }
568} 554}
569 555
@@ -581,6 +567,7 @@ cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq,
581{ 567{
582 struct GNUNET_CADET_Channel *ch = impl_state; 568 struct GNUNET_CADET_Channel *ch = impl_state;
583 569
570 (void) mq;
584 GNUNET_assert (NULL != ch->pending_env); 571 GNUNET_assert (NULL != ch->pending_env);
585 GNUNET_MQ_discard (ch->pending_env); 572 GNUNET_MQ_discard (ch->pending_env);
586 ch->pending_env = NULL; 573 ch->pending_env = NULL;
@@ -709,6 +696,7 @@ check_local_data (void *cls,
709{ 696{
710 uint16_t size; 697 uint16_t size;
711 698
699 (void) cls;
712 size = ntohs (message->header.size); 700 size = ntohs (message->header.size);
713 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size) 701 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
714 { 702 {
@@ -806,6 +794,32 @@ handle_local_ack (void *cls,
806 794
807 795
808/** 796/**
797 * Function called during #GNUNET_CADET_disconnect() to destroy
798 * all channels that are still open.
799 *
800 * @param cls the `struct GNUNET_CADET_Handle`
801 * @param cid chanenl ID
802 * @param value a `struct GNUNET_CADET_Channel` to destroy
803 * @return #GNUNET_OK (continue to iterate)
804 */
805static int
806destroy_channel_cb (void *cls,
807 uint32_t cid,
808 void *value)
809{
810 /* struct GNUNET_CADET_Handle *handle = cls; */
811 struct GNUNET_CADET_Channel *ch = value;
812
813 (void) cls;
814 (void) cid;
815 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
816 "Destroying channel due to GNUNET_CADET_disconnect()\n");
817 destroy_channel (ch);
818 return GNUNET_OK;
819}
820
821
822/**
809 * Generic error handler, called with the appropriate error code and 823 * Generic error handler, called with the appropriate error code and
810 * the same closure specified at the creation of the message queue. 824 * the same closure specified at the creation of the message queue.
811 * Not every message queue implementation supports an error handler. 825 * Not every message queue implementation supports an error handler.
@@ -822,9 +836,14 @@ handle_mq_error (void *cls,
822 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
823 "MQ ERROR: %u\n", 837 "MQ ERROR: %u\n",
824 error); 838 error);
839 GNUNET_CONTAINER_multihashmap32_iterate (h->channels,
840 &destroy_channel_cb,
841 h);
825 GNUNET_MQ_destroy (h->mq); 842 GNUNET_MQ_destroy (h->mq);
826 h->mq = NULL; 843 h->mq = NULL;
827 reconnect (h); 844 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
845 &reconnect_cbk,
846 h);
828} 847}
829 848
830 849
@@ -842,6 +861,7 @@ check_get_peers (void *cls,
842{ 861{
843 size_t esize; 862 size_t esize;
844 863
864 (void) cls;
845 esize = ntohs (message->size); 865 esize = ntohs (message->size);
846 if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == esize) 866 if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == esize)
847 return GNUNET_OK; 867 return GNUNET_OK;
@@ -895,11 +915,9 @@ check_get_peer (void *cls,
895 const struct GNUNET_CADET_LocalInfoPeer *message) 915 const struct GNUNET_CADET_LocalInfoPeer *message)
896{ 916{
897 size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer); 917 size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
898 const struct GNUNET_PeerIdentity *paths_array;
899 size_t esize; 918 size_t esize;
900 unsigned int epaths;
901 unsigned int peers;
902 919
920 (void) cls;
903 esize = ntohs (message->header.size); 921 esize = ntohs (message->header.size);
904 if (esize < msize) 922 if (esize < msize)
905 { 923 {
@@ -911,10 +929,6 @@ check_get_peer (void *cls,
911 GNUNET_break (0); 929 GNUNET_break (0);
912 return GNUNET_SYSERR; 930 return GNUNET_SYSERR;
913 } 931 }
914 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
915 epaths = ntohs (message->paths);
916 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
917
918 return GNUNET_OK; 932 return GNUNET_OK;
919} 933}
920 934
@@ -1166,38 +1180,6 @@ reconnect (struct GNUNET_CADET_Handle *h)
1166 handlers, 1180 handlers,
1167 &handle_mq_error, 1181 &handle_mq_error,
1168 h); 1182 h);
1169 if (NULL == h->mq)
1170 {
1171 schedule_reconnect (h);
1172 return;
1173 }
1174 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1175}
1176
1177
1178/**
1179 * Function called during #GNUNET_CADET_disconnect() to destroy
1180 * all channels that are still open.
1181 *
1182 * @param cls the `struct GNUNET_CADET_Handle`
1183 * @param cid chanenl ID
1184 * @param value a `struct GNUNET_CADET_Channel` to destroy
1185 * @return #GNUNET_OK (continue to iterate)
1186 */
1187static int
1188destroy_channel_cb (void *cls,
1189 uint32_t cid,
1190 void *value)
1191{
1192 /* struct GNUNET_CADET_Handle *handle = cls; */
1193 struct GNUNET_CADET_Channel *ch = value;
1194
1195 (void) cls;
1196 (void) cid;
1197 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1198 "Destroying channel due to GNUNET_CADET_disconnect()\n");
1199 destroy_channel (ch);
1200 return GNUNET_OK;
1201} 1183}
1202 1184
1203 1185
@@ -1219,6 +1201,7 @@ destroy_port_cb (void *cls,
1219 struct GNUNET_CADET_Port *port = value; 1201 struct GNUNET_CADET_Port *port = value;
1220 1202
1221 (void) cls; 1203 (void) cls;
1204 (void) id;
1222 /* This is a warning, the app should have cleanly closed all open ports */ 1205 /* This is a warning, the app should have cleanly closed all open ports */
1223 GNUNET_break (0); 1206 GNUNET_break (0);
1224 GNUNET_CADET_close_port (port); 1207 GNUNET_CADET_close_port (port);
@@ -1270,18 +1253,21 @@ GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1270void 1253void
1271GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p) 1254GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1272{ 1255{
1273 struct GNUNET_CADET_PortMessage *msg;
1274 struct GNUNET_MQ_Envelope *env;
1275
1276 GNUNET_assert (GNUNET_YES == 1256 GNUNET_assert (GNUNET_YES ==
1277 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports, 1257 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports,
1278 &p->id, 1258 &p->id,
1279 p)); 1259 p));
1280 env = GNUNET_MQ_msg (msg, 1260 if (NULL != p->cadet->mq)
1281 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE); 1261 {
1282 msg->port = p->id; 1262 struct GNUNET_CADET_PortMessage *msg;
1283 GNUNET_MQ_send (p->cadet->mq, 1263 struct GNUNET_MQ_Envelope *env;
1284 env); 1264
1265 env = GNUNET_MQ_msg (msg,
1266 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1267 msg->port = p->id;
1268 GNUNET_MQ_send (p->cadet->mq,
1269 env);
1270 }
1285 GNUNET_free_non_null (p->handlers); 1271 GNUNET_free_non_null (p->handlers);
1286 GNUNET_free (p); 1272 GNUNET_free (p);
1287} 1273}
@@ -1633,9 +1619,6 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
1633 return NULL; 1619 return NULL;
1634 } 1620 }
1635 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); 1621 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
1636 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1637 h->reconnect_task = NULL;
1638
1639 return h; 1622 return h;
1640} 1623}
1641 1624
@@ -1661,8 +1644,6 @@ GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1661 GNUNET_CADET_DisconnectEventHandler disconnects, 1644 GNUNET_CADET_DisconnectEventHandler disconnects,
1662 const struct GNUNET_MQ_MessageHandler *handlers) 1645 const struct GNUNET_MQ_MessageHandler *handlers)
1663{ 1646{
1664 struct GNUNET_CADET_PortMessage *msg;
1665 struct GNUNET_MQ_Envelope *env;
1666 struct GNUNET_CADET_Port *p; 1647 struct GNUNET_CADET_Port *p;
1667 1648
1668 GNUNET_assert (NULL != connects); 1649 GNUNET_assert (NULL != connects);
@@ -1688,13 +1669,11 @@ GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1688 p->window_changes = window_changes; 1669 p->window_changes = window_changes;
1689 p->disconnects = disconnects; 1670 p->disconnects = disconnects;
1690 p->handlers = GNUNET_MQ_copy_handlers (handlers); 1671 p->handlers = GNUNET_MQ_copy_handlers (handlers);
1691 1672
1692 1673 GNUNET_assert (GNUNET_OK ==
1693 env = GNUNET_MQ_msg (msg, 1674 open_port_cb (h,
1694 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN); 1675 &p->id,
1695 msg->port = p->id; 1676 p));
1696 GNUNET_MQ_send (h->mq,
1697 env);
1698 return p; 1677 return p;
1699} 1678}
1700 1679
@@ -1753,7 +1732,8 @@ GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1753 handlers, 1732 handlers,
1754 &cadet_mq_error_handler, 1733 &cadet_mq_error_handler,
1755 ch); 1734 ch);
1756 GNUNET_MQ_set_handlers_closure (ch->mq, channel_cls); 1735 GNUNET_MQ_set_handlers_closure (ch->mq,
1736 channel_cls);
1757 1737
1758 /* Request channel creation to service */ 1738 /* Request channel creation to service */
1759 env = GNUNET_MQ_msg (msg, 1739 env = GNUNET_MQ_msg (msg,
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c
index 67cebf02b..13b04b885 100644
--- a/src/cadet/gnunet-cadet.c
+++ b/src/cadet/gnunet-cadet.c
@@ -27,6 +27,7 @@
27#include "gnunet_cadet_service.h" 27#include "gnunet_cadet_service.h"
28#include "cadet.h" 28#include "cadet.h"
29 29
30#define STREAM_BUFFER_SIZE 1024 // Pakets
30 31
31/** 32/**
32 * Option -P. 33 * Option -P.
@@ -123,6 +124,8 @@ static struct GNUNET_SCHEDULER_Task *rd_task;
123 */ 124 */
124static struct GNUNET_SCHEDULER_Task *job; 125static struct GNUNET_SCHEDULER_Task *job;
125 126
127static unsigned int sent_pkt;
128
126 129
127/** 130/**
128 * Wait for input on STDIO and send it out over the #ch. 131 * Wait for input on STDIO and send it out over the #ch.
@@ -228,6 +231,12 @@ shutdown_task (void *cls)
228 } 231 }
229} 232}
230 233
234void
235mq_cb(void *cls)
236{
237 listen_stdio ();
238}
239
231 240
232/** 241/**
233 * Task run in stdio mode, after some data is available at stdin. 242 * Task run in stdio mode, after some data is available at stdin.
@@ -248,6 +257,8 @@ read_stdio (void *cls)
248 60000); 257 60000);
249 if (data_size < 1) 258 if (data_size < 1)
250 { 259 {
260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
261 "read() returned %s\n", strerror(errno));
251 GNUNET_SCHEDULER_shutdown(); 262 GNUNET_SCHEDULER_shutdown();
252 return; 263 return;
253 } 264 }
@@ -262,9 +273,21 @@ read_stdio (void *cls)
262 data_size); 273 data_size);
263 GNUNET_MQ_send (GNUNET_CADET_get_mq (ch), 274 GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
264 env); 275 env);
276
277 sent_pkt++;
278
265 if (GNUNET_NO == echo) 279 if (GNUNET_NO == echo)
266 { 280 {
267 listen_stdio (); 281 // Use MQ's notification if too much data of stdin is pooring in too fast.
282 if (STREAM_BUFFER_SIZE < sent_pkt)
283 {
284 GNUNET_MQ_notify_sent (env, mq_cb, cls);
285 sent_pkt = 0;
286 }
287 else
288 {
289 listen_stdio ();
290 }
268 } 291 }
269 else 292 else
270 { 293 {
@@ -554,9 +577,9 @@ peer_callback (void *cls,
554 }else{ 577 }else{
555 p = paths; 578 p = paths;
556 FPRINTF (stdout, 579 FPRINTF (stdout,
557 "Path with offset %u: ", 580 "Indirekt path with offset %u: ",
558 offset); 581 offset);
559 for (i = 0; i < offset && NULL != p;) 582 for (i = 0; i <= offset && NULL != p;)
560 { 583 {
561 FPRINTF (stdout, 584 FPRINTF (stdout,
562 "%s ", 585 "%s ",
diff --git a/src/cadet/gnunet-service-cadet.c b/src/cadet/gnunet-service-cadet.c
index dd693731f..4568d2733 100644
--- a/src/cadet/gnunet-service-cadet.c
+++ b/src/cadet/gnunet-service-cadet.c
@@ -881,7 +881,7 @@ path_info_iterator (void *cls,
881 unsigned int path_length; 881 unsigned int path_length;
882 882
883 path_length = GCPP_get_length (path); 883 path_length = GCPP_get_length (path);
884 path_size = sizeof (struct GNUNET_PeerIdentity) * (path_length - 1); 884 path_size = sizeof (struct GNUNET_PeerIdentity) * path_length;
885 if (sizeof (*resp) + path_size > UINT16_MAX) 885 if (sizeof (*resp) + path_size > UINT16_MAX)
886 { 886 {
887 LOG (GNUNET_ERROR_TYPE_WARNING, 887 LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -902,9 +902,9 @@ path_info_iterator (void *cls,
902 /* Don't copy first peer. First peer is always the local one. Last 902 /* Don't copy first peer. First peer is always the local one. Last
903 * peer is always the destination (leave as 0, EOL). 903 * peer is always the destination (leave as 0, EOL).
904 */ 904 */
905 for (i = 0; i < off; i++) 905 for (i = 0; i <= off; i++)
906 id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path, 906 id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path,
907 i + 1)); 907 i));
908 GNUNET_MQ_send (mq, 908 GNUNET_MQ_send (mq,
909 env); 909 env);
910 return GNUNET_YES; 910 return GNUNET_YES;
@@ -927,29 +927,23 @@ get_peer_info (void *cls,
927 struct CadetClient *c = cls; 927 struct CadetClient *c = cls;
928 struct GNUNET_MQ_Envelope *env; 928 struct GNUNET_MQ_Envelope *env;
929 struct GNUNET_CADET_LocalInfoPeer *msg; 929 struct GNUNET_CADET_LocalInfoPeer *msg;
930
931 930
932 env = GNUNET_MQ_msg (msg, 931 env = GNUNET_MQ_msg (msg,
933 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); 932 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
934
935 msg->offset = htons(0); 933 msg->offset = htons(0);
936 msg->destination = *peer; 934 msg->destination = *peer;
937 msg->paths = htons (GCP_count_paths (p)); 935 msg->paths = htons (GCP_count_paths (p));
938 msg->tunnel = htons (NULL != GCP_get_tunnel (p, 936 msg->tunnel = htons (NULL != GCP_get_tunnel (p,
939 GNUNET_NO)); 937 GNUNET_NO));
940 msg->finished_with_paths = htons(0); 938 msg->finished_with_paths = htons(0);
941
942 GNUNET_MQ_send (c->mq, 939 GNUNET_MQ_send (c->mq,
943 env); 940 env);
944 941 GCP_iterate_indirect_paths (p,
945 GCP_iterate_indirect_paths(p, 942 &path_info_iterator,
946 &path_info_iterator, 943 c->mq);
947 c->mq);
948
949} 944}
950 945
951 946
952
953/** 947/**
954 * Handler for client's SHOW_PEER request. 948 * Handler for client's SHOW_PEER request.
955 * 949 *
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index 8e536e376..b375d51ca 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -243,7 +243,17 @@ GCP_2s (const struct CadetPeer *cp)
243 static char buf[5]; 243 static char buf[5];
244 char *ret; 244 char *ret;
245 245
246 if ((NULL == cp) ||
247 (NULL == &cp->pid.public_key))
248 return "NULL";
249
250
246 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&cp->pid.public_key); 251 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&cp->pid.public_key);
252
253 if (NULL == ret)
254 return "NULL";
255
256
247 strncpy (buf, 257 strncpy (buf,
248 ret, 258 ret,
249 sizeof (buf) - 1); 259 sizeof (buf) - 1);
@@ -1207,6 +1217,8 @@ GCP_iterate_paths (struct CadetPeer *cp,
1207 (NULL == cp->core_mq) ? "" : " including direct link"); 1217 (NULL == cp->core_mq) ? "" : " including direct link");
1208 if (NULL != cp->core_mq) 1218 if (NULL != cp->core_mq)
1209 { 1219 {
1220 /* FIXME: this branch seems to duplicate the
1221 i=0 case below (direct link). Leave out!??? -CG */
1210 struct CadetPeerPath *path; 1222 struct CadetPeerPath *path;
1211 1223
1212 path = GCPP_get_path_from_route (1, 1224 path = GCPP_get_path_from_route (1,
diff --git a/src/consensus/gnunet-service-consensus.c b/src/consensus/gnunet-service-consensus.c
index 86d056aaf..afbefdc5a 100644
--- a/src/consensus/gnunet-service-consensus.c
+++ b/src/consensus/gnunet-service-consensus.c
@@ -2821,7 +2821,7 @@ construct_task_graph_gradecast (struct ConsensusSession *session,
2821 } 2821 }
2822 /* We run this task to make sure that the leader 2822 /* We run this task to make sure that the leader
2823 has the stored the SET_KIND_LEADER set of himself, 2823 has the stored the SET_KIND_LEADER set of himself,
2824 so he can participate in the rest of the gradecast 2824 so it can participate in the rest of the gradecast
2825 without the code having to handle any special cases. */ 2825 without the code having to handle any special cases. */
2826 task = ((struct TaskEntry) { 2826 task = ((struct TaskEntry) {
2827 .step = step, 2827 .step = step,
diff --git a/src/conversation/gnunet-conversation.c b/src/conversation/gnunet-conversation.c
index 92a435d55..bb4946720 100644
--- a/src/conversation/gnunet-conversation.c
+++ b/src/conversation/gnunet-conversation.c
@@ -264,6 +264,13 @@ phone_event_handler (void *cls,
264 switch (code) 264 switch (code)
265 { 265 {
266 case GNUNET_CONVERSATION_EC_PHONE_RING: 266 case GNUNET_CONVERSATION_EC_PHONE_RING:
267 /*
268 * FIXME: we should be playing our ringtones from contrib/sounds now!
269 *
270 ring_my_bell();
271 *
272 * see https://gstreamer.freedesktop.org/documentation/application-development/highlevel/playback-components.html on how to play a wav using the gst framework being used here
273 */
267 FPRINTF (stdout, 274 FPRINTF (stdout,
268 _("Incoming call from `%s'. Please /accept %u or /cancel %u the call.\n"), 275 _("Incoming call from `%s'. Please /accept %u or /cancel %u the call.\n"),
269 GNUNET_GNSRECORD_pkey_to_zkey (caller_id), 276 GNUNET_GNSRECORD_pkey_to_zkey (caller_id),
@@ -717,7 +724,7 @@ do_status (const char *args)
717 break; 724 break;
718 case CS_RINGING: 725 case CS_RINGING:
719 FPRINTF (stdout, 726 FPRINTF (stdout,
720 _("We are calling `%s', his phone should be ringing.\n"), 727 _("We are calling `%s', their phone should be ringing.\n"),
721 peer_name); 728 peer_name);
722 break; 729 break;
723 case CS_CONNECTED: 730 case CS_CONNECTED:
diff --git a/src/core/core.h b/src/core/core.h
index a2c05d4af..2ce77244e 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -172,7 +172,7 @@ struct DisconnectNotifyMessage
172 * messages being received or transmitted. This overall message is 172 * messages being received or transmitted. This overall message is
173 * followed by the real message, or just the header of the real 173 * followed by the real message, or just the header of the real
174 * message (depending on the client's preferences). The receiver can 174 * message (depending on the client's preferences). The receiver can
175 * tell if he got the full message or only a partial message by 175 * tell if it got the full message or only a partial message by
176 * looking at the size field in the header of NotifyTrafficMessage and 176 * looking at the size field in the header of NotifyTrafficMessage and
177 * checking it with the size field in the message that follows. 177 * checking it with the size field in the message that follows.
178 */ 178 */
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 0afc75add..a033f9fac 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -230,7 +230,7 @@ handle_client_init (void *cls,
230/** 230/**
231 * We will never be ready to transmit the given message in (disconnect 231 * We will never be ready to transmit the given message in (disconnect
232 * or invalid request). Frees resources associated with @a car. We 232 * or invalid request). Frees resources associated with @a car. We
233 * don't explicitly tell the client, he'll learn with the disconnect 233 * don't explicitly tell the client, it'll learn with the disconnect
234 * (or violated the protocol). 234 * (or violated the protocol).
235 * 235 *
236 * @param car request that now permanently failed; the 236 * @param car request that now permanently failed; the
diff --git a/src/core/gnunet-service-core.h b/src/core/gnunet-service-core.h
index 81e73ec39..fd1a88e75 100644
--- a/src/core/gnunet-service-core.h
+++ b/src/core/gnunet-service-core.h
@@ -113,7 +113,7 @@ GSC_CLIENTS_solicit_request (struct GSC_ClientActiveRequest *car);
113/** 113/**
114 * We will never be ready to transmit the given message in (disconnect 114 * We will never be ready to transmit the given message in (disconnect
115 * or invalid request). Frees resources associated with @a car. We 115 * or invalid request). Frees resources associated with @a car. We
116 * don't explicitly tell the client, he'll learn with the disconnect 116 * don't explicitly tell the client, it'll learn with the disconnect
117 * (or violated the protocol). 117 * (or violated the protocol).
118 * 118 *
119 * @param car request that now permanently failed; the 119 * @param car request that now permanently failed; the
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index 6e713cf61..c017e0c23 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -123,7 +123,7 @@ struct EphemeralKeyMessage
123 123
124 124
125/** 125/**
126 * We're sending an (encrypted) PING to the other peer to check if he 126 * We're sending an (encrypted) PING to the other peer to check if it
127 * can decrypt. The other peer should respond with a PONG with the 127 * can decrypt. The other peer should respond with a PONG with the
128 * same content, except this time encrypted with the receiver's key. 128 * same content, except this time encrypted with the receiver's key.
129 */ 129 */
@@ -854,8 +854,8 @@ handle_transport_notify_connect (void *cls,
854 } 854 }
855 else 855 else
856 { 856 {
857 /* peer with "higher" identity starts a delayed KX, if the "lower" peer 857 /* peer with "higher" identity starts a delayed KX, if the "lower" peer
858 * does not start a KX since he sees no reasons to do so */ 858 * does not start a KX since it sees no reasons to do so */
859 kx->retry_set_key_task 859 kx->retry_set_key_task
860 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 860 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
861 &set_key_retry_task, 861 &set_key_retry_task,
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c
index 41fe4dfb7..16f9a092d 100644
--- a/src/core/gnunet-service-core_sessions.c
+++ b/src/core/gnunet-service-core_sessions.c
@@ -356,7 +356,7 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
356 356
357 357
358/** 358/**
359 * The other peer has indicated that he 'lost' the session 359 * The other peer has indicated that it 'lost' the session
360 * (KX down), reinitialize the session on our end, in particular 360 * (KX down), reinitialize the session on our end, in particular
361 * this means to restart the typemap transmission. 361 * this means to restart the typemap transmission.
362 * 362 *
diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h
index 845edac69..be862b71f 100644
--- a/src/core/gnunet-service-core_sessions.h
+++ b/src/core/gnunet-service-core_sessions.h
@@ -40,7 +40,7 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
40 40
41 41
42/** 42/**
43 * The other peer has indicated that he 'lost' the session 43 * The other peer has indicated that it 'lost' the session
44 * (KX down), reinitialize the session on our end, in particular 44 * (KX down), reinitialize the session on our end, in particular
45 * this means to restart the typemap transmission. 45 * this means to restart the typemap transmission.
46 * 46 *
diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c
index f659dedff..6a0ff231b 100644
--- a/src/datastore/perf_datastore_api.c
+++ b/src/datastore/perf_datastore_api.c
@@ -172,7 +172,7 @@ struct CpsRunContext
172 172
173 /** 173 /**
174 * Counts the number of items put in the current phase. 174 * Counts the number of items put in the current phase.
175 * Once it hits #PUT_10, we progress tot he #RP_CUT phase 175 * Once it hits #PUT_10, we progress to the #RP_CUT phase
176 * or are done if @e i reaches #ITERATIONS. 176 * or are done if @e i reaches #ITERATIONS.
177 */ 177 */
178 unsigned int j; 178 unsigned int j;
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index b09fd1af3..3568ebe8f 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -76,7 +76,7 @@
76 * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic 76 * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic
77 * link. Even greater security risk can be achieved by setting no 77 * link. Even greater security risk can be achieved by setting no
78 * password for $USER. Luckily $USER has only priviledges to mess 78 * password for $USER. Luckily $USER has only priviledges to mess
79 * up GNUnet's tables, nothing else (unless you give him more, 79 * up GNUnet's tables, nothing else (unless you give them more,
80 * of course).<p> 80 * of course).<p>
81 * 81 *
82 * 4) Still, perhaps you should briefly try if the DB connection 82 * 4) Still, perhaps you should briefly try if the DB connection
diff --git a/src/fs/gnunet-service-fs_cp.h b/src/fs/gnunet-service-fs_cp.h
index 5e98f4940..dc7e03f4a 100644
--- a/src/fs/gnunet-service-fs_cp.h
+++ b/src/fs/gnunet-service-fs_cp.h
@@ -84,7 +84,7 @@ struct GSF_PeerPerformanceData
84 84
85 /** 85 /**
86 * If we get content we already have from this peer, for how 86 * If we get content we already have from this peer, for how
87 * long do we block him? Adjusted based on the fraction of 87 * long do we block it? Adjusted based on the fraction of
88 * redundant data we receive, between 1s and 1h. 88 * redundant data we receive, between 1s and 1h.
89 */ 89 */
90 struct GNUNET_TIME_Relative migration_delay; 90 struct GNUNET_TIME_Relative migration_delay;
diff --git a/src/gns/gnunet-bcd.c b/src/gns/gnunet-bcd.c
index 5279e83a4..9737e1a49 100644
--- a/src/gns/gnunet-bcd.c
+++ b/src/gns/gnunet-bcd.c
@@ -469,7 +469,7 @@ run (void *cls,
469 "open", 469 "open",
470 fn); 470 fn);
471 GNUNET_free (fn); 471 GNUNET_free (fn);
472 CLOSE (fd); 472 GNUNET_break (0 == CLOSE (fd));
473 return; 473 return;
474 } 474 }
475 GNUNET_free (fn); 475 GNUNET_free (fn);
@@ -499,6 +499,7 @@ run (void *cls,
499 return; 499 return;
500 GNUNET_SCHEDULER_add_shutdown (&server_stop, 500 GNUNET_SCHEDULER_add_shutdown (&server_stop,
501 NULL); 501 NULL);
502 GNUNET_break (0 == CLOSE(fd));
502} 503}
503 504
504 505
diff --git a/src/include/block_dns.h b/src/include/block_dns.h
index f54a51232..234ed502d 100644
--- a/src/include/block_dns.h
+++ b/src/include/block_dns.h
@@ -38,7 +38,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
38struct GNUNET_DNS_Advertisement 38struct GNUNET_DNS_Advertisement
39{ 39{
40 /** 40 /**
41 * Signature of the peer affirming that he is offering the service. 41 * Signature of the peer affirming that it is offering the service.
42 */ 42 */
43 struct GNUNET_CRYPTO_EddsaSignature signature; 43 struct GNUNET_CRYPTO_EddsaSignature signature;
44 44
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index b4bf5b0aa..1b982cc15 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -1074,7 +1074,7 @@ GNUNET_ntoh_double (double d);
1074 * @param tsize the target size for the resulting vector, use 0 to 1074 * @param tsize the target size for the resulting vector, use 0 to
1075 * free the vector (then, arr will be NULL afterwards). 1075 * free the vector (then, arr will be NULL afterwards).
1076 */ 1076 */
1077#define GNUNET_array_grow(arr,size,tsize) GNUNET_xgrow_((void**)&arr, sizeof(arr[0]), &size, tsize, __FILE__, __LINE__) 1077#define GNUNET_array_grow(arr,size,tsize) GNUNET_xgrow_((void**)&(arr), sizeof((arr)[0]), &size, tsize, __FILE__, __LINE__)
1078 1078
1079/** 1079/**
1080 * @ingroup memory 1080 * @ingroup memory
@@ -1089,7 +1089,7 @@ GNUNET_ntoh_double (double d);
1089 * array size 1089 * array size
1090 * @param element the element that will be appended to the array 1090 * @param element the element that will be appended to the array
1091 */ 1091 */
1092#define GNUNET_array_append(arr,size,element) do { GNUNET_array_grow(arr,size,size+1); arr[size-1] = element; } while(0) 1092#define GNUNET_array_append(arr,size,element) do { GNUNET_array_grow(arr,size,size+1); (arr)[size-1] = element; } while(0)
1093 1093
1094/** 1094/**
1095 * @ingroup memory 1095 * @ingroup memory
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h
index e25043d17..b38f38b69 100644
--- a/src/include/gnunet_core_service.h
+++ b/src/include/gnunet_core_service.h
@@ -232,7 +232,7 @@ enum GNUNET_CORE_KxState
232 232
233 /** 233 /**
234 * The other peer has confirmed our session key + PING with a PONG 234 * The other peer has confirmed our session key + PING with a PONG
235 * message encrypted with his session key (which we got). Key 235 * message encrypted with their session key (which we got). Key
236 * exchange is done. 236 * exchange is done.
237 */ 237 */
238 GNUNET_CORE_KX_STATE_UP, 238 GNUNET_CORE_KX_STATE_UP,
diff --git a/src/include/gnunet_dnsparser_lib.h b/src/include/gnunet_dnsparser_lib.h
index ba1392510..0fc6ac19c 100644
--- a/src/include/gnunet_dnsparser_lib.h
+++ b/src/include/gnunet_dnsparser_lib.h
@@ -82,6 +82,7 @@
82#define GNUNET_DNSPARSER_TYPE_OPENPGPKEY 61 82#define GNUNET_DNSPARSER_TYPE_OPENPGPKEY 61
83#define GNUNET_DNSPARSER_TYPE_TKEY 249 83#define GNUNET_DNSPARSER_TYPE_TKEY 249
84#define GNUNET_DNSPARSER_TYPE_TSIG 250 84#define GNUNET_DNSPARSER_TYPE_TSIG 250
85#define GNUNET_DNSPARSER_TYPE_ALL 255
85#define GNUNET_DNSPARSER_TYPE_URI 256 86#define GNUNET_DNSPARSER_TYPE_URI 256
86#define GNUNET_DNSPARSER_TYPE_TA 32768 87#define GNUNET_DNSPARSER_TYPE_TA 32768
87 88
@@ -840,6 +841,58 @@ GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
840 size_t udp_payload_length, 841 size_t udp_payload_length,
841 size_t *off); 842 size_t *off);
842 843
844/* ***************** low-level duplication API ******************** */
845
846/**
847 * Duplicate (deep-copy) the given DNS record
848 *
849 * @param r the record
850 * @return the newly allocated record
851 */
852struct GNUNET_DNSPARSER_Record *
853GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r);
854
855
856/**
857 * Duplicate (deep-copy) the given DNS record
858 *
859 * @param r the record
860 * @return the newly allocated record
861 */
862struct GNUNET_DNSPARSER_SoaRecord *
863GNUNET_DNSPARSER_duplicate_soa_record (const struct GNUNET_DNSPARSER_SoaRecord *r);
864
865
866/**
867 * Duplicate (deep-copy) the given DNS record
868 *
869 * @param r the record
870 * @return the newly allocated record
871 */
872struct GNUNET_DNSPARSER_CertRecord *
873GNUNET_DNSPARSER_duplicate_cert_record (const struct GNUNET_DNSPARSER_CertRecord *r);
874
875
876/**
877 * Duplicate (deep-copy) the given DNS record
878 *
879 * @param r the record
880 * @return the newly allocated record
881 */
882struct GNUNET_DNSPARSER_MxRecord *
883GNUNET_DNSPARSER_duplicate_mx_record (const struct GNUNET_DNSPARSER_MxRecord *r);
884
885
886/**
887 * Duplicate (deep-copy) the given DNS record
888 *
889 * @param r the record
890 * @return the newly allocated record
891 */
892struct GNUNET_DNSPARSER_SrvRecord *
893GNUNET_DNSPARSER_duplicate_srv_record (const struct GNUNET_DNSPARSER_SrvRecord *r);
894
895
843/* ***************** low-level deallocation API ******************** */ 896/* ***************** low-level deallocation API ******************** */
844 897
845/** 898/**
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h
index 86957a25c..98469a156 100644
--- a/src/include/gnunet_os_lib.h
+++ b/src/include/gnunet_os_lib.h
@@ -556,7 +556,7 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
556 556
557 557
558/** 558/**
559 * Retrieve the status of a process, waiting on him if dead. 559 * Retrieve the status of a process, waiting on it if dead.
560 * Nonblocking version. 560 * Nonblocking version.
561 * 561 *
562 * @param proc pointer to process structure 562 * @param proc pointer to process structure
@@ -586,7 +586,7 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc);
586 586
587 587
588/** 588/**
589 * Retrieve the status of a process, waiting on him if dead. 589 * Retrieve the status of a process, waiting on it if dead.
590 * Blocking version. 590 * Blocking version.
591 * 591 *
592 * @param proc pointer to process structure 592 * @param proc pointer to process structure
diff --git a/src/include/gnunet_psyc_service.h b/src/include/gnunet_psyc_service.h
index f31de0e67..053fe4495 100644
--- a/src/include/gnunet_psyc_service.h
+++ b/src/include/gnunet_psyc_service.h
@@ -135,7 +135,7 @@ enum GNUNET_PSYC_ChannelFlags
135enum GNUNET_PSYC_Policy 135enum GNUNET_PSYC_Policy
136{ 136{
137 /** 137 /**
138 * Anyone can join the channel, without announcing his presence; 138 * Anyone can join the channel, without announcing their presence;
139 * all messages are always public and can be distributed freely. 139 * all messages are always public and can be distributed freely.
140 * Joins may be announced, but this is not required. 140 * Joins may be announced, but this is not required.
141 */ 141 */
diff --git a/src/include/gnunet_secretsharing_service.h b/src/include/gnunet_secretsharing_service.h
index bd11df982..a3f44222e 100644
--- a/src/include/gnunet_secretsharing_service.h
+++ b/src/include/gnunet_secretsharing_service.h
@@ -248,7 +248,7 @@ GNUNET_SECRETSHARING_encrypt (const struct GNUNET_SECRETSHARING_PublicKey *publi
248 * published the same value, it will be decrypted. 248 * published the same value, it will be decrypted.
249 * 249 *
250 * When the operation is canceled, the decrypt_cb is not called anymore, but the calling 250 * When the operation is canceled, the decrypt_cb is not called anymore, but the calling
251 * peer may already have irrevocably contributed his share for the decryption of the value. 251 * peer may already have irrevocably contributed its share for the decryption of the value.
252 * 252 *
253 * @param cfg configuration to use 253 * @param cfg configuration to use
254 * @param share our secret share to use for decryption 254 * @param share our secret share to use for decryption
@@ -273,7 +273,7 @@ GNUNET_SECRETSHARING_decrypt (const struct GNUNET_CONFIGURATION_Handle *cfg,
273 * Cancel a decryption. 273 * Cancel a decryption.
274 * 274 *
275 * The decrypt_cb is not called anymore, but the calling 275 * The decrypt_cb is not called anymore, but the calling
276 * peer may already have irrevocably contributed his share for the decryption of the value. 276 * peer may already have irrevocably contributed its share for the decryption of the value.
277 * 277 *
278 * @param dh to cancel 278 * @param dh to cancel
279 */ 279 */
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index bc9e3dc16..d7accaf2c 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -134,7 +134,7 @@ extern "C"
134 134
135/** 135/**
136 * Accept state in regex DFA. Peer affirms that 136 * Accept state in regex DFA. Peer affirms that
137 * he offers the matching service. 137 * it offers the matching service.
138 */ 138 */
139#define GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT 18 139#define GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT 18
140 140
diff --git a/src/namestore/test_namestore_api_sqlite.conf b/src/namestore/test_namestore_api_sqlite.conf
index 8c0e557e7..cd4822097 100644
--- a/src/namestore/test_namestore_api_sqlite.conf
+++ b/src/namestore/test_namestore_api_sqlite.conf
@@ -2,7 +2,7 @@
2 2
3[namestore] 3[namestore]
4DATABASE = sqlite 4DATABASE = sqlite
5PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/v_log 5# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/v_log
6 6
7[namestore-sqlite] 7[namestore-sqlite]
8FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db 8FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db
diff --git a/src/nat/gnunet-helper-nat-server.c b/src/nat/gnunet-helper-nat-server.c
index 44817ede7..c5c6b563e 100644
--- a/src/nat/gnunet-helper-nat-server.c
+++ b/src/nat/gnunet-helper-nat-server.c
@@ -683,7 +683,10 @@ main (int argc,
683 if (1 == getppid ()) /* Check the parent process id, if 1 the parent has died, so we should die too */ 683 if (1 == getppid ()) /* Check the parent process id, if 1 the parent has died, so we should die too */
684 break; 684 break;
685 if (FD_ISSET (icmpsock, &rs)) 685 if (FD_ISSET (icmpsock, &rs))
686 {
686 process_icmp_response (); 687 process_icmp_response ();
688 continue;
689 }
687 if (0 == (++alt % 2)) 690 if (0 == (++alt % 2))
688 send_icmp_echo (&external); 691 send_icmp_echo (&external);
689 else 692 else
diff --git a/src/rps/gnunet-rps.c b/src/rps/gnunet-rps.c
index 739f71dac..b3785a733 100644
--- a/src/rps/gnunet-rps.c
+++ b/src/rps/gnunet-rps.c
@@ -150,6 +150,11 @@ run (void *cls,
150 static struct GNUNET_PeerIdentity zero_pid; 150 static struct GNUNET_PeerIdentity zero_pid;
151 151
152 rps_handle = GNUNET_RPS_connect (cfg); 152 rps_handle = GNUNET_RPS_connect (cfg);
153 if (NULL == rps_handle)
154 {
155 FPRINTF (stderr, "Failed to connect to the rps service\n");
156 return;
157 }
153 158
154 if ((0 == memcmp (&zero_pid, &peer_id, sizeof (peer_id))) && 159 if ((0 == memcmp (&zero_pid, &peer_id, sizeof (peer_id))) &&
155 (!view_update)) 160 (!view_update))
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 1b9681663..84fb33be2 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -243,7 +243,7 @@ struct PeerContext
243 243
244 /** 244 /**
245 * This is pobably followed by 'statistical' data (when we first saw 245 * This is pobably followed by 'statistical' data (when we first saw
246 * him, how did we get his ID, how many pushes (in a timeinterval), 246 * it, how did we get its ID, how many pushes (in a timeinterval),
247 * ...) 247 * ...)
248 */ 248 */
249}; 249};
@@ -503,6 +503,8 @@ add_valid_peer (const struct GNUNET_PeerIdentity *peer)
503 return ret; 503 return ret;
504} 504}
505 505
506static void
507remove_pending_message (struct PendingMessage *pending_msg, int cancel);
506 508
507/** 509/**
508 * @brief Set the peer flag to living and 510 * @brief Set the peer flag to living and
@@ -531,7 +533,7 @@ set_peer_live (struct PeerContext *peer_ctx)
531 GNUNET_i2s (&peer_ctx->peer_id)); 533 GNUNET_i2s (&peer_ctx->peer_id));
532 // TODO wait until cadet sets mq->cancel_impl 534 // TODO wait until cadet sets mq->cancel_impl
533 //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); 535 //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev);
534 GNUNET_free (peer_ctx->liveliness_check_pending); 536 remove_pending_message (peer_ctx->liveliness_check_pending, GNUNET_YES);
535 peer_ctx->liveliness_check_pending = NULL; 537 peer_ctx->liveliness_check_pending = NULL;
536 } 538 }
537 539
@@ -653,56 +655,6 @@ get_mq (const struct GNUNET_PeerIdentity *peer)
653 return peer_ctx->mq; 655 return peer_ctx->mq;
654} 656}
655 657
656
657/**
658 * @brief This is called in response to the first message we sent as a
659 * liveliness check.
660 *
661 * @param cls #PeerContext of peer with pending liveliness check
662 */
663static void
664mq_liveliness_check_successful (void *cls)
665{
666 struct PeerContext *peer_ctx = cls;
667
668 if (NULL != peer_ctx->liveliness_check_pending)
669 {
670 LOG (GNUNET_ERROR_TYPE_DEBUG,
671 "Liveliness check for peer %s was successfull\n",
672 GNUNET_i2s (&peer_ctx->peer_id));
673 GNUNET_free (peer_ctx->liveliness_check_pending);
674 peer_ctx->liveliness_check_pending = NULL;
675 set_peer_live (peer_ctx);
676 }
677}
678
679/**
680 * Issue a check whether peer is live
681 *
682 * @param peer_ctx the context of the peer
683 */
684static void
685check_peer_live (struct PeerContext *peer_ctx)
686{
687 LOG (GNUNET_ERROR_TYPE_DEBUG,
688 "Get informed about peer %s getting live\n",
689 GNUNET_i2s (&peer_ctx->peer_id));
690
691 struct GNUNET_MQ_Handle *mq;
692 struct GNUNET_MQ_Envelope *ev;
693
694 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE);
695 peer_ctx->liveliness_check_pending = GNUNET_new (struct PendingMessage);
696 peer_ctx->liveliness_check_pending->ev = ev;
697 peer_ctx->liveliness_check_pending->peer_ctx = peer_ctx;
698 peer_ctx->liveliness_check_pending->type = "Check liveliness";
699 mq = get_mq (&peer_ctx->peer_id);
700 GNUNET_MQ_notify_sent (ev,
701 mq_liveliness_check_successful,
702 peer_ctx);
703 GNUNET_MQ_send (mq, ev);
704}
705
706/** 658/**
707 * @brief Add an envelope to a message passed to mq to list of pending messages 659 * @brief Add an envelope to a message passed to mq to list of pending messages
708 * 660 *
@@ -757,6 +709,54 @@ remove_pending_message (struct PendingMessage *pending_msg, int cancel)
757 709
758 710
759/** 711/**
712 * @brief This is called in response to the first message we sent as a
713 * liveliness check.
714 *
715 * @param cls #PeerContext of peer with pending liveliness check
716 */
717static void
718mq_liveliness_check_successful (void *cls)
719{
720 struct PeerContext *peer_ctx = cls;
721
722 if (NULL != peer_ctx->liveliness_check_pending)
723 {
724 LOG (GNUNET_ERROR_TYPE_DEBUG,
725 "Liveliness check for peer %s was successfull\n",
726 GNUNET_i2s (&peer_ctx->peer_id));
727 remove_pending_message (peer_ctx->liveliness_check_pending, GNUNET_YES);
728 peer_ctx->liveliness_check_pending = NULL;
729 set_peer_live (peer_ctx);
730 }
731}
732
733/**
734 * Issue a check whether peer is live
735 *
736 * @param peer_ctx the context of the peer
737 */
738static void
739check_peer_live (struct PeerContext *peer_ctx)
740{
741 LOG (GNUNET_ERROR_TYPE_DEBUG,
742 "Get informed about peer %s getting live\n",
743 GNUNET_i2s (&peer_ctx->peer_id));
744
745 struct GNUNET_MQ_Handle *mq;
746 struct GNUNET_MQ_Envelope *ev;
747
748 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE);
749 peer_ctx->liveliness_check_pending =
750 insert_pending_message (&peer_ctx->peer_id, ev, "Check liveliness");
751 mq = get_mq (&peer_ctx->peer_id);
752 GNUNET_MQ_notify_sent (ev,
753 mq_liveliness_check_successful,
754 peer_ctx);
755 GNUNET_MQ_send (mq, ev);
756}
757
758
759/**
760 * @brief Check whether function of type #PeerOp was already scheduled 760 * @brief Check whether function of type #PeerOp was already scheduled
761 * 761 *
762 * The array with pending operations will probably never grow really big, so 762 * The array with pending operations will probably never grow really big, so
@@ -1256,6 +1256,13 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1256 "Removing unsent %s\n", 1256 "Removing unsent %s\n",
1257 peer_ctx->pending_messages_head->type); 1257 peer_ctx->pending_messages_head->type);
1258 /* Cancle pending message, too */ 1258 /* Cancle pending message, too */
1259 if ( (NULL != peer_ctx->liveliness_check_pending) &&
1260 (0 == memcmp (peer_ctx->pending_messages_head,
1261 peer_ctx->liveliness_check_pending,
1262 sizeof (struct PendingMessage))) )
1263 {
1264 peer_ctx->liveliness_check_pending = NULL;
1265 }
1259 remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES); 1266 remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES);
1260 } 1267 }
1261 /* If we are still waiting for notification whether this peer is live 1268 /* If we are still waiting for notification whether this peer is live
@@ -1267,7 +1274,7 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1267 GNUNET_i2s (&peer_ctx->peer_id)); 1274 GNUNET_i2s (&peer_ctx->peer_id));
1268 // TODO wait until cadet sets mq->cancel_impl 1275 // TODO wait until cadet sets mq->cancel_impl
1269 //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); 1276 //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev);
1270 GNUNET_free (peer_ctx->liveliness_check_pending); 1277 remove_pending_message (peer_ctx->liveliness_check_pending, GNUNET_YES);
1271 peer_ctx->liveliness_check_pending = NULL; 1278 peer_ctx->liveliness_check_pending = NULL;
1272 } 1279 }
1273 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING); 1280 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING);
@@ -2728,7 +2735,7 @@ cleanup_destroyed_channel (void *cls,
2728 return; 2735 return;
2729 } 2736 }
2730 else 2737 else
2731 { /* Other peer destroyed our sending channel that he is supposed to keep 2738 { /* Other peer destroyed our sending channel that it is supposed to keep
2732 * open. It probably went down. Remove it from our knowledge. */ 2739 * open. It probably went down. Remove it from our knowledge. */
2733 Peers_cleanup_destroyed_channel (cls, channel); 2740 Peers_cleanup_destroyed_channel (cls, channel);
2734 remove_peer (peer); 2741 remove_peer (peer);
@@ -2893,7 +2900,6 @@ client_respond (void *cls,
2893 GNUNET_memcpy (&out_msg[1], 2900 GNUNET_memcpy (&out_msg[1],
2894 peer_ids, 2901 peer_ids,
2895 num_peers * sizeof (struct GNUNET_PeerIdentity)); 2902 num_peers * sizeof (struct GNUNET_PeerIdentity));
2896 GNUNET_free (peer_ids);
2897 2903
2898 cli_ctx = reply_cls->cli_ctx; 2904 cli_ctx = reply_cls->cli_ctx;
2899 GNUNET_assert (NULL != cli_ctx); 2905 GNUNET_assert (NULL != cli_ctx);
@@ -3210,6 +3216,10 @@ handle_peer_push (void *cls,
3210 tmp_att_peer); 3216 tmp_att_peer);
3211 add_peer_array_to_set (peer, 1, att_peer_set); 3217 add_peer_array_to_set (peer, 1, att_peer_set);
3212 } 3218 }
3219 else
3220 {
3221 GNUNET_free (tmp_att_peer);
3222 }
3213 } 3223 }
3214 3224
3215 3225
@@ -3588,6 +3598,7 @@ handle_client_act_malicious (void *cls,
3588 3598
3589 num_mal_peers_sent = ntohl (msg->num_peers) - 1; 3599 num_mal_peers_sent = ntohl (msg->num_peers) - 1;
3590 num_mal_peers_old = num_mal_peers; 3600 num_mal_peers_old = num_mal_peers;
3601 GNUNET_assert (GNUNET_MAX_MALLOC_CHECKED > num_mal_peers_sent);
3591 GNUNET_array_grow (mal_peers, 3602 GNUNET_array_grow (mal_peers,
3592 num_mal_peers, 3603 num_mal_peers,
3593 num_mal_peers + num_mal_peers_sent); 3604 num_mal_peers + num_mal_peers_sent);
@@ -4172,6 +4183,7 @@ shutdown_task (void *cls)
4172 { 4183 {
4173 tmp_att_peer = att_peers_head; 4184 tmp_att_peer = att_peers_head;
4174 GNUNET_CONTAINER_DLL_remove (att_peers_head, att_peers_tail, tmp_att_peer); 4185 GNUNET_CONTAINER_DLL_remove (att_peers_head, att_peers_tail, tmp_att_peer);
4186 GNUNET_free (tmp_att_peer);
4175 } 4187 }
4176 #endif /* ENABLE_MALICIOUS */ 4188 #endif /* ENABLE_MALICIOUS */
4177} 4189}
diff --git a/src/rps/gnunet-service-rps_custommap.c b/src/rps/gnunet-service-rps_custommap.c
index 90177cb94..42507655b 100644
--- a/src/rps/gnunet-service-rps_custommap.c
+++ b/src/rps/gnunet-service-rps_custommap.c
@@ -220,6 +220,7 @@ CustomPeerMap_remove_peer (const struct CustomPeerMap *c_peer_map,
220 GNUNET_free (index); 220 GNUNET_free (index);
221 GNUNET_assert (GNUNET_CONTAINER_multihashmap32_size (c_peer_map->hash_map) == 221 GNUNET_assert (GNUNET_CONTAINER_multihashmap32_size (c_peer_map->hash_map) ==
222 GNUNET_CONTAINER_multipeermap_size (c_peer_map->peer_map)); 222 GNUNET_CONTAINER_multipeermap_size (c_peer_map->peer_map));
223 GNUNET_free (p);
223 return GNUNET_OK; 224 return GNUNET_OK;
224} 225}
225 226
diff --git a/src/rps/gnunet-service-rps_sampler.c b/src/rps/gnunet-service-rps_sampler.c
index 711d5be63..4d1ae4650 100644
--- a/src/rps/gnunet-service-rps_sampler.c
+++ b/src/rps/gnunet-service-rps_sampler.c
@@ -725,6 +725,7 @@ RPS_sampler_request_cancel (struct RPS_SamplerRequestHandle *req_handle)
725 } 725 }
726 GNUNET_free (i); 726 GNUNET_free (i);
727 } 727 }
728 GNUNET_free (req_handle->ids);
728 GNUNET_CONTAINER_DLL_remove (req_handle->sampler->req_handle_head, 729 GNUNET_CONTAINER_DLL_remove (req_handle->sampler->req_handle_head,
729 req_handle->sampler->req_handle_tail, 730 req_handle->sampler->req_handle_tail,
730 req_handle); 731 req_handle);
diff --git a/src/rps/rps-test_util.c b/src/rps/rps-test_util.c
index 0ee290e67..d47e4952f 100644
--- a/src/rps/rps-test_util.c
+++ b/src/rps/rps-test_util.c
@@ -352,10 +352,10 @@ create_file (const char *name)
352 if (NULL == strstr (name, "sampler_el")) 352 if (NULL == strstr (name, "sampler_el"))
353 {/* only append random string to sampler */ 353 {/* only append random string to sampler */
354 if (NULL == (file_name = GNUNET_DISK_mktemp (name_buf))) 354 if (NULL == (file_name = GNUNET_DISK_mktemp (name_buf)))
355 LOG (GNUNET_ERROR_TYPE_WARNING, "Could not create file\n"); 355 LOG (GNUNET_ERROR_TYPE_WARNING, "Could not create file\n");
356 356
357 GNUNET_free (name_buf); 357 GNUNET_free (name_buf);
358 return file_name; 358 return file_name;
359 } 359 }
360 360
361 return name_buf; 361 return name_buf;
diff --git a/src/rps/test_rps.c b/src/rps/test_rps.c
index 3ef1e6611..08424022f 100644
--- a/src/rps/test_rps.c
+++ b/src/rps/test_rps.c
@@ -841,6 +841,13 @@ seed_peers (void *cls)
841 unsigned int amount; 841 unsigned int amount;
842 unsigned int i; 842 unsigned int i;
843 843
844 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
845 {
846 return;
847 }
848
849 GNUNET_assert (NULL != peer->rps_handle);
850
844 // TODO if malicious don't seed mal peers 851 // TODO if malicious don't seed mal peers
845 amount = round (.5 * num_peers); 852 amount = round (.5 * num_peers);
846 853
@@ -953,6 +960,8 @@ rps_connect_complete_cb (void *cls,
953 struct RPSPeer *rps_peer = cls; 960 struct RPSPeer *rps_peer = cls;
954 struct GNUNET_RPS_Handle *rps = ca_result; 961 struct GNUNET_RPS_Handle *rps = ca_result;
955 962
963 GNUNET_assert (NULL != ca_result);
964
956 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test) 965 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
957 { 966 {
958 return; 967 return;
@@ -996,9 +1005,11 @@ rps_connect_adapter (void *cls,
996 struct GNUNET_RPS_Handle *h; 1005 struct GNUNET_RPS_Handle *h;
997 1006
998 h = GNUNET_RPS_connect (cfg); 1007 h = GNUNET_RPS_connect (cfg);
1008 GNUNET_assert (NULL != h);
999 1009
1000 if (NULL != cur_test_run.pre_test) 1010 if (NULL != cur_test_run.pre_test)
1001 cur_test_run.pre_test (cls, h); 1011 cur_test_run.pre_test (cls, h);
1012 GNUNET_assert (NULL != h);
1002 1013
1003 return h; 1014 return h;
1004} 1015}
@@ -2905,6 +2916,7 @@ main (int argc, char *argv[])
2905 } 2916 }
2906 2917
2907 ret_value = cur_test_run.eval_cb(); 2918 ret_value = cur_test_run.eval_cb();
2919
2908 if (NO_COLLECT_VIEW == cur_test_run.have_collect_view) 2920 if (NO_COLLECT_VIEW == cur_test_run.have_collect_view)
2909 { 2921 {
2910 GNUNET_array_grow (rps_peers->cur_view, 2922 GNUNET_array_grow (rps_peers->cur_view,
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c
index 505af0fba..1f565cfeb 100644
--- a/src/secretsharing/gnunet-service-secretsharing.c
+++ b/src/secretsharing/gnunet-service-secretsharing.c
@@ -51,7 +51,7 @@ struct KeygenPeerInfo
51 struct GNUNET_CRYPTO_PaillierPublicKey paillier_public_key; 51 struct GNUNET_CRYPTO_PaillierPublicKey paillier_public_key;
52 52
53 /** 53 /**
54 * The peer's commitment to his presecret. 54 * The peer's commitment to its presecret.
55 */ 55 */
56 gcry_mpi_t presecret_commitment; 56 gcry_mpi_t presecret_commitment;
57 57
diff --git a/src/secretsharing/secretsharing_api.c b/src/secretsharing/secretsharing_api.c
index cfb13f520..2a828f08d 100644
--- a/src/secretsharing/secretsharing_api.c
+++ b/src/secretsharing/secretsharing_api.c
@@ -314,7 +314,7 @@ handle_decrypt_done (void *cls,
314 * published the same value, it will be decrypted. 314 * published the same value, it will be decrypted.
315 * 315 *
316 * When the operation is canceled, the decrypt_cb is not called anymore, but the calling 316 * When the operation is canceled, the decrypt_cb is not called anymore, but the calling
317 * peer may already have irrevocably contributed his share for the decryption of the value. 317 * peer may already have irrevocably contributed its share for the decryption of the value.
318 * 318 *
319 * @param share our secret share to use for decryption 319 * @param share our secret share to use for decryption
320 * @param ciphertext ciphertext to publish in order to decrypt it (if enough peers agree) 320 * @param ciphertext ciphertext to publish in order to decrypt it (if enough peers agree)
@@ -485,7 +485,7 @@ GNUNET_SECRETSHARING_encrypt (const struct GNUNET_SECRETSHARING_PublicKey *publi
485 * Cancel a decryption. 485 * Cancel a decryption.
486 * 486 *
487 * The decrypt_cb is not called anymore, but the calling 487 * The decrypt_cb is not called anymore, but the calling
488 * peer may already have irrevocably contributed his share for the decryption of the value. 488 * peer may already have irrevocably contributed its share for the decryption of the value.
489 * 489 *
490 * @param dh to cancel 490 * @param dh to cancel
491 */ 491 */
diff --git a/src/secretsharing/secretsharing_protocol.h b/src/secretsharing/secretsharing_protocol.h
index 7627deb30..da1454ec0 100644
--- a/src/secretsharing/secretsharing_protocol.h
+++ b/src/secretsharing/secretsharing_protocol.h
@@ -58,7 +58,7 @@ struct GNUNET_SECRETSHARING_KeygenCommitData
58 */ 58 */
59 struct GNUNET_CRYPTO_PaillierPublicKey pubkey; 59 struct GNUNET_CRYPTO_PaillierPublicKey pubkey;
60 /** 60 /**
61 * Commitment of 'peer' to his presecret. 61 * Commitment of 'peer' to its presecret.
62 */ 62 */
63 struct GNUNET_HashCode commitment GNUNET_PACKED; 63 struct GNUNET_HashCode commitment GNUNET_PACKED;
64}; 64};
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h
index c9e59b441..f7c262eac 100644
--- a/src/set/gnunet-service-set.h
+++ b/src/set/gnunet-service-set.h
@@ -125,7 +125,7 @@ typedef struct OperationState *
125 * @param op operation that is created, should be initialized to 125 * @param op operation that is created, should be initialized to
126 * begin the evaluation 126 * begin the evaluation
127 * @param opaque_context message to be transmitted to the listener 127 * @param opaque_context message to be transmitted to the listener
128 * to convince him to accept, may be NULL 128 * to convince it to accept, may be NULL
129 * @return operation-specific state to keep in @a op 129 * @return operation-specific state to keep in @a op
130 */ 130 */
131typedef struct OperationState * 131typedef struct OperationState *
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c
index 0561df406..254763b45 100644
--- a/src/set/gnunet-service-set_intersection.c
+++ b/src/set/gnunet-service-set_intersection.c
@@ -695,7 +695,7 @@ initialize_map_unfiltered (void *cls,
695 695
696/** 696/**
697 * Send our element count to the peer, in case our element count is 697 * Send our element count to the peer, in case our element count is
698 * lower than his. 698 * lower than theirs.
699 * 699 *
700 * @param op intersection operation 700 * @param op intersection operation
701 */ 701 */
@@ -1077,7 +1077,7 @@ handle_intersection_p2p_done (void *cls,
1077 * @param op operation that is created, should be initialized to 1077 * @param op operation that is created, should be initialized to
1078 * begin the evaluation 1078 * begin the evaluation
1079 * @param opaque_context message to be transmitted to the listener 1079 * @param opaque_context message to be transmitted to the listener
1080 * to convince him to accept, may be NULL 1080 * to convince it to accept, may be NULL
1081 * @return operation-specific state to keep in @a op 1081 * @return operation-specific state to keep in @a op
1082 */ 1082 */
1083static struct OperationState * 1083static struct OperationState *
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c
index 7af220374..c3c14f1ba 100644
--- a/src/set/gnunet-service-set_union.c
+++ b/src/set/gnunet-service-set_union.c
@@ -2149,7 +2149,7 @@ handle_union_p2p_done (void *cls,
2149 * 2149 *
2150 * We should notify the active peer once 2150 * We should notify the active peer once
2151 * all our demands are satisfied, so that the active 2151 * all our demands are satisfied, so that the active
2152 * peer can quit if we gave him everything. 2152 * peer can quit if we gave it everything.
2153 */ 2153 */
2154 GNUNET_CADET_receive_done (op->channel); 2154 GNUNET_CADET_receive_done (op->channel);
2155 maybe_finish (op); 2155 maybe_finish (op);
@@ -2194,7 +2194,7 @@ handle_union_p2p_over (void *cls,
2194 * 2194 *
2195 * @param op operation to perform (to be initialized) 2195 * @param op operation to perform (to be initialized)
2196 * @param opaque_context message to be transmitted to the listener 2196 * @param opaque_context message to be transmitted to the listener
2197 * to convince him to accept, may be NULL 2197 * to convince it to accept, may be NULL
2198 */ 2198 */
2199static struct OperationState * 2199static struct OperationState *
2200union_evaluate (struct Operation *op, 2200union_evaluate (struct Operation *op,
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index 829fb5352..f7a4e4525 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -111,7 +111,7 @@ struct Peer
111 uint32_t strength; 111 uint32_t strength;
112 112
113 /** 113 /**
114 * Is this peer listed here because he is a friend? 114 * Is this peer listed here because it is a friend?
115 */ 115 */
116 int is_friend; 116 int is_friend;
117 117
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 6ebc6da8c..8c4f33fd0 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -612,7 +612,7 @@ notify_client_about_neighbour (void *cls,
612 612
613/** 613/**
614 * Initialize a normal client. We got a start message from this 614 * Initialize a normal client. We got a start message from this
615 * client, add him to the list of clients for broadcasting of inbound 615 * client, add it to the list of clients for broadcasting of inbound
616 * messages. 616 * messages.
617 * 617 *
618 * @param cls the client 618 * @param cls the client
@@ -2173,7 +2173,7 @@ test_connection_ok (void *cls,
2173 2173
2174/** 2174/**
2175 * Initialize a blacklisting client. We got a blacklist-init 2175 * Initialize a blacklisting client. We got a blacklist-init
2176 * message from this client, add him to the list of clients 2176 * message from this client, add it to the list of clients
2177 * to query for blacklisting. 2177 * to query for blacklisting.
2178 * 2178 *
2179 * @param cls the client 2179 * @param cls the client
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index b1f3965ad..3965bc13e 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -179,7 +179,7 @@ struct GNUNET_ATS_SessionQuotaMessage
179 179
180 180
181/** 181/**
182 * Message we send to the other peer to notify him that we intentionally 182 * Message we send to the other peer to notify it that we intentionally
183 * are disconnecting (to reduce timeouts). This is just a friendly 183 * are disconnecting (to reduce timeouts). This is just a friendly
184 * notification, peers must not rely on always receiving disconnect 184 * notification, peers must not rely on always receiving disconnect
185 * messages. 185 * messages.
@@ -3081,7 +3081,7 @@ master_task (void *cls)
3081 3081
3082/** 3082/**
3083 * Send a ACK message to the neighbour to confirm that we 3083 * Send a ACK message to the neighbour to confirm that we
3084 * got his SYN_ACK. 3084 * got its SYN_ACK.
3085 * 3085 *
3086 * @param n neighbour to send the ACK to 3086 * @param n neighbour to send the ACK to
3087 */ 3087 */
diff --git a/src/transport/transport.conf.in b/src/transport/transport.conf.in
index 4185acc29..c6b207ad7 100644
--- a/src/transport/transport.conf.in
+++ b/src/transport/transport.conf.in
@@ -9,7 +9,8 @@ BINARY = gnunet-service-transport
9NEIGHBOUR_LIMIT = 50 9NEIGHBOUR_LIMIT = 50
10ACCEPT_FROM = 127.0.0.1; 10ACCEPT_FROM = 127.0.0.1;
11ACCEPT_FROM6 = ::1; 11ACCEPT_FROM6 = ::1;
12PLUGINS = tcp udp 12# TCP is the only transport plugin known to work "reliably"
13PLUGINS = tcp
13UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport.sock 14UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport.sock
14BLACKLIST_FILE = $GNUNET_CONFIG_HOME/transport/blacklist 15BLACKLIST_FILE = $GNUNET_CONFIG_HOME/transport/blacklist
15UNIX_MATCH_UID = NO 16UNIX_MATCH_UID = NO
diff --git a/src/util/dnsparser.c b/src/util/dnsparser.c
index cce68f2ee..57d0a014c 100644
--- a/src/util/dnsparser.c
+++ b/src/util/dnsparser.c
@@ -759,6 +759,122 @@ GNUNET_DNSPARSER_parse (const char *udp_payload,
759 759
760 760
761/** 761/**
762 * Duplicate (deep-copy) the given DNS record
763 *
764 * @param r the record
765 * @return the newly allocated record
766 */
767struct GNUNET_DNSPARSER_Record *
768GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r)
769{
770 struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup (r, sizeof (*r));
771
772 dup->name = GNUNET_strdup (r->name);
773 switch (r->type)
774 {
775 case GNUNET_DNSPARSER_TYPE_NS:
776 case GNUNET_DNSPARSER_TYPE_CNAME:
777 case GNUNET_DNSPARSER_TYPE_PTR:
778 {
779 dup->data.hostname = GNUNET_strdup (r->data.hostname);
780 break;
781 }
782 case GNUNET_DNSPARSER_TYPE_SOA:
783 {
784 dup->data.soa = GNUNET_DNSPARSER_duplicate_soa_record (r->data.soa);
785 break;
786 }
787 case GNUNET_DNSPARSER_TYPE_CERT:
788 {
789 dup->data.cert = GNUNET_DNSPARSER_duplicate_cert_record (r->data.cert);
790 break;
791 }
792 case GNUNET_DNSPARSER_TYPE_MX:
793 {
794 dup->data.mx = GNUNET_DNSPARSER_duplicate_mx_record (r->data.mx);
795 break;
796 }
797 case GNUNET_DNSPARSER_TYPE_SRV:
798 {
799 dup->data.srv = GNUNET_DNSPARSER_duplicate_srv_record (r->data.srv);
800 break;
801 }
802 default:
803 {
804 dup->data.raw.data = GNUNET_memdup (r->data.raw.data,
805 r->data.raw.data_len);
806 }
807 }
808 return dup;
809}
810
811
812/**
813 * Duplicate (deep-copy) the given DNS record
814 *
815 * @param r the record
816 * @return the newly allocated record
817 */
818struct GNUNET_DNSPARSER_SoaRecord *
819GNUNET_DNSPARSER_duplicate_soa_record (const struct GNUNET_DNSPARSER_SoaRecord *r)
820{
821 struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof (*r));
822
823 dup->mname = GNUNET_strdup (r->mname);
824 dup->rname = GNUNET_strdup (r->rname);
825 return dup;
826}
827
828
829/**
830 * Duplicate (deep-copy) the given DNS record
831 *
832 * @param r the record
833 * @return the newly allocated record
834 */
835struct GNUNET_DNSPARSER_CertRecord *
836GNUNET_DNSPARSER_duplicate_cert_record (const struct GNUNET_DNSPARSER_CertRecord *r)
837{
838 struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof (*r));
839
840 dup->certificate_data = GNUNET_strdup (r->certificate_data);
841 return dup;
842}
843
844
845/**
846 * Duplicate (deep-copy) the given DNS record
847 *
848 * @param r the record
849 * @return the newly allocated record
850 */
851struct GNUNET_DNSPARSER_MxRecord *
852GNUNET_DNSPARSER_duplicate_mx_record (const struct GNUNET_DNSPARSER_MxRecord *r)
853{
854 struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup (r, sizeof (*r));
855
856 dup->mxhost = GNUNET_strdup (r->mxhost);
857 return dup;
858}
859
860
861/**
862 * Duplicate (deep-copy) the given DNS record
863 *
864 * @param r the record
865 * @return the newly allocated record
866 */
867struct GNUNET_DNSPARSER_SrvRecord *
868GNUNET_DNSPARSER_duplicate_srv_record (const struct GNUNET_DNSPARSER_SrvRecord *r)
869{
870 struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof (*r));
871
872 dup->target = GNUNET_strdup (r->target);
873 return dup;
874}
875
876
877/**
762 * Free memory taken by a packet. 878 * Free memory taken by a packet.
763 * 879 *
764 * @param p packet to free 880 * @param p packet to free
diff --git a/src/util/dnsstub.c b/src/util/dnsstub.c
index 8b5b20f3c..5b84e6e63 100644
--- a/src/util/dnsstub.c
+++ b/src/util/dnsstub.c
@@ -354,7 +354,7 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs,
354 "Received DNS response from server we never asked (ignored)"); 354 "Received DNS response from server we never asked (ignored)");
355 return GNUNET_NO; 355 return GNUNET_NO;
356 } 356 }
357 if (sizeof (struct GNUNET_TUN_DnsHeader) > r) 357 if (sizeof (struct GNUNET_TUN_DnsHeader) > (size_t) r)
358 { 358 {
359 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 359 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
360 _("Received DNS response that is too small (%u bytes)"), 360 _("Received DNS response that is too small (%u bytes)"),
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c
index d90d8ec10..5b890261b 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -27,721 +27,559 @@
27#include "gnunet_statistics_service.h" 27#include "gnunet_statistics_service.h"
28#include "resolver.h" 28#include "resolver.h"
29 29
30
31struct Record
32{
33 struct Record *next;
34
35 struct Record *prev;
36
37 struct GNUNET_DNSPARSER_Record *record;
38};
39
30/** 40/**
31 * A cached DNS lookup result (for reverse lookup). 41 * A cached DNS lookup result.
32 */ 42 */
33struct IPCache 43struct ResolveCache
34{ 44{
35 /** 45 /**
36 * This is a doubly linked list. 46 * This is a doubly linked list.
37 */ 47 */
38 struct IPCache *next; 48 struct ResolveCache *next;
39 49
40 /** 50 /**
41 * This is a doubly linked list. 51 * This is a doubly linked list.
42 */ 52 */
43 struct IPCache *prev; 53 struct ResolveCache *prev;
44 54
45 /** 55 /**
46 * Hostname in human-readable form. 56 * type of queried DNS record
47 */ 57 */
48 char *addr; 58 uint16_t record_type;
49 59
50 /** 60 /**
51 * Binary IP address, allocated at the end of this struct. 61 * a pointer to the request_id if a query for this hostname/record_type
62 * is currently pending, NULL otherwise.
52 */ 63 */
53 const void *ip; 64 int16_t *request_id;
54 65
55 /** 66 /**
56 * Last time this entry was updated. 67 * The client that queried the records contained in this cache entry.
57 */ 68 */
58 struct GNUNET_TIME_Absolute last_refresh; 69 struct GNUNET_SERVICE_Client *client;
59 70
60 /** 71 /**
61 * Last time this entry was requested. 72 * head of a double linked list containing the lookup results
62 */ 73 */
63 struct GNUNET_TIME_Absolute last_request; 74 struct Record *records_head;
64 75
65 /** 76 /**
66 * Number of bytes in ip. 77 * tail of a double linked list containing the lookup results
67 */ 78 */
68 size_t ip_len; 79 struct Record *records_tail;
69 80
70 /** 81 /**
71 * Address family of the IP. 82 * handle for cancelling a request
72 */ 83 */
73 int af; 84 struct GNUNET_DNSSTUB_RequestSocket *resolve_handle;
85
86 /**
87 * handle for the resolution timeout task
88 */
89 struct GNUNET_SCHEDULER_Task *timeout_task;
90
74}; 91};
75 92
76 93
77/** 94/**
78 * Start of the linked list of cached DNS lookup results. 95 * Start of the linked list of cached DNS lookup results.
79 */ 96 */
80static struct IPCache *cache_head; 97static struct ResolveCache *cache_head;
81 98
82/** 99/**
83 * Tail of the linked list of cached DNS lookup results. 100 * Tail of the linked list of cached DNS lookup results.
84 */ 101 */
85static struct IPCache *cache_tail; 102static struct ResolveCache *cache_tail;
86 103
87/** 104/**
88 * Pipe for asynchronously notifying about resolve result 105 * context of dnsstub library
89 */ 106 */
90static struct GNUNET_DISK_PipeHandle *resolve_result_pipe; 107static struct GNUNET_DNSSTUB_Context *dnsstub_ctx;
91 108
92/**
93 * Task for reading from resolve_result_pipe
94 */
95static struct GNUNET_SCHEDULER_Task *resolve_result_pipe_task;
96 109
97 110void free_cache_entry (struct ResolveCache *entry)
98#if HAVE_GETNAMEINFO
99/**
100 * Resolve the given request using getnameinfo
101 *
102 * @param cache the request to resolve (and where to store the result)
103 */
104static void
105getnameinfo_resolve (struct IPCache *cache)
106{ 111{
107 char hostname[256]; 112 struct Record *pos;
108 const struct sockaddr *sa; 113 struct Record *next;
109 struct sockaddr_in v4; 114
110 struct sockaddr_in6 v6; 115 next = entry->records_head;
111 size_t salen; 116 while (NULL != (pos = next))
112 int ret;
113
114 switch (cache->af)
115 { 117 {
116 case AF_INET: 118 next = pos->next;
117 GNUNET_assert (cache->ip_len == sizeof (struct in_addr)); 119 GNUNET_CONTAINER_DLL_remove (entry->records_head,
118 sa = (const struct sockaddr*) &v4; 120 entry->records_tail,
119 memset (&v4, 0, sizeof (v4)); 121 pos);
120 v4.sin_addr = * (const struct in_addr*) cache->ip; 122 if (NULL != pos->record)
121 v4.sin_family = AF_INET; 123 {
122#if HAVE_SOCKADDR_IN_SIN_LEN 124 GNUNET_DNSPARSER_free_record (pos->record);
123 v4.sin_len = sizeof (v4); 125 GNUNET_free (pos->record);
124#endif 126 }
125 salen = sizeof (v4); 127 GNUNET_free (pos);
126 break;
127 case AF_INET6:
128 GNUNET_assert (cache->ip_len == sizeof (struct in6_addr));
129 sa = (const struct sockaddr*) &v6;
130 memset (&v6, 0, sizeof (v6));
131 v6.sin6_addr = * (const struct in6_addr*) cache->ip;
132 v6.sin6_family = AF_INET6;
133#if HAVE_SOCKADDR_IN_SIN_LEN
134 v6.sin6_len = sizeof (v6);
135#endif
136 salen = sizeof (v6);
137 break;
138 default:
139 GNUNET_assert (0);
140 } 128 }
141 129 if (NULL != entry->resolve_handle)
142 if (0 ==
143 (ret = getnameinfo (sa, salen,
144 hostname, sizeof (hostname),
145 NULL,
146 0, 0)))
147 { 130 {
148 cache->addr = GNUNET_strdup (hostname); 131 GNUNET_DNSSTUB_resolve_cancel (entry->resolve_handle);
132 entry->resolve_handle = NULL;
149 } 133 }
150 else 134 if (NULL != entry->timeout_task)
151 { 135 {
152 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 136 GNUNET_SCHEDULER_cancel (entry->timeout_task);
153 "getnameinfo failed: %s\n", 137 entry->timeout_task = NULL;
154 gai_strerror (ret));
155 } 138 }
139 GNUNET_free_non_null (entry->request_id);
140 GNUNET_free (entry);
156} 141}
157#endif
158 142
159 143
160#if HAVE_GETHOSTBYADDR 144static char*
145extract_dns_server (const char* line, size_t line_len)
146{
147 if (0 == strncmp (line, "nameserver ", 11))
148 return GNUNET_strndup (line + 11, line_len - 11);
149 return NULL;
150}
151
152
161/** 153/**
162 * Resolve the given request using gethostbyaddr 154 * reads the list of nameservers from /etc/resolve.conf
163 * 155 *
164 * @param cache the request to resolve (and where to store the result) 156 * @param server_addrs[out] a list of null-terminated server address strings
157 * @return the number of server addresses in @server_addrs, -1 on error
165 */ 158 */
166static void 159static ssize_t
167gethostbyaddr_resolve (struct IPCache *cache) 160lookup_dns_servers (char ***server_addrs)
168{ 161{
169 struct hostent *ent; 162 struct GNUNET_DISK_FileHandle *fh;
170 163 char buf[2048];
171 ent = gethostbyaddr (cache->ip, 164 ssize_t bytes_read;
172 cache->ip_len, 165 size_t read_offset = 0;
173 cache->af); 166 unsigned int num_dns_servers = 0;
174 if (NULL != ent) 167
168 fh = GNUNET_DISK_file_open ("/etc/resolv.conf",
169 GNUNET_DISK_OPEN_READ,
170 GNUNET_DISK_PERM_NONE);
171 if (NULL == fh)
175 { 172 {
176 cache->addr = GNUNET_strdup (ent->h_name); 173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
174 "Could not open /etc/resolv.conf. "
175 "DNS resolution will not be possible.\n");
176 return -1;
177 } 177 }
178 else 178 bytes_read = GNUNET_DISK_file_read (fh,
179 buf,
180 sizeof (buf));
181 *server_addrs = NULL;
182 while (read_offset < bytes_read)
179 { 183 {
180 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 184 char *newline;
181 "gethostbyaddr failed: %s\n", 185 size_t line_len;
182 hstrerror (h_errno)); 186 char *dns_server;
187
188 newline = strchr (buf + read_offset, '\n');
189 if (NULL == newline)
190 {
191 break;
192 }
193 line_len = newline - buf - read_offset;
194 dns_server = extract_dns_server (buf + read_offset, line_len);
195 if (NULL != dns_server)
196 {
197 GNUNET_array_append (*server_addrs,
198 num_dns_servers,
199 dns_server);
200 }
201 read_offset += line_len + 1;
183 } 202 }
203 GNUNET_DISK_file_close (fh);
204 return num_dns_servers;
184} 205}
185#endif
186 206
187 207
188/** 208static char *
189 * Resolve the given request using the available methods. 209make_reverse_hostname (const void *ip, int af)
190 *
191 * @param cache the request to resolve (and where to store the result)
192 */
193static void
194cache_resolve (struct IPCache *cache)
195{ 210{
196#if HAVE_GETNAMEINFO 211 char *buf = GNUNET_new_array (80, char);
197 if (NULL == cache->addr) 212 int pos = 0;
198 getnameinfo_resolve (cache); 213 if (AF_INET == af)
199#endif 214 {
200#if HAVE_GETHOSTBYADDR 215 struct in_addr *addr = (struct in_addr *)ip;
201 if (NULL == cache->addr) 216 uint32_t ip_int = addr->s_addr;
202 gethostbyaddr_resolve (cache); 217 for (int i = 3; i >= 0; i--)
203#endif 218 {
219 int n = GNUNET_snprintf (buf + pos,
220 80 - pos,
221 "%u.",
222 ((uint8_t *)&ip_int)[i]);
223 if (n < 0)
224 {
225 GNUNET_free (buf);
226 return NULL;
227 }
228 pos += n;
229 }
230 pos += GNUNET_snprintf (buf + pos, 80 - pos, "in-addr.arpa");
231 }
232 else if (AF_INET6 == af)
233 {
234 struct in6_addr *addr = (struct in6_addr *)ip;
235 for (int i = 15; i >= 0; i--)
236 {
237 int n = GNUNET_snprintf (buf + pos, 80 - pos, "%x.", addr->s6_addr[i] & 0xf);
238 if (n < 0)
239 {
240 GNUNET_free (buf);
241 return NULL;
242 }
243 pos += n;
244 n = GNUNET_snprintf (buf + pos, 80 - pos, "%x.", addr->s6_addr[i] >> 4);
245 if (n < 0)
246 {
247 GNUNET_free (buf);
248 return NULL;
249 }
250 pos += n;
251 }
252 pos += GNUNET_snprintf (buf + pos, 80 - pos, "ip6.arpa");
253 }
254 buf[pos] = '\0';
255 return buf;
204} 256}
205 257
206 258
207/**
208 * Function called after the replies for the request have all
209 * been transmitted to the client, and we can now read the next
210 * request from the client.
211 *
212 * @param cls the `struct GNUNET_SERVICE_Client` to continue with
213 */
214static void 259static void
215notify_service_client_done (void *cls) 260send_reply (struct GNUNET_DNSPARSER_Record *record,
261 uint16_t request_id,
262 struct GNUNET_SERVICE_Client *client)
216{ 263{
217 struct GNUNET_SERVICE_Client *client = cls;
218
219 GNUNET_SERVICE_client_continue (client);
220}
221
222
223/**
224 * Get an IP address as a string (works for both IPv4 and IPv6). Note
225 * that the resolution happens asynchronously and that the first call
226 * may not immediately result in the FQN (but instead in a
227 * human-readable IP address).
228 *
229 * @param client handle to the client making the request (for sending the reply)
230 * @param af AF_INET or AF_INET6
231 * @param ip `struct in_addr` or `struct in6_addr`
232 */
233static void
234get_ip_as_string (struct GNUNET_SERVICE_Client *client,
235 int af,
236 const void *ip,
237 uint32_t request_id)
238{
239 struct IPCache *pos;
240 struct IPCache *next;
241 struct GNUNET_TIME_Absolute now;
242 struct GNUNET_MQ_Envelope *env;
243 struct GNUNET_MQ_Handle *mq;
244 struct GNUNET_RESOLVER_ResponseMessage *msg; 264 struct GNUNET_RESOLVER_ResponseMessage *msg;
245 size_t ip_len; 265 struct GNUNET_MQ_Envelope *env;
246 struct in6_addr ix; 266 void *payload;
247 size_t alen; 267 size_t payload_len;
248 268
249 switch (af) 269 switch (record->type)
250 {
251 case AF_INET:
252 ip_len = sizeof (struct in_addr);
253 break;
254 case AF_INET6:
255 ip_len = sizeof (struct in6_addr);
256 break;
257 default:
258 GNUNET_assert (0);
259 }
260 now = GNUNET_TIME_absolute_get ();
261 next = cache_head;
262 while ( (NULL != (pos = next)) &&
263 ( (pos->af != af) ||
264 (pos->ip_len != ip_len) ||
265 (0 != memcmp (pos->ip, ip, ip_len))) )
266 { 270 {
267 next = pos->next; 271 case GNUNET_DNSPARSER_TYPE_PTR:
268 if (GNUNET_TIME_absolute_get_duration (pos->last_request).rel_value_us <
269 60 * 60 * 1000 * 1000LL)
270 { 272 {
271 GNUNET_CONTAINER_DLL_remove (cache_head, 273 char *hostname = record->data.hostname;
272 cache_tail, 274 payload = hostname;
273 pos); 275 payload_len = strlen (hostname) + 1;
274 GNUNET_free_non_null (pos->addr); 276 break;
275 GNUNET_free (pos);
276 continue;
277 } 277 }
278 } 278 case GNUNET_DNSPARSER_TYPE_A:
279 if (NULL != pos) 279 case GNUNET_DNSPARSER_TYPE_AAAA:
280 {
281 if ( (1 == inet_pton (af,
282 pos->ip,
283 &ix)) &&
284 (GNUNET_TIME_absolute_get_duration (pos->last_request).rel_value_us >
285 120 * 1000 * 1000LL) )
286 { 280 {
287 /* try again if still numeric AND 2 minutes have expired */ 281 payload = record->data.raw.data;
288 GNUNET_free_non_null (pos->addr); 282 payload_len = record->data.raw.data_len;
289 pos->addr = NULL; 283 break;
290 cache_resolve (pos); 284 }
291 pos->last_request = now; 285 default:
286 {
287 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
288 "Cannot handle DNS response type: unimplemented\n");
289 return;
292 } 290 }
293 } 291 }
294 else
295 {
296 pos = GNUNET_malloc (sizeof (struct IPCache) + ip_len);
297 pos->ip = &pos[1];
298 GNUNET_memcpy (&pos[1],
299 ip,
300 ip_len);
301 pos->last_request = now;
302 pos->last_refresh = now;
303 pos->ip_len = ip_len;
304 pos->af = af;
305 GNUNET_CONTAINER_DLL_insert (cache_head,
306 cache_tail,
307 pos);
308 cache_resolve (pos);
309 }
310 if (NULL != pos->addr)
311 alen = strlen (pos->addr) + 1;
312 else
313 alen = 0;
314 mq = GNUNET_SERVICE_client_get_mq (client);
315 env = GNUNET_MQ_msg_extra (msg, 292 env = GNUNET_MQ_msg_extra (msg,
316 alen, 293 payload_len,
317 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 294 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
318 msg->id = request_id; 295 msg->id = request_id;
319 GNUNET_memcpy (&msg[1], 296 GNUNET_memcpy (&msg[1],
320 pos->addr, 297 payload,
321 alen); 298 payload_len);
322 GNUNET_MQ_send (mq, 299 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
323 env); 300 env);
324 // send end message
325 env = GNUNET_MQ_msg (msg,
326 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
327 msg->id = request_id;
328 GNUNET_MQ_notify_sent (env,
329 &notify_service_client_done,
330 client);
331 GNUNET_MQ_send (mq,
332 env);
333} 301}
334 302
335 303
336#if HAVE_GETADDRINFO_A
337struct AsyncCls
338{
339 struct gaicb *host;
340 struct sigevent *sig;
341 struct GNUNET_MQ_Handle *mq;
342 uint32_t request_id;
343};
344
345
346static void 304static void
347resolve_result_pipe_cb (void *cls) 305send_end_msg (uint16_t request_id,
306 struct GNUNET_SERVICE_Client *client)
348{ 307{
349 struct AsyncCls *async_cls;
350 struct gaicb *host;
351 struct GNUNET_RESOLVER_ResponseMessage *msg; 308 struct GNUNET_RESOLVER_ResponseMessage *msg;
352 struct GNUNET_MQ_Envelope *env; 309 struct GNUNET_MQ_Envelope *env;
353 310
354 GNUNET_DISK_file_read (GNUNET_DISK_pipe_handle (resolve_result_pipe, 311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
355 GNUNET_DISK_PIPE_END_READ), 312 "Sending end message\n");
356 &async_cls, 313 env = GNUNET_MQ_msg (msg,
357 sizeof (struct AsyncCls *)); 314 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
358 resolve_result_pipe_task = 315 msg->id = request_id;
359 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 316 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
360 GNUNET_DISK_pipe_handle (resolve_result_pipe, 317 env);
361 GNUNET_DISK_PIPE_END_READ), 318}
362 &resolve_result_pipe_cb, 319
363 NULL); 320
364 host = async_cls->host; 321static void
365 for (struct addrinfo *pos = host->ar_result; pos != NULL; pos = pos->ai_next) 322handle_resolve_result (void *cls,
323 const struct GNUNET_TUN_DnsHeader *dns,
324 size_t dns_len)
325{
326 struct ResolveCache *cache = cls;
327 struct GNUNET_DNSPARSER_Packet *parsed;
328 uint16_t request_id = *cache->request_id;
329 struct GNUNET_SERVICE_Client *client = cache->client;
330
331 parsed = GNUNET_DNSPARSER_parse ((const char *)dns,
332 dns_len);
333 if (NULL == parsed)
334 {
335 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
336 "Failed to parse DNS reply (request ID %u\n",
337 request_id);
338 return;
339 }
340 if (request_id != ntohs (parsed->id))
341 {
342 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
343 "Request ID in DNS reply does not match\n");
344 return;
345 }
346 else if (0 == parsed->num_answers)
347 {
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
349 "DNS reply (request ID %u) contains no answers\n",
350 request_id);
351 GNUNET_CONTAINER_DLL_remove (cache_head,
352 cache_tail,
353 cache);
354 free_cache_entry (cache);
355 cache = NULL;
356 }
357 else
366 { 358 {
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
368 "Lookup result for hostname %s: %s (request ID %u)\n", 360 "Got reply for request ID %u\n",
369 host->ar_name, 361 request_id);
370 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen), 362 for (unsigned int i = 0; i != parsed->num_answers; i++)
371 async_cls->request_id);
372 switch (pos->ai_family)
373 { 363 {
374 case AF_INET: 364 struct Record *cache_entry = GNUNET_new (struct Record);
375 env = GNUNET_MQ_msg_extra (msg, 365 struct GNUNET_DNSPARSER_Record *record = &parsed->answers[i];
376 sizeof (struct in_addr), 366 cache_entry->record = GNUNET_DNSPARSER_duplicate_record (record);
377 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 367 GNUNET_CONTAINER_DLL_insert (cache->records_head,
378 msg->id = async_cls->request_id; 368 cache->records_tail,
379 GNUNET_memcpy (&msg[1], 369 cache_entry);
380 &((struct sockaddr_in*) pos->ai_addr)->sin_addr, 370 send_reply (cache_entry->record,
381 sizeof (struct in_addr)); 371 request_id,
382 GNUNET_MQ_send (async_cls->mq, 372 cache->client);
383 env);
384 break;
385 case AF_INET6:
386 env = GNUNET_MQ_msg_extra (msg,
387 sizeof (struct in6_addr),
388 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
389 msg->id = async_cls->request_id;
390 GNUNET_memcpy (&msg[1],
391 &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr,
392 sizeof (struct in6_addr));
393 GNUNET_MQ_send (async_cls->mq,
394 env);
395 break;
396 default:
397 /* unsupported, skip */
398 break;
399 } 373 }
374 GNUNET_free_non_null (cache->request_id);
375 cache->request_id = NULL;
400 } 376 }
401 // send end message 377 send_end_msg (request_id,
402 env = GNUNET_MQ_msg (msg, 378 client);
403 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 379 if (NULL != cache)
404 msg->id = async_cls->request_id; 380 cache->client = NULL;
405 GNUNET_MQ_send (async_cls->mq, 381 if (NULL != cache)
406 env); 382 {
407 freeaddrinfo (host->ar_result); 383 if (NULL != cache->timeout_task)
408 GNUNET_free ((struct gaicb *)host->ar_request); // free hints 384 {
409 GNUNET_free (host); 385 GNUNET_SCHEDULER_cancel (cache->timeout_task);
410 GNUNET_free (async_cls->sig); 386 cache->timeout_task = NULL;
411 GNUNET_free (async_cls); 387 }
388 if (NULL != cache->resolve_handle)
389 {
390 GNUNET_DNSSTUB_resolve_cancel (cache->resolve_handle);
391 cache->resolve_handle = NULL;
392 }
393 }
394 GNUNET_DNSPARSER_free_packet (parsed);
412} 395}
413 396
414 397
415static void 398static void
416handle_async_result (union sigval val) 399handle_resolve_timeout (void *cls)
417{ 400{
418 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (resolve_result_pipe, 401 struct ResolveCache *cache = cls;
419 GNUNET_DISK_PIPE_END_WRITE), 402
420 &val.sival_ptr, 403 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
421 sizeof (val.sival_ptr)); 404 "timeout!\n");
405 if (NULL != cache->resolve_handle)
406 {
407 GNUNET_DNSSTUB_resolve_cancel (cache->resolve_handle);
408 cache->resolve_handle = NULL;
409 }
410 GNUNET_CONTAINER_DLL_remove (cache_head,
411 cache_tail,
412 cache);
413 free_cache_entry (cache);
422} 414}
423 415
424 416
425static int 417static int
426getaddrinfo_a_resolve (struct GNUNET_MQ_Handle *mq, 418resolve_and_cache (const char* hostname,
427 const char *hostname, 419 uint16_t record_type,
428 int af, 420 uint16_t request_id,
429 uint32_t request_id) 421 struct GNUNET_SERVICE_Client *client)
430{ 422{
431 int ret; 423 char *packet_buf;
432 struct gaicb *host; 424 size_t packet_size;
433 struct addrinfo *hints; 425 struct GNUNET_DNSPARSER_Query query;
434 struct sigevent *sig; 426 struct GNUNET_DNSPARSER_Packet packet;
435 struct AsyncCls *async_cls; 427 struct ResolveCache *cache;
436 428 struct GNUNET_TIME_Relative timeout =
437 host = GNUNET_new (struct gaicb); 429 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5);
438 hints = GNUNET_new (struct addrinfo); 430
439 sig = GNUNET_new (struct sigevent); 431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
440 async_cls = GNUNET_new (struct AsyncCls); 432 "resolve_and_cache\n");
441 memset (hints, 433 query.name = (char *)hostname;
434 query.type = record_type;
435 query.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
436 memset (&packet,
442 0, 437 0,
443 sizeof (struct addrinfo)); 438 sizeof (packet));
444 memset (sig, 439 packet.num_queries = 1;
445 0, 440 packet.queries = &query;
446 sizeof (struct sigevent)); 441 packet.id = htons (request_id);
447 hints->ai_family = af; 442 packet.flags.recursion_desired = 1;
448 hints->ai_socktype = SOCK_STREAM; /* go for TCP */ 443 if (GNUNET_OK !=
449 host->ar_name = hostname; 444 GNUNET_DNSPARSER_pack (&packet,
450 host->ar_service = NULL; 445 UINT16_MAX,
451 host->ar_request = hints; 446 &packet_buf,
452 host->ar_result = NULL; 447 &packet_size))
453 sig->sigev_notify = SIGEV_THREAD; 448 {
454 sig->sigev_value.sival_ptr = async_cls; 449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
455 sig->sigev_notify_function = &handle_async_result; 450 "Failed to pack query for hostname `%s'\n",
456 async_cls->host = host; 451 hostname);
457 async_cls->sig = sig;
458 async_cls->mq = mq;
459 async_cls->request_id = request_id;
460 ret = getaddrinfo_a (GAI_NOWAIT,
461 &host,
462 1,
463 sig);
464 if (0 != ret)
465 return GNUNET_SYSERR; 452 return GNUNET_SYSERR;
453
454 }
455 cache = GNUNET_malloc (sizeof (struct ResolveCache));
456 cache->record_type = record_type;
457 cache->request_id = GNUNET_memdup (&request_id, sizeof (request_id));
458 cache->client = client;
459 cache->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout,
460 &handle_resolve_timeout,
461 cache);
462 cache->resolve_handle =
463 GNUNET_DNSSTUB_resolve (dnsstub_ctx,
464 packet_buf,
465 packet_size,
466 &handle_resolve_result,
467 cache);
468 GNUNET_CONTAINER_DLL_insert (cache_head,
469 cache_tail,
470 cache);
471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
472 "resolve %s, request_id = %u\n",
473 hostname,
474 request_id);
475 GNUNET_free (packet_buf);
466 return GNUNET_OK; 476 return GNUNET_OK;
467} 477}
468 478
469 479
470#elif HAVE_GETADDRINFO 480static const char *
471static int 481get_hostname (struct ResolveCache *cache_entry)
472getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq,
473 const char *hostname,
474 int af,
475 uint32_t request_id)
476{ 482{
477 int s; 483 if (NULL != cache_entry->records_head)
478 struct addrinfo hints;
479 struct addrinfo *result;
480 struct addrinfo *pos;
481 struct GNUNET_RESOLVER_ResponseMessage *msg;
482 struct GNUNET_MQ_Envelope *env;
483
484#ifdef WINDOWS
485 /* Due to a bug, getaddrinfo will not return a mix of different families */
486 if (AF_UNSPEC == af)
487 { 484 {
488 int ret1; 485 GNUNET_assert (NULL != cache_entry->records_head);
489 int ret2; 486 GNUNET_assert (NULL != cache_entry->records_head->record);
490 ret1 = getaddrinfo_resolve (mq, 487 GNUNET_assert (NULL != cache_entry->records_head->record->name);
491 hostname, 488 return cache_entry->records_head->record->name;
492 AF_INET,
493 request_id);
494 ret2 = getaddrinfo_resolve (mq,
495 hostname,
496 AF_INET6,
497 request_id);
498 if ( (ret1 == GNUNET_OK) ||
499 (ret2 == GNUNET_OK) )
500 return GNUNET_OK;
501 if ( (ret1 == GNUNET_SYSERR) ||
502 (ret2 == GNUNET_SYSERR) )
503 return GNUNET_SYSERR;
504 return GNUNET_NO;
505 } 489 }
506#endif 490 return NULL;
507
508 memset (&hints,
509 0,
510 sizeof (struct addrinfo));
511 hints.ai_family = af;
512 hints.ai_socktype = SOCK_STREAM; /* go for TCP */
513
514 if (0 != (s = getaddrinfo (hostname,
515 NULL,
516 &hints,
517 &result)))
518 {
519 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
520 _("Could not resolve `%s' (%s): %s\n"),
521 hostname,
522 (af ==
523 AF_INET) ? "IPv4" : ((af == AF_INET6) ? "IPv6" : "any"),
524 gai_strerror (s));
525 if ( (s == EAI_BADFLAGS) ||
526#ifndef WINDOWS
527 (s == EAI_SYSTEM) ||
528#endif
529 (s == EAI_MEMORY) )
530 return GNUNET_NO; /* other function may still succeed */
531 return GNUNET_SYSERR;
532 }
533 if (NULL == result)
534 return GNUNET_SYSERR;
535 for (pos = result; pos != NULL; pos = pos->ai_next)
536 {
537 switch (pos->ai_family)
538 {
539 case AF_INET:
540 env = GNUNET_MQ_msg_extra (msg,
541 sizeof (struct in_addr),
542 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
543 msg->id = request_id;
544 GNUNET_memcpy (&msg[1],
545 &((struct sockaddr_in*) pos->ai_addr)->sin_addr,
546 sizeof (struct in_addr));
547 GNUNET_MQ_send (mq,
548 env);
549 break;
550 case AF_INET6:
551 env = GNUNET_MQ_msg_extra (msg,
552 sizeof (struct in6_addr),
553 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
554 msg->id = request_id;
555 GNUNET_memcpy (&msg[1],
556 &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr,
557 sizeof (struct in6_addr));
558 GNUNET_MQ_send (mq,
559 env);
560 break;
561 default:
562 /* unsupported, skip */
563 break;
564 }
565 }
566 freeaddrinfo (result);
567 return GNUNET_OK;
568} 491}
569 492
570 493
571#elif HAVE_GETHOSTBYNAME2 494static const uint16_t *
572 495get_record_type (struct ResolveCache *cache_entry)
573
574static int
575gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq,
576 const char *hostname,
577 int af,
578 uint32_t request_id)
579{ 496{
580 struct hostent *hp; 497 if (NULL != cache_entry->records_head)
581 int ret1; 498 return &cache_entry->record_type;
582 int ret2; 499 return NULL;
583 struct GNUNET_MQ_Envelope *env; 500}
584 struct GNUNET_RESOLVER_ResponseMessage *msg;
585 501
586#ifdef WINDOWS
587 /* gethostbyname2() in plibc is a compat dummy that calls gethostbyname(). */
588 return GNUNET_NO;
589#endif
590 502
591 if (af == AF_UNSPEC) 503static const struct GNUNET_TIME_Absolute *
592 { 504get_expiration_time (struct ResolveCache *cache_entry)
593 ret1 = gethostbyname2_resolve (mq, 505{
594 hostname, 506 if (NULL != cache_entry->records_head)
595 AF_INET, 507 return &cache_entry->records_head->record->expiration_time;
596 request_id); 508 return NULL;
597 ret2 = gethostbyname2_resolve (mq,
598 hostname,
599 AF_INET6,
600 request_id);
601 if ( (ret1 == GNUNET_OK) ||
602 (ret2 == GNUNET_OK) )
603 return GNUNET_OK;
604 if ( (ret1 == GNUNET_SYSERR) ||
605 (ret2 == GNUNET_SYSERR) )
606 return GNUNET_SYSERR;
607 return GNUNET_NO;
608 }
609 hp = gethostbyname2 (hostname,
610 af);
611 if (hp == NULL)
612 {
613 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
614 _("Could not find IP of host `%s': %s\n"),
615 hostname,
616 hstrerror (h_errno));
617 return GNUNET_SYSERR;
618 }
619 GNUNET_assert (hp->h_addrtype == af);
620 switch (af)
621 {
622 case AF_INET:
623 GNUNET_assert (hp->h_length == sizeof (struct in_addr));
624 env = GNUNET_MQ_msg_extra (msg,
625 hp->h_length,
626 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
627 msg->id = request_id;
628 GNUNET_memcpy (&msg[1],
629 hp->h_addr_list[0],
630 hp->h_length);
631 GNUNET_MQ_send (mq,
632 env);
633 break;
634 case AF_INET6:
635 GNUNET_assert (hp->h_length == sizeof (struct in6_addr));
636 env = GNUNET_MQ_msg_extra (msg,
637 hp->h_length,
638 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
639 msg->id = request_id;
640 GNUNET_memcpy (&msg[1],
641 hp->h_addr_list[0],
642 hp->h_length);
643 GNUNET_MQ_send (mq,
644 env);
645 break;
646 default:
647 GNUNET_break (0);
648 return GNUNET_SYSERR;
649 }
650 return GNUNET_OK;
651} 509}
652 510
653#elif HAVE_GETHOSTBYNAME
654
655 511
656static int 512static int
657gethostbyname_resolve (struct GNUNET_MQ_Handle *mq, 513remove_if_expired (struct ResolveCache *cache_entry)
658 const char *hostname,
659 uint32_t request_id)
660{ 514{
661 struct hostent *hp; 515 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
662 struct GNUNET_RESOLVER_ResponseMessage *msg;
663 struct GNUNET_MQ_Envelope *env;
664 516
665 hp = GETHOSTBYNAME (hostname); 517 if ( (NULL != cache_entry->records_head) &&
666 if (NULL == hp) 518 (now.abs_value_us > get_expiration_time (cache_entry)->abs_value_us) )
667 { 519 {
668 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 520 GNUNET_CONTAINER_DLL_remove (cache_head,
669 _("Could not find IP of host `%s': %s\n"), 521 cache_tail,
670 hostname, 522 cache_entry);
671 hstrerror (h_errno)); 523 free_cache_entry (cache_entry);
672 return GNUNET_SYSERR; 524 return GNUNET_YES;
673 }
674 if (hp->h_addrtype != AF_INET)
675 {
676 GNUNET_break (0);
677 return GNUNET_SYSERR;
678 } 525 }
679 GNUNET_assert (hp->h_length == sizeof (struct in_addr)); 526 return GNUNET_NO;
680 env = GNUNET_MQ_msg_extra (msg,
681 hp->h_length,
682 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
683 msg->id = request_id;
684 GNUNET_memcpy (&msg[1],
685 hp->h_addr_list[0],
686 hp->h_length);
687 GNUNET_MQ_send (mq,
688 env);
689 return GNUNET_OK;
690} 527}
691#endif
692 528
693 529
694/** 530/**
695 * Convert a string to an IP address. 531 * Get an IP address as a string (works for both IPv4 and IPv6). Note
532 * that the resolution happens asynchronously and that the first call
533 * may not immediately result in the FQN (but instead in a
534 * human-readable IP address).
696 * 535 *
697 * @param client where to send the IP address 536 * @param client handle to the client making the request (for sending the reply)
698 * @param hostname the hostname to resolve 537 * @param af AF_INET or AF_INET6
699 * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" 538 * @param ip `struct in_addr` or `struct in6_addr`
700 */ 539 */
701static void 540static int
702get_ip_from_hostname (struct GNUNET_SERVICE_Client *client, 541try_cache (const char *hostname,
703 const char *hostname, 542 uint16_t record_type,
704 int af, 543 uint16_t request_id,
705 uint32_t request_id) 544 struct GNUNET_SERVICE_Client *client)
706{ 545{
707 struct GNUNET_MQ_Envelope *env; 546 struct ResolveCache *pos;
708 struct GNUNET_RESOLVER_ResponseMessage *msg; 547 struct ResolveCache *next;
709 struct GNUNET_MQ_Handle *mq; 548
710 549 next = cache_head;
711 mq = GNUNET_SERVICE_client_get_mq (client); 550 while ( (NULL != (pos = next)) &&
712#if HAVE_GETADDRINFO_A 551 ( (NULL == pos->records_head) ||
713 getaddrinfo_a_resolve (mq, 552 (0 != strcmp (get_hostname (pos), hostname)) ||
714 hostname, 553 (*get_record_type (pos) != record_type) ) )
715 af, 554 {
716 request_id); 555 next = pos->next;
717 GNUNET_SERVICE_client_continue (client); 556 remove_if_expired (pos);
718 return; 557 }
719#elif HAVE_GETADDRINFO 558 if (NULL != pos)
720 getaddrinfo_resolve (mq, 559 {
721 hostname, 560 if (GNUNET_NO == remove_if_expired (pos))
722 af, 561 {
723 request_id); 562 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
724#elif HAVE_GETHOSTBYNAME2 563 "found cache entry for '%s', record type '%u'\n",
725 gethostbyname2_resolve (mq, 564 hostname,
726 hostname, 565 record_type);
727 af, 566 struct Record *cache_pos = pos->records_head;
728 request_id); 567 while (NULL != cache_pos)
729#elif HAVE_GETHOSTBYNAME 568 {
730 if ( ( (af == AF_UNSPEC) || 569 send_reply (cache_pos->record,
731 (af == PF_INET) ) ) 570 request_id,
732 gethostbyname_resolve (mq, 571 client);
733 hostname, 572 cache_pos = cache_pos->next;
734 request_id); 573 }
735#endif 574 send_end_msg (request_id,
736 // send end message 575 client);
737 env = GNUNET_MQ_msg (msg, 576 return GNUNET_YES;
738 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 577 }
739 msg->id = request_id; 578 }
740 GNUNET_MQ_notify_sent (env, 579 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
741 &notify_service_client_done, 580 "no cache entry for '%s'\n",
742 client); 581 hostname);
743 GNUNET_MQ_send (mq, 582 return GNUNET_NO;
744 env);
745} 583}
746 584
747 585
@@ -801,6 +639,23 @@ check_get (void *cls,
801} 639}
802 640
803 641
642static void
643process_get (const char *hostname,
644 uint16_t record_type,
645 uint16_t request_id,
646 struct GNUNET_SERVICE_Client *client)
647{
648 if (GNUNET_NO == try_cache (hostname, record_type, request_id, client))
649 {
650 int result = resolve_and_cache (hostname,
651 record_type,
652 request_id,
653 client);
654 GNUNET_assert (GNUNET_OK == result);
655 }
656}
657
658
804/** 659/**
805 * Handle GET-message. 660 * Handle GET-message.
806 * 661 *
@@ -812,45 +667,100 @@ handle_get (void *cls,
812 const struct GNUNET_RESOLVER_GetMessage *msg) 667 const struct GNUNET_RESOLVER_GetMessage *msg)
813{ 668{
814 struct GNUNET_SERVICE_Client *client = cls; 669 struct GNUNET_SERVICE_Client *client = cls;
815 const void *ip;
816 int direction; 670 int direction;
817 int af; 671 int af;
818 uint32_t id; 672 uint16_t request_id;
673 const char *hostname;
819 674
820 direction = ntohl (msg->direction); 675 direction = ntohl (msg->direction);
821 af = ntohl (msg->af); 676 af = ntohl (msg->af);
822 id = ntohl (msg->id); 677 request_id = ntohs (msg->id);
823 if (GNUNET_NO == direction) 678 if (GNUNET_NO == direction)
824 { 679 {
825 /* IP from hostname */ 680 /* IP from hostname */
826 const char *hostname; 681 hostname = GNUNET_strdup ((const char *) &msg[1]);
827 682 switch (af)
828 hostname = (const char *) &msg[1]; 683 {
829 get_ip_from_hostname (client, 684 case AF_UNSPEC:
830 hostname, 685 {
831 af, 686 process_get (hostname, GNUNET_DNSPARSER_TYPE_ALL, request_id, client);
832 id); 687 break;
833 return; 688 }
689 case AF_INET:
690 {
691 process_get (hostname, GNUNET_DNSPARSER_TYPE_A, request_id, client);
692 break;
693 }
694 case AF_INET6:
695 {
696 process_get (hostname, GNUNET_DNSPARSER_TYPE_AAAA, request_id, client);
697 break;
698 }
699 default:
700 {
701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
702 "got invalid af: %d\n",
703 af);
704 GNUNET_assert (0);
705 }
706 }
707 }
708 else
709 {
710 /* hostname from IP */
711 hostname = make_reverse_hostname (&msg[1], af);
712 process_get (hostname, GNUNET_DNSPARSER_TYPE_PTR, request_id, client);
834 } 713 }
835 ip = &msg[1]; 714 GNUNET_free_non_null ((char *)hostname);
715 GNUNET_SERVICE_client_continue (client);
716}
836 717
837#if !defined(GNUNET_CULL_LOGGING) 718
719static void
720shutdown_task (void *cls)
721{
722 (void) cls;
723 struct ResolveCache *pos;
724
725 while (NULL != (pos = cache_head))
838 { 726 {
839 char buf[INET6_ADDRSTRLEN]; 727 GNUNET_CONTAINER_DLL_remove (cache_head,
728 cache_tail,
729 pos);
730 free_cache_entry (pos);
731 }
732 GNUNET_DNSSTUB_stop (dnsstub_ctx);
733}
734
840 735
736static void
737init_cb (void *cls,
738 const struct GNUNET_CONFIGURATION_Handle *cfg,
739 struct GNUNET_SERVICE_Handle *sh)
740{
741 (void) cfg;
742 (void) sh;
743
744 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
745 cls);
746 dnsstub_ctx = GNUNET_DNSSTUB_start (128);
747 char **dns_servers;
748 ssize_t num_dns_servers = lookup_dns_servers (&dns_servers);
749 if (0 == num_dns_servers)
750 {
751 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
752 "no DNS server available. DNS resolution will not be possible.\n");
753 }
754 for (int i = 0; i != num_dns_servers; i++)
755 {
756 int result = GNUNET_DNSSTUB_add_dns_ip (dnsstub_ctx, dns_servers[i]);
841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
842 "Resolver asked to look up IP address `%s (request ID %u)'.\n", 758 "Adding DNS server '%s': %s\n",
843 inet_ntop (af, 759 dns_servers[i],
844 ip, 760 GNUNET_OK == result ? "success" : "failure");
845 buf, 761 GNUNET_free (dns_servers[i]);
846 sizeof (buf)),
847 id);
848 } 762 }
849#endif 763 GNUNET_free_non_null (dns_servers);
850 get_ip_as_string (client,
851 af,
852 ip,
853 id);
854} 764}
855 765
856 766
@@ -870,19 +780,6 @@ connect_cb (void *cls,
870 (void) cls; 780 (void) cls;
871 (void) mq; 781 (void) mq;
872 782
873#if HAVE_GETADDRINFO_A
874 resolve_result_pipe = GNUNET_DISK_pipe (GNUNET_NO,
875 GNUNET_NO,
876 GNUNET_NO,
877 GNUNET_NO);
878 GNUNET_assert (NULL != resolve_result_pipe);
879 resolve_result_pipe_task =
880 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
881 GNUNET_DISK_pipe_handle (resolve_result_pipe,
882 GNUNET_DISK_PIPE_END_READ),
883 &resolve_result_pipe_cb,
884 NULL);
885#endif
886 return c; 783 return c;
887} 784}
888 785
@@ -900,19 +797,16 @@ disconnect_cb (void *cls,
900 void *internal_cls) 797 void *internal_cls)
901{ 798{
902 (void) cls; 799 (void) cls;
800 struct ResolveCache *pos = cache_head;
903 801
904#if HAVE_GETADDRINFO_A 802 while (NULL != pos)
905 if (NULL != resolve_result_pipe_task)
906 {
907 GNUNET_SCHEDULER_cancel (resolve_result_pipe_task);
908 resolve_result_pipe_task = NULL;
909 }
910 if (NULL != resolve_result_pipe)
911 { 803 {
912 GNUNET_DISK_pipe_close (resolve_result_pipe); 804 if (pos->client == c)
913 resolve_result_pipe = NULL; 805 {
806 pos->client = NULL;
807 }
808 pos = pos->next;
914 } 809 }
915#endif
916 GNUNET_assert (c == internal_cls); 810 GNUNET_assert (c == internal_cls);
917} 811}
918 812
@@ -923,7 +817,7 @@ disconnect_cb (void *cls,
923GNUNET_SERVICE_MAIN 817GNUNET_SERVICE_MAIN
924("resolver", 818("resolver",
925 GNUNET_SERVICE_OPTION_NONE, 819 GNUNET_SERVICE_OPTION_NONE,
926 NULL, 820 &init_cb,
927 &connect_cb, 821 &connect_cb,
928 &disconnect_cb, 822 &disconnect_cb,
929 NULL, 823 NULL,
@@ -950,23 +844,4 @@ GNUNET_RESOLVER_memory_init ()
950#endif 844#endif
951 845
952 846
953/**
954 * Free globals on exit.
955 */
956void __attribute__ ((destructor))
957GNUNET_RESOLVER_memory_done ()
958{
959 struct IPCache *pos;
960
961 while (NULL != (pos = cache_head))
962 {
963 GNUNET_CONTAINER_DLL_remove (cache_head,
964 cache_tail,
965 pos);
966 GNUNET_free_non_null (pos->addr);
967 GNUNET_free (pos);
968 }
969}
970
971
972/* end of gnunet-service-resolver.c */ 847/* end of gnunet-service-resolver.c */
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index d13991334..a758f24f1 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -1588,7 +1588,7 @@ GNUNET_OS_start_process_s (int pipe_control,
1588 1588
1589 1589
1590/** 1590/**
1591 * Retrieve the status of a process, waiting on him if dead. 1591 * Retrieve the status of a process, waiting on it if dead.
1592 * Nonblocking version. 1592 * Nonblocking version.
1593 * 1593 *
1594 * @param proc process ID 1594 * @param proc process ID
@@ -1705,7 +1705,7 @@ process_status (struct GNUNET_OS_Process *proc,
1705 1705
1706 1706
1707/** 1707/**
1708 * Retrieve the status of a process, waiting on him if dead. 1708 * Retrieve the status of a process, waiting on it if dead.
1709 * Nonblocking version. 1709 * Nonblocking version.
1710 * 1710 *
1711 * @param proc process ID 1711 * @param proc process ID
@@ -1726,7 +1726,7 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1726 1726
1727 1727
1728/** 1728/**
1729 * Retrieve the status of a process, waiting on him if dead. 1729 * Retrieve the status of a process, waiting on it if dead.
1730 * Blocking version. 1730 * Blocking version.
1731 * 1731 *
1732 * @param proc pointer to process structure 1732 * @param proc pointer to process structure
diff --git a/src/util/resolver.h b/src/util/resolver.h
index a0f105afa..07851d052 100644
--- a/src/util/resolver.h
+++ b/src/util/resolver.h
@@ -60,7 +60,7 @@ struct GNUNET_RESOLVER_GetMessage
60 * identifies the request and is contained in the response message. The 60 * identifies the request and is contained in the response message. The
61 * client has to match response to request by this identifier. 61 * client has to match response to request by this identifier.
62 */ 62 */
63 uint32_t id GNUNET_PACKED; 63 uint16_t id GNUNET_PACKED;
64 64
65 /* followed by 0-terminated string for A/AAAA-lookup or 65 /* followed by 0-terminated string for A/AAAA-lookup or
66 by 'struct in_addr' / 'struct in6_addr' for reverse lookup */ 66 by 'struct in_addr' / 'struct in6_addr' for reverse lookup */
@@ -79,7 +79,7 @@ struct GNUNET_RESOLVER_ResponseMessage
79 * identifies the request this message responds to. The client 79 * identifies the request this message responds to. The client
80 * has to match response to request by this identifier. 80 * has to match response to request by this identifier.
81 */ 81 */
82 uint32_t id GNUNET_PACKED; 82 uint16_t id GNUNET_PACKED;
83 83
84 /* followed by 0-terminated string for response to a reverse lookup 84 /* followed by 0-terminated string for response to a reverse lookup
85 * or by 'struct in_addr' / 'struct in6_addr' for response to 85 * or by 'struct in_addr' / 'struct in6_addr' for response to
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c
index b94819f06..8a054327b 100644
--- a/src/util/resolver_api.c
+++ b/src/util/resolver_api.c
@@ -68,10 +68,10 @@ static struct GNUNET_RESOLVER_RequestHandle *req_head;
68 */ 68 */
69static struct GNUNET_RESOLVER_RequestHandle *req_tail; 69static struct GNUNET_RESOLVER_RequestHandle *req_tail;
70 70
71/** 71///**
72 * ID of the last request we sent to the service 72// * ID of the last request we sent to the service
73 */ 73// */
74static uint32_t last_request_id; 74//static uint16_t last_request_id;
75 75
76/** 76/**
77 * How long should we wait to reconnect? 77 * How long should we wait to reconnect?
@@ -445,7 +445,7 @@ process_requests ()
445 GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); 445 GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
446 msg->direction = htonl (rh->direction); 446 msg->direction = htonl (rh->direction);
447 msg->af = htonl (rh->af); 447 msg->af = htonl (rh->af);
448 msg->id = htonl (rh->id); 448 msg->id = htons (rh->id);
449 GNUNET_memcpy (&msg[1], 449 GNUNET_memcpy (&msg[1],
450 &rh[1], 450 &rh[1],
451 rh->data_len); 451 rh->data_len);
@@ -491,7 +491,7 @@ handle_response (void *cls,
491 struct GNUNET_RESOLVER_RequestHandle *rh = req_head; 491 struct GNUNET_RESOLVER_RequestHandle *rh = req_head;
492 uint16_t size; 492 uint16_t size;
493 char *nret; 493 char *nret;
494 uint32_t request_id = msg->id; 494 uint16_t request_id = msg->id;
495 495
496 for (; rh != NULL; rh = rh->next) 496 for (; rh != NULL; rh = rh->next)
497 { 497 {
@@ -911,6 +911,14 @@ handle_lookup_timeout (void *cls)
911} 911}
912 912
913 913
914static uint16_t
915get_request_id ()
916{
917 return (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
918 UINT16_MAX);
919}
920
921
914/** 922/**
915 * Convert a string to one or more IP addresses. 923 * Convert a string to one or more IP addresses.
916 * 924 *
@@ -945,7 +953,8 @@ GNUNET_RESOLVER_ip_get (const char *hostname,
945 hostname); 953 hostname);
946 rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen); 954 rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen);
947 rh->af = af; 955 rh->af = af;
948 rh->id = ++last_request_id; 956 //rh->id = ++last_request_id;
957 rh->id = get_request_id ();
949 rh->addr_callback = callback; 958 rh->addr_callback = callback;
950 rh->cls = callback_cls; 959 rh->cls = callback_cls;
951 GNUNET_memcpy (&rh[1], 960 GNUNET_memcpy (&rh[1],
@@ -1092,7 +1101,8 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa,
1092 rh->name_callback = callback; 1101 rh->name_callback = callback;
1093 rh->cls = cls; 1102 rh->cls = cls;
1094 rh->af = sa->sa_family; 1103 rh->af = sa->sa_family;
1095 rh->id = ++last_request_id; 1104 //rh->id = ++last_request_id;
1105 rh->id = get_request_id ();
1096 rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); 1106 rh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1097 GNUNET_memcpy (&rh[1], 1107 GNUNET_memcpy (&rh[1],
1098 ip, 1108 ip,