diff options
author | tg(x) <*@tg-x.net> | 2017-02-24 20:10:46 +0100 |
---|---|---|
committer | tg(x) <*@tg-x.net> | 2017-02-24 20:10:46 +0100 |
commit | b7002d3f8016478d716236238bd43a7c06c924d2 (patch) | |
tree | 3a37e4ffc3dfbb53c7dd571b85126ec762ffbbae | |
parent | cb1165ecfc5c89c22aa4a6fffb72e27e0bde43a3 (diff) | |
parent | fa0b5c44f096a68ac0a51c4cbb37c920ceb36bce (diff) | |
download | gnunet-b7002d3f8016478d716236238bd43a7c06c924d2.tar.gz gnunet-b7002d3f8016478d716236238bd43a7c06c924d2.zip |
Merge branch 'master' of gnunet.org:gnunet
45 files changed, 2536 insertions, 1764 deletions
diff --git a/contrib/gnunet-gns-import.sh b/contrib/gnunet-gns-import.sh index 8c9d1b9d4..8614821fe 100755 --- a/contrib/gnunet-gns-import.sh +++ b/contrib/gnunet-gns-import.sh | |||
@@ -63,7 +63,7 @@ gnunet-identity -e master-zone -s gns-proxy $options | |||
63 | 63 | ||
64 | # Use master-zone for intercepted DNS queries | 64 | # Use master-zone for intercepted DNS queries |
65 | # (remove this entry to disable DNS interception by GNS service) | 65 | # (remove this entry to disable DNS interception by GNS service) |
66 | gnunet-identity -e master-zone -s gns-intercept $options | 66 | gnunet-identity -e master-zone -s dns2gns $options |
67 | 67 | ||
68 | # 'gns-private' is not yet used (!) | 68 | # 'gns-private' is not yet used (!) |
69 | gnunet-identity -e private-zone -s gns-private $options | 69 | gnunet-identity -e private-zone -s gns-private $options |
diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c index 0825bd095..87adae7e9 100644 --- a/src/block/plugin_block_template.c +++ b/src/block/plugin_block_template.c | |||
@@ -111,7 +111,7 @@ block_plugin_template_create_group (void *cls, | |||
111 | } | 111 | } |
112 | GNUNET_break (NULL == va_arg (va, const char *)); | 112 | GNUNET_break (NULL == va_arg (va, const char *)); |
113 | return GNUNET_BLOCK_GROUP_bf_create (cls, | 113 | return GNUNET_BLOCK_GROUP_bf_create (cls, |
114 | TEMPLATE_BF_SIZE, | 114 | bf_size, |
115 | BLOOMFILTER_K, | 115 | BLOOMFILTER_K, |
116 | type, | 116 | type, |
117 | nonce, | 117 | nonce, |
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index af77ea067..bf05fae6b 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c | |||
@@ -603,7 +603,11 @@ GCT_count_any_connections (const struct CadetTunnel *t) | |||
603 | static struct CadetTConnection * | 603 | static struct CadetTConnection * |
604 | get_ready_connection (struct CadetTunnel *t) | 604 | get_ready_connection (struct CadetTunnel *t) |
605 | { | 605 | { |
606 | return t->connection_ready_head; | 606 | struct CadetTConnection *hd = t->connection_ready_head; |
607 | |||
608 | GNUNET_assert ( (NULL == hd) || | ||
609 | (GNUNET_YES == hd->is_ready) ); | ||
610 | return hd; | ||
607 | } | 611 | } |
608 | 612 | ||
609 | 613 | ||
@@ -1315,7 +1319,8 @@ send_kx (struct CadetTunnel *t, | |||
1315 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; | 1319 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; |
1316 | enum GNUNET_CADET_KX_Flags flags; | 1320 | enum GNUNET_CADET_KX_Flags flags; |
1317 | 1321 | ||
1318 | if (NULL == ct) | 1322 | if ( (NULL == ct) || |
1323 | (GNUNET_NO == ct->is_ready) ) | ||
1319 | ct = get_ready_connection (t); | 1324 | ct = get_ready_connection (t); |
1320 | if (NULL == ct) | 1325 | if (NULL == ct) |
1321 | { | 1326 | { |
@@ -1825,7 +1830,7 @@ GCT_handle_kx_auth (struct CadetTConnection *ct, | |||
1825 | 1, | 1830 | 1, |
1826 | GNUNET_NO); | 1831 | GNUNET_NO); |
1827 | send_kx (t, | 1832 | send_kx (t, |
1828 | NULL, | 1833 | ct, |
1829 | &t->ax); | 1834 | &t->ax); |
1830 | return; | 1835 | return; |
1831 | } | 1836 | } |
@@ -1971,13 +1976,19 @@ GCT_connection_lost (struct CadetTConnection *ct) | |||
1971 | struct CadetTunnel *t = ct->t; | 1976 | struct CadetTunnel *t = ct->t; |
1972 | 1977 | ||
1973 | if (GNUNET_YES == ct->is_ready) | 1978 | if (GNUNET_YES == ct->is_ready) |
1979 | { | ||
1974 | GNUNET_CONTAINER_DLL_remove (t->connection_ready_head, | 1980 | GNUNET_CONTAINER_DLL_remove (t->connection_ready_head, |
1975 | t->connection_ready_tail, | 1981 | t->connection_ready_tail, |
1976 | ct); | 1982 | ct); |
1983 | t->num_ready_connections--; | ||
1984 | } | ||
1977 | else | 1985 | else |
1986 | { | ||
1978 | GNUNET_CONTAINER_DLL_remove (t->connection_busy_head, | 1987 | GNUNET_CONTAINER_DLL_remove (t->connection_busy_head, |
1979 | t->connection_busy_tail, | 1988 | t->connection_busy_tail, |
1980 | ct); | 1989 | ct); |
1990 | t->num_busy_connections--; | ||
1991 | } | ||
1981 | GNUNET_free (ct); | 1992 | GNUNET_free (ct); |
1982 | } | 1993 | } |
1983 | 1994 | ||
diff --git a/src/consensus/gnunet-service-consensus.c b/src/consensus/gnunet-service-consensus.c index 16ca6a57f..4036d2b11 100644 --- a/src/consensus/gnunet-service-consensus.c +++ b/src/consensus/gnunet-service-consensus.c | |||
@@ -2013,6 +2013,7 @@ task_start_reconcile (struct TaskEntry *task) | |||
2013 | &session->global_id, | 2013 | &session->global_id, |
2014 | &rcm.header, | 2014 | &rcm.header, |
2015 | GNUNET_SET_RESULT_SYMMETRIC, | 2015 | GNUNET_SET_RESULT_SYMMETRIC, |
2016 | (struct GNUNET_SET_Option[]) { 0 }, | ||
2016 | set_result_cb, | 2017 | set_result_cb, |
2017 | task); | 2018 | task); |
2018 | 2019 | ||
@@ -2439,6 +2440,7 @@ set_listen_cb (void *cls, | |||
2439 | 2440 | ||
2440 | task->cls.setop.op = GNUNET_SET_accept (request, | 2441 | task->cls.setop.op = GNUNET_SET_accept (request, |
2441 | GNUNET_SET_RESULT_SYMMETRIC, | 2442 | GNUNET_SET_RESULT_SYMMETRIC, |
2443 | (struct GNUNET_SET_Option[]) { 0 }, | ||
2442 | set_result_cb, | 2444 | set_result_cb, |
2443 | task); | 2445 | task); |
2444 | 2446 | ||
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 52c6f72ab..31b91f12f 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c | |||
@@ -32,11 +32,19 @@ | |||
32 | #include "gnunet-service-core_typemap.h" | 32 | #include "gnunet-service-core_typemap.h" |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * How many messages do we queue up at most for optional | 35 | * How many messages do we queue up at most for any client? This can |
36 | * notifications to a client? (this can cause notifications | 36 | * cause messages to be dropped if clients do not process them fast |
37 | * about outgoing messages to be dropped). | 37 | * enough! Note that this is a soft limit; we try |
38 | * to keep a few larger messages above the limit. | ||
38 | */ | 39 | */ |
39 | #define MAX_NOTIFY_QUEUE 1024 | 40 | #define SOFT_MAX_QUEUE 128 |
41 | |||
42 | /** | ||
43 | * How many messages do we queue up at most for any client? This can | ||
44 | * cause messages to be dropped if clients do not process them fast | ||
45 | * enough! Note that this is the hard limit. | ||
46 | */ | ||
47 | #define HARD_MAX_QUEUE 256 | ||
40 | 48 | ||
41 | 49 | ||
42 | /** | 50 | /** |
@@ -819,6 +827,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, | |||
819 | struct GNUNET_MQ_Envelope *env; | 827 | struct GNUNET_MQ_Envelope *env; |
820 | struct NotifyTrafficMessage *ntm; | 828 | struct NotifyTrafficMessage *ntm; |
821 | uint16_t mtype; | 829 | uint16_t mtype; |
830 | unsigned int qlen; | ||
822 | int tm; | 831 | int tm; |
823 | 832 | ||
824 | tm = type_match (ntohs (msg->type), | 833 | tm = type_match (ntohs (msg->type), |
@@ -834,6 +843,45 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, | |||
834 | if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) && | 843 | if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) && |
835 | (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) ) | 844 | (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) ) |
836 | continue; | 845 | continue; |
846 | |||
847 | /* Drop messages if: | ||
848 | 1) We are above the hard limit, or | ||
849 | 2) We are above the soft limit, and a coin toss limited | ||
850 | to the message size (giving larger messages a | ||
851 | proportionally higher chance of being queued) falls | ||
852 | below the threshold. The threshold is based on where | ||
853 | we are between the soft and the hard limit, scaled | ||
854 | to match the range of message sizes we usually encounter | ||
855 | (i.e. up to 32k); so a 64k message has a 50% chance of | ||
856 | being kept if we are just barely below the hard max, | ||
857 | and a 99% chance of being kept if we are at the soft max. | ||
858 | The reason is to make it more likely to drop control traffic | ||
859 | (ACK, queries) which may be cummulative or highly redundant, | ||
860 | and cheap to drop than data traffic. */ | ||
861 | qlen = GNUNET_MQ_get_length (c->mq); | ||
862 | if ( (qlen >= HARD_MAX_QUEUE) || | ||
863 | ( (qlen > SOFT_MAX_QUEUE) && | ||
864 | ( (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
865 | ntohs (msg->size)) ) < | ||
866 | (qlen - SOFT_MAX_QUEUE) * 0x8000 / | ||
867 | (HARD_MAX_QUEUE - SOFT_MAX_QUEUE) ) ) ) | ||
868 | { | ||
869 | char buf[1024]; | ||
870 | |||
871 | GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, | ||
872 | "Dropping decrypted message of type %u as client is too busy (queue full)\n", | ||
873 | (unsigned int) ntohs (msg->type)); | ||
874 | GNUNET_snprintf (buf, | ||
875 | sizeof (buf), | ||
876 | gettext_noop ("# messages of type %u discarded (client busy)"), | ||
877 | (unsigned int) ntohs (msg->type)); | ||
878 | GNUNET_STATISTICS_update (GSC_stats, | ||
879 | buf, | ||
880 | 1, | ||
881 | GNUNET_NO); | ||
882 | continue; | ||
883 | } | ||
884 | |||
837 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 885 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
838 | "Sending %u message with %u bytes to client interested in messages of type %u.\n", | 886 | "Sending %u message with %u bytes to client interested in messages of type %u.\n", |
839 | options, | 887 | options, |
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c index 311a61283..916e6acae 100644 --- a/src/datastore/datastore_api.c +++ b/src/datastore/datastore_api.c | |||
@@ -498,8 +498,17 @@ make_queue_entry (struct GNUNET_DATASTORE_Handle *h, | |||
498 | struct GNUNET_DATASTORE_QueueEntry *pos; | 498 | struct GNUNET_DATASTORE_QueueEntry *pos; |
499 | unsigned int c; | 499 | unsigned int c; |
500 | 500 | ||
501 | c = 0; | 501 | if ( (NULL != h->queue_tail) && |
502 | pos = h->queue_head; | 502 | (h->queue_tail->priority >= queue_priority) ) |
503 | { | ||
504 | c = h->queue_size; | ||
505 | pos = NULL; | ||
506 | } | ||
507 | else | ||
508 | { | ||
509 | c = 0; | ||
510 | pos = h->queue_head; | ||
511 | } | ||
503 | while ( (NULL != pos) && | 512 | while ( (NULL != pos) && |
504 | (c < max_queue_size) && | 513 | (c < max_queue_size) && |
505 | (pos->priority >= queue_priority) ) | 514 | (pos->priority >= queue_priority) ) |
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 6adaa04d9..e4b664f4b 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c | |||
@@ -1528,6 +1528,7 @@ listen_set_union (void *cls, | |||
1528 | GNUNET_SET_OPERATION_UNION); | 1528 | GNUNET_SET_OPERATION_UNION); |
1529 | neighbor->set_op = GNUNET_SET_accept (request, | 1529 | neighbor->set_op = GNUNET_SET_accept (request, |
1530 | GNUNET_SET_RESULT_ADDED, | 1530 | GNUNET_SET_RESULT_ADDED, |
1531 | (struct GNUNET_SET_Option[]) { 0 }, | ||
1531 | &handle_set_union_result, | 1532 | &handle_set_union_result, |
1532 | neighbor); | 1533 | neighbor); |
1533 | neighbor->consensus_insertion_offset = 0; | 1534 | neighbor->consensus_insertion_offset = 0; |
@@ -1558,6 +1559,7 @@ initiate_set_union (void *cls) | |||
1558 | &neighbor->real_session_id, | 1559 | &neighbor->real_session_id, |
1559 | NULL, | 1560 | NULL, |
1560 | GNUNET_SET_RESULT_ADDED, | 1561 | GNUNET_SET_RESULT_ADDED, |
1562 | (struct GNUNET_SET_Option[]) { 0 }, | ||
1561 | &handle_set_union_result, | 1563 | &handle_set_union_result, |
1562 | neighbor); | 1564 | neighbor); |
1563 | neighbor->consensus_insertion_offset = 0; | 1565 | neighbor->consensus_insertion_offset = 0; |
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am index 6c4cbf114..271b4ebd7 100644 --- a/src/exit/Makefile.am +++ b/src/exit/Makefile.am | |||
@@ -30,11 +30,11 @@ endif | |||
30 | 30 | ||
31 | libexec_PROGRAMS = \ | 31 | libexec_PROGRAMS = \ |
32 | gnunet-daemon-exit \ | 32 | gnunet-daemon-exit \ |
33 | $(EXITBIN) | 33 | $(EXITBIN) |
34 | 34 | ||
35 | if MINGW | 35 | if MINGW |
36 | gnunet_helper_exit_LDFLAGS = \ | 36 | gnunet_helper_exit_LDFLAGS = \ |
37 | -no-undefined -Wl,--export-all-symbols | 37 | -no-undefined -Wl,--export-all-symbols |
38 | 38 | ||
39 | gnunet_helper_exit_LDADD = \ | 39 | gnunet_helper_exit_LDADD = \ |
40 | -lsetupapi -lnewdev -lshell32 -liconv -lstdc++ \ | 40 | -lsetupapi -lnewdev -lshell32 -liconv -lstdc++ \ |
@@ -47,13 +47,13 @@ else | |||
47 | gnunet-helper-exit.c | 47 | gnunet-helper-exit.c |
48 | endif | 48 | endif |
49 | gnunet_daemon_exit_SOURCES = \ | 49 | gnunet_daemon_exit_SOURCES = \ |
50 | gnunet-daemon-exit.c exit.h | 50 | gnunet-daemon-exit.c exit.h |
51 | gnunet_daemon_exit_LDADD = \ | 51 | gnunet_daemon_exit_LDADD = \ |
52 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ | 52 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ |
53 | $(top_builddir)/src/dht/libgnunetdht.la \ | 53 | $(top_builddir)/src/dht/libgnunetdht.la \ |
54 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 54 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
55 | $(top_builddir)/src/tun/libgnunettun.la \ | 55 | $(top_builddir)/src/tun/libgnunettun.la \ |
56 | $(top_builddir)/src/util/libgnunetutil.la \ | 56 | $(top_builddir)/src/util/libgnunetutil.la \ |
57 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | 57 | $(top_builddir)/src/cadet/libgnunetcadetnew.la \ |
58 | $(top_builddir)/src/regex/libgnunetregex.la \ | 58 | $(top_builddir)/src/regex/libgnunetregex.la \ |
59 | $(GN_LIBINTL) | 59 | $(GN_LIBINTL) |
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 92acc61cd..09576e393 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010-2013 Christian Grothoff | 3 | Copyright (C) 2010-2013, 2017 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -195,33 +195,6 @@ struct RedirectInformation | |||
195 | 195 | ||
196 | 196 | ||
197 | /** | 197 | /** |
198 | * Queue of messages to a channel. | ||
199 | */ | ||
200 | struct ChannelMessageQueue | ||
201 | { | ||
202 | /** | ||
203 | * This is a doubly-linked list. | ||
204 | */ | ||
205 | struct ChannelMessageQueue *next; | ||
206 | |||
207 | /** | ||
208 | * This is a doubly-linked list. | ||
209 | */ | ||
210 | struct ChannelMessageQueue *prev; | ||
211 | |||
212 | /** | ||
213 | * Payload to send via the channel. | ||
214 | */ | ||
215 | const void *payload; | ||
216 | |||
217 | /** | ||
218 | * Number of bytes in @e payload. | ||
219 | */ | ||
220 | size_t len; | ||
221 | }; | ||
222 | |||
223 | |||
224 | /** | ||
225 | * This struct is saved into #connections_map to allow finding the | 198 | * This struct is saved into #connections_map to allow finding the |
226 | * right channel given an IP packet from TUN. It is also associated | 199 | * right channel given an IP packet from TUN. It is also associated |
227 | * with the channel's closure so we can find it again for the next | 200 | * with the channel's closure so we can find it again for the next |
@@ -241,11 +214,6 @@ struct ChannelState | |||
241 | struct GNUNET_PeerIdentity peer; | 214 | struct GNUNET_PeerIdentity peer; |
242 | 215 | ||
243 | /** | 216 | /** |
244 | * Active channel transmission request (or NULL). | ||
245 | */ | ||
246 | struct GNUNET_CADET_TransmitHandle *th; | ||
247 | |||
248 | /** | ||
249 | * #GNUNET_NO if this is a channel for TCP/UDP, | 217 | * #GNUNET_NO if this is a channel for TCP/UDP, |
250 | * #GNUNET_YES if this is a channel for DNS, | 218 | * #GNUNET_YES if this is a channel for DNS, |
251 | * #GNUNET_SYSERR if the channel is not yet initialized. | 219 | * #GNUNET_SYSERR if the channel is not yet initialized. |
@@ -273,16 +241,6 @@ struct ChannelState | |||
273 | struct LocalService *serv; | 241 | struct LocalService *serv; |
274 | 242 | ||
275 | /** | 243 | /** |
276 | * Head of DLL of messages for this channel. | ||
277 | */ | ||
278 | struct ChannelMessageQueue *head; | ||
279 | |||
280 | /** | ||
281 | * Tail of DLL of messages for this channel. | ||
282 | */ | ||
283 | struct ChannelMessageQueue *tail; | ||
284 | |||
285 | /** | ||
286 | * Primary redirection information for this connection. | 244 | * Primary redirection information for this connection. |
287 | */ | 245 | */ |
288 | struct RedirectInformation ri; | 246 | struct RedirectInformation ri; |
@@ -292,22 +250,12 @@ struct ChannelState | |||
292 | { | 250 | { |
293 | 251 | ||
294 | /** | 252 | /** |
295 | * DNS reply ready for transmission. | ||
296 | */ | ||
297 | char *reply; | ||
298 | |||
299 | /** | ||
300 | * Socket we are using to transmit this request (must match if we receive | 253 | * Socket we are using to transmit this request (must match if we receive |
301 | * a response). | 254 | * a response). |
302 | */ | 255 | */ |
303 | struct GNUNET_DNSSTUB_RequestSocket *rs; | 256 | struct GNUNET_DNSSTUB_RequestSocket *rs; |
304 | 257 | ||
305 | /** | 258 | /** |
306 | * Number of bytes in 'reply'. | ||
307 | */ | ||
308 | size_t reply_length; | ||
309 | |||
310 | /** | ||
311 | * Original DNS request ID as used by the client. | 259 | * Original DNS request ID as used by the client. |
312 | */ | 260 | */ |
313 | uint16_t original_id; | 261 | uint16_t original_id; |
@@ -428,7 +376,7 @@ static struct GNUNET_DHT_Handle *dht; | |||
428 | /** | 376 | /** |
429 | * Task for doing DHT PUTs to advertise exit service. | 377 | * Task for doing DHT PUTs to advertise exit service. |
430 | */ | 378 | */ |
431 | static struct GNUNET_SCHEDULER_Task * dht_task; | 379 | static struct GNUNET_SCHEDULER_Task *dht_task; |
432 | 380 | ||
433 | /** | 381 | /** |
434 | * Advertisement message we put into the DHT to advertise us | 382 | * Advertisement message we put into the DHT to advertise us |
@@ -447,6 +395,21 @@ static struct GNUNET_HashCode dht_put_key; | |||
447 | static struct GNUNET_CRYPTO_EddsaPrivateKey *peer_key; | 395 | static struct GNUNET_CRYPTO_EddsaPrivateKey *peer_key; |
448 | 396 | ||
449 | /** | 397 | /** |
398 | * Port for DNS exit. | ||
399 | */ | ||
400 | static struct GNUNET_CADET_Port *dns_port; | ||
401 | |||
402 | /** | ||
403 | * Port for IPv4 exit. | ||
404 | */ | ||
405 | static struct GNUNET_CADET_Port *cadet_port4; | ||
406 | |||
407 | /** | ||
408 | * Port for IPv6 exit. | ||
409 | */ | ||
410 | static struct GNUNET_CADET_Port *cadet_port6; | ||
411 | |||
412 | /** | ||
450 | * Are we an IPv4-exit? | 413 | * Are we an IPv4-exit? |
451 | */ | 414 | */ |
452 | static int ipv4_exit; | 415 | static int ipv4_exit; |
@@ -467,51 +430,27 @@ static int ipv4_enabled; | |||
467 | static int ipv6_enabled; | 430 | static int ipv6_enabled; |
468 | 431 | ||
469 | 432 | ||
433 | GNUNET_NETWORK_STRUCT_BEGIN | ||
434 | |||
470 | /** | 435 | /** |
471 | * We got a reply from DNS for a request of a CADET channel. Send it | 436 | * Message with a DNS response. |
472 | * via the channel (after changing the request ID back). | 437 | */ |
473 | * | 438 | struct DnsResponseMessage |
474 | * @param cls the `struct ChannelState` | ||
475 | * @param size number of bytes available in @a buf | ||
476 | * @param buf where to copy the reply | ||
477 | * @return number of bytes written to @a buf | ||
478 | */ | ||
479 | static size_t | ||
480 | transmit_reply_to_cadet (void *cls, | ||
481 | size_t size, | ||
482 | void *buf) | ||
483 | { | 439 | { |
484 | struct ChannelState *ts = cls; | 440 | /** |
485 | size_t off; | 441 | * GNUnet header, of type #GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET |
486 | size_t ret; | 442 | */ |
487 | char *cbuf = buf; | 443 | struct GNUNET_MessageHeader header; |
488 | struct GNUNET_MessageHeader hdr; | 444 | |
445 | /** | ||
446 | * DNS header. | ||
447 | */ | ||
489 | struct GNUNET_TUN_DnsHeader dns; | 448 | struct GNUNET_TUN_DnsHeader dns; |
490 | 449 | ||
491 | GNUNET_assert (GNUNET_YES == ts->is_dns); | 450 | /* Followed by more DNS payload */ |
492 | ts->th = NULL; | 451 | }; |
493 | GNUNET_assert (ts->specifics.dns.reply != NULL); | 452 | |
494 | if (size == 0) | 453 | GNUNET_NETWORK_STRUCT_END |
495 | return 0; | ||
496 | ret = sizeof (struct GNUNET_MessageHeader) + ts->specifics.dns.reply_length; | ||
497 | GNUNET_assert (ret <= size); | ||
498 | hdr.size = htons (ret); | ||
499 | hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET); | ||
500 | GNUNET_memcpy (&dns, ts->specifics.dns.reply, sizeof (dns)); | ||
501 | dns.id = ts->specifics.dns.original_id; | ||
502 | off = 0; | ||
503 | GNUNET_memcpy (&cbuf[off], &hdr, sizeof (hdr)); | ||
504 | off += sizeof (hdr); | ||
505 | GNUNET_memcpy (&cbuf[off], &dns, sizeof (dns)); | ||
506 | off += sizeof (dns); | ||
507 | GNUNET_memcpy (&cbuf[off], &ts->specifics.dns.reply[sizeof (dns)], ts->specifics.dns.reply_length - sizeof (dns)); | ||
508 | off += ts->specifics.dns.reply_length - sizeof (dns); | ||
509 | GNUNET_free (ts->specifics.dns.reply); | ||
510 | ts->specifics.dns.reply = NULL; | ||
511 | ts->specifics.dns.reply_length = 0; | ||
512 | GNUNET_assert (ret == off); | ||
513 | return ret; | ||
514 | } | ||
515 | 454 | ||
516 | 455 | ||
517 | /** | 456 | /** |
@@ -521,7 +460,7 @@ transmit_reply_to_cadet (void *cls, | |||
521 | * @param cls NULL | 460 | * @param cls NULL |
522 | * @param rs the socket that received the response | 461 | * @param rs the socket that received the response |
523 | * @param dns the response itself | 462 | * @param dns the response itself |
524 | * @param r number of bytes in dns | 463 | * @param r number of bytes in @a dns |
525 | */ | 464 | */ |
526 | static void | 465 | static void |
527 | process_dns_result (void *cls, | 466 | process_dns_result (void *cls, |
@@ -530,6 +469,8 @@ process_dns_result (void *cls, | |||
530 | size_t r) | 469 | size_t r) |
531 | { | 470 | { |
532 | struct ChannelState *ts; | 471 | struct ChannelState *ts; |
472 | struct GNUNET_MQ_Envelope *env; | ||
473 | struct DnsResponseMessage *resp; | ||
533 | 474 | ||
534 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 475 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
535 | "Processing DNS result from stub resolver\n"); | 476 | "Processing DNS result from stub resolver\n"); |
@@ -542,48 +483,35 @@ process_dns_result (void *cls, | |||
542 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 483 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
543 | "Got a response from the stub resolver for DNS request received via CADET!\n"); | 484 | "Got a response from the stub resolver for DNS request received via CADET!\n"); |
544 | channels[dns->id] = NULL; | 485 | channels[dns->id] = NULL; |
545 | GNUNET_free_non_null (ts->specifics.dns.reply); | 486 | env = GNUNET_MQ_msg_extra (resp, |
546 | ts->specifics.dns.reply = GNUNET_malloc (r); | 487 | r - sizeof (struct GNUNET_TUN_DnsHeader), |
547 | ts->specifics.dns.reply_length = r; | 488 | GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET); |
548 | GNUNET_memcpy (ts->specifics.dns.reply, dns, r); | 489 | GNUNET_memcpy (&resp->dns, |
549 | if (NULL != ts->th) | 490 | dns, |
550 | GNUNET_CADET_notify_transmit_ready_cancel (ts->th); | 491 | r); |
551 | ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel, | 492 | resp->dns.id = ts->specifics.dns.original_id; |
552 | GNUNET_NO, | 493 | GNUNET_MQ_send (GNUNET_CADET_get_mq (ts->channel), |
553 | GNUNET_TIME_UNIT_FOREVER_REL, | 494 | env); |
554 | sizeof (struct GNUNET_MessageHeader) + r, | ||
555 | &transmit_reply_to_cadet, | ||
556 | ts); | ||
557 | } | 495 | } |
558 | 496 | ||
559 | 497 | ||
560 | /** | 498 | /** |
561 | * Process a request via cadet to perform a DNS query. | 499 | * Check a request via cadet to perform a DNS query. |
562 | * | ||
563 | * @param cls closure, NULL | ||
564 | * @param channel connection to the other end | ||
565 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
566 | * @param message the actual message | ||
567 | * | 500 | * |
501 | * @param cls our `struct ChannelState *` | ||
502 | * @param msg the actual message | ||
568 | * @return #GNUNET_OK to keep the connection open, | 503 | * @return #GNUNET_OK to keep the connection open, |
569 | * #GNUNET_SYSERR to close it (signal serious error) | 504 | * #GNUNET_SYSERR to close it (signal serious error) |
570 | */ | 505 | */ |
571 | static int | 506 | static int |
572 | receive_dns_request (void *cls GNUNET_UNUSED, | 507 | check_dns_request (void *cls, |
573 | struct GNUNET_CADET_Channel *channel, | 508 | const struct DnsResponseMessage *msg) |
574 | void **channel_ctx, | ||
575 | const struct GNUNET_MessageHeader *message) | ||
576 | { | 509 | { |
577 | struct ChannelState *ts = *channel_ctx; | 510 | struct ChannelState *ts = cls; |
578 | const struct GNUNET_TUN_DnsHeader *dns; | ||
579 | size_t mlen = ntohs (message->size); | ||
580 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); | ||
581 | char buf[dlen] GNUNET_ALIGN; | ||
582 | struct GNUNET_TUN_DnsHeader *dout; | ||
583 | 511 | ||
584 | if (NULL == dnsstub) | 512 | if (NULL == dnsstub) |
585 | { | 513 | { |
586 | GNUNET_break_op (0); | 514 | GNUNET_break (0); |
587 | return GNUNET_SYSERR; | 515 | return GNUNET_SYSERR; |
588 | } | 516 | } |
589 | if (GNUNET_NO == ts->is_dns) | 517 | if (GNUNET_NO == ts->is_dns) |
@@ -591,34 +519,53 @@ receive_dns_request (void *cls GNUNET_UNUSED, | |||
591 | GNUNET_break_op (0); | 519 | GNUNET_break_op (0); |
592 | return GNUNET_SYSERR; | 520 | return GNUNET_SYSERR; |
593 | } | 521 | } |
522 | return GNUNET_OK; | ||
523 | } | ||
524 | |||
525 | |||
526 | /** | ||
527 | * Process a request via cadet to perform a DNS query. | ||
528 | * | ||
529 | * @param cls our `struct ChannelState *` | ||
530 | * @param msg the actual message | ||
531 | */ | ||
532 | static void | ||
533 | handle_dns_request (void *cls, | ||
534 | const struct DnsResponseMessage *msg) | ||
535 | { | ||
536 | struct ChannelState *ts = cls; | ||
537 | size_t mlen = ntohs (msg->header.size); | ||
538 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); | ||
539 | char buf[dlen] GNUNET_ALIGN; | ||
540 | struct GNUNET_TUN_DnsHeader *dout; | ||
541 | |||
594 | if (GNUNET_SYSERR == ts->is_dns) | 542 | if (GNUNET_SYSERR == ts->is_dns) |
595 | { | 543 | { |
596 | /* channel is DNS from now on */ | 544 | /* channel is DNS from now on */ |
597 | ts->is_dns = GNUNET_YES; | 545 | ts->is_dns = GNUNET_YES; |
598 | } | 546 | } |
599 | if (dlen < sizeof (struct GNUNET_TUN_DnsHeader)) | 547 | ts->specifics.dns.original_id = msg->dns.id; |
600 | { | ||
601 | GNUNET_break_op (0); | ||
602 | return GNUNET_SYSERR; | ||
603 | } | ||
604 | dns = (const struct GNUNET_TUN_DnsHeader *) &message[1]; | ||
605 | ts->specifics.dns.original_id = dns->id; | ||
606 | if (channels[ts->specifics.dns.my_id] == ts) | 548 | if (channels[ts->specifics.dns.my_id] == ts) |
607 | channels[ts->specifics.dns.my_id] = NULL; | 549 | channels[ts->specifics.dns.my_id] = NULL; |
608 | ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 550 | ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
609 | UINT16_MAX + 1); | 551 | UINT16_MAX + 1); |
610 | channels[ts->specifics.dns.my_id] = ts; | 552 | channels[ts->specifics.dns.my_id] = ts; |
611 | GNUNET_memcpy (buf, dns, dlen); | 553 | GNUNET_memcpy (buf, |
554 | &msg->dns, | ||
555 | dlen); | ||
612 | dout = (struct GNUNET_TUN_DnsHeader *) buf; | 556 | dout = (struct GNUNET_TUN_DnsHeader *) buf; |
613 | dout->id = ts->specifics.dns.my_id; | 557 | dout->id = ts->specifics.dns.my_id; |
614 | ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve2 (dnsstub, | 558 | ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve2 (dnsstub, |
615 | buf, dlen, | 559 | buf, |
560 | dlen, | ||
616 | &process_dns_result, | 561 | &process_dns_result, |
617 | NULL); | 562 | NULL); |
618 | if (NULL == ts->specifics.dns.rs) | 563 | if (NULL == ts->specifics.dns.rs) |
619 | return GNUNET_SYSERR; | 564 | { |
620 | GNUNET_CADET_receive_done (channel); | 565 | GNUNET_break_op (0); |
621 | return GNUNET_OK; | 566 | return; |
567 | } | ||
568 | GNUNET_CADET_receive_done (ts->channel); | ||
622 | } | 569 | } |
623 | 570 | ||
624 | 571 | ||
@@ -753,706 +700,445 @@ get_redirect_state (int af, | |||
753 | } | 700 | } |
754 | 701 | ||
755 | 702 | ||
756 | /** | ||
757 | * Free memory associated with a service record. | ||
758 | * | ||
759 | * @param cls unused | ||
760 | * @param key service descriptor | ||
761 | * @param value service record to free | ||
762 | * @return #GNUNET_OK | ||
763 | */ | ||
764 | static int | ||
765 | free_service_record (void *cls, | ||
766 | const struct GNUNET_HashCode *key, | ||
767 | void *value) | ||
768 | { | ||
769 | struct LocalService *service = value; | ||
770 | |||
771 | GNUNET_assert (GNUNET_YES == | ||
772 | GNUNET_CONTAINER_multihashmap_remove (services, | ||
773 | key, | ||
774 | service)); | ||
775 | GNUNET_CADET_close_port (service->port); | ||
776 | GNUNET_free_non_null (service->name); | ||
777 | GNUNET_free (service); | ||
778 | return GNUNET_OK; | ||
779 | } | ||
780 | |||
781 | |||
782 | /** | ||
783 | * Callback from CADET for new channels. | ||
784 | * | ||
785 | * @param cls closure | ||
786 | * @param channel new handle to the channel | ||
787 | * @param initiator peer that started the channel | ||
788 | * @param port destination port | ||
789 | * @param options channel options flags | ||
790 | * @return initial channel context for the channel | ||
791 | */ | ||
792 | static void * | ||
793 | new_service_channel (void *cls, | ||
794 | struct GNUNET_CADET_Channel *channel, | ||
795 | const struct GNUNET_PeerIdentity *initiator, | ||
796 | const struct GNUNET_HashCode *port, | ||
797 | enum GNUNET_CADET_ChannelOption options) | ||
798 | { | ||
799 | struct LocalService *ls = cls; | ||
800 | struct ChannelState *s = GNUNET_new (struct ChannelState); | ||
801 | |||
802 | s->peer = *initiator; | ||
803 | GNUNET_STATISTICS_update (stats, | ||
804 | gettext_noop ("# Inbound CADET channels created"), | ||
805 | 1, | ||
806 | GNUNET_NO); | ||
807 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
808 | "Received inbound channel from `%s'\n", | ||
809 | GNUNET_i2s (initiator)); | ||
810 | s->channel = channel; | ||
811 | s->specifics.tcp_udp.serv = ls; | ||
812 | s->specifics.tcp_udp.ri.remote_address = ls->address; | ||
813 | return s; | ||
814 | } | ||
815 | |||
816 | 703 | ||
817 | /** | 704 | /** |
818 | * Given a service descriptor and a destination port, find the | 705 | * Check a request via cadet to send a request to a TCP service |
819 | * respective service entry. | 706 | * offered by this system. |
820 | * | 707 | * |
821 | * @param proto IPPROTO_TCP or IPPROTO_UDP | 708 | * @param cls our `struct ChannelState *` |
822 | * @param name name of the service | 709 | * @param start the actual message |
823 | * @param destination_port destination port | 710 | * @return #GNUNET_OK to keep the connection open, |
824 | * @param service service information record to store (service->name will be set). | 711 | * #GNUNET_SYSERR to close it (signal serious error) |
825 | */ | 712 | */ |
826 | static void | 713 | static int |
827 | store_service (int proto, | 714 | check_tcp_service (void *cls, |
828 | const char *name, | 715 | const struct GNUNET_EXIT_TcpServiceStartMessage *start) |
829 | uint16_t destination_port, | ||
830 | struct LocalService *service) | ||
831 | { | 716 | { |
832 | struct GNUNET_HashCode cadet_port; | 717 | struct ChannelState *state = cls; |
833 | 718 | ||
834 | service->name = GNUNET_strdup (name); | 719 | if (NULL == state) |
835 | GNUNET_TUN_service_name_to_hash (name, | ||
836 | &service->descriptor); | ||
837 | GNUNET_TUN_compute_service_cadet_port (&service->descriptor, | ||
838 | destination_port, | ||
839 | &cadet_port); | ||
840 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
841 | "Opening CADET port %s for SERVICE exit %s on port %u\n", | ||
842 | GNUNET_h2s (&cadet_port), | ||
843 | name, | ||
844 | (unsigned int) destination_port); | ||
845 | service->port = GNUNET_CADET_open_port (cadet_handle, | ||
846 | &cadet_port, | ||
847 | &new_service_channel, | ||
848 | service); | ||
849 | service->is_udp = (IPPROTO_UDP == proto); | ||
850 | if (GNUNET_OK != | ||
851 | GNUNET_CONTAINER_multihashmap_put (services, | ||
852 | &cadet_port, | ||
853 | service, | ||
854 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
855 | { | 720 | { |
856 | GNUNET_CADET_close_port (service->port); | 721 | GNUNET_break_op (0); |
857 | GNUNET_free_non_null (service->name); | 722 | return GNUNET_SYSERR; |
858 | GNUNET_free (service); | ||
859 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
860 | _("Got duplicate service records for `%s:%u'\n"), | ||
861 | name, | ||
862 | (unsigned int) destination_port); | ||
863 | } | 723 | } |
724 | if (GNUNET_YES == state->is_dns) | ||
725 | { | ||
726 | GNUNET_break_op (0); | ||
727 | return GNUNET_SYSERR; | ||
728 | } | ||
729 | if (NULL == state->specifics.tcp_udp.serv) | ||
730 | { | ||
731 | GNUNET_break_op (0); | ||
732 | return GNUNET_SYSERR; | ||
733 | } | ||
734 | if (NULL != state->specifics.tcp_udp.heap_node) | ||
735 | { | ||
736 | GNUNET_break_op (0); | ||
737 | return GNUNET_SYSERR; | ||
738 | } | ||
739 | if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
740 | { | ||
741 | GNUNET_break_op (0); | ||
742 | return GNUNET_SYSERR; | ||
743 | } | ||
744 | return GNUNET_OK; | ||
864 | } | 745 | } |
865 | 746 | ||
866 | 747 | ||
867 | /** | 748 | /** |
868 | * CADET is ready to receive a message for the channel. Transmit it. | 749 | * Prepare an IPv4 packet for transmission via the TUN interface. |
869 | * | 750 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). |
870 | * @param cls the `struct ChannelState`. | 751 | * For UDP, the UDP header will be fully created, whereas for TCP |
871 | * @param size number of bytes available in @a buf | 752 | * only the ports and checksum will be filled in. So for TCP, |
872 | * @param buf where to copy the message | 753 | * a skeleton TCP header must be part of the provided payload. |
873 | * @return number of bytes copied to @a buf | ||
874 | */ | ||
875 | static size_t | ||
876 | send_to_peer_notify_callback (void *cls, | ||
877 | size_t size, | ||
878 | void *buf) | ||
879 | { | ||
880 | struct ChannelState *s = cls; | ||
881 | struct GNUNET_CADET_Channel *channel = s->channel; | ||
882 | struct ChannelMessageQueue *tnq; | ||
883 | |||
884 | s->th = NULL; | ||
885 | tnq = s->specifics.tcp_udp.head; | ||
886 | if (NULL == tnq) | ||
887 | return 0; | ||
888 | if (0 == size) | ||
889 | { | ||
890 | s->th = GNUNET_CADET_notify_transmit_ready (channel, | ||
891 | GNUNET_NO /* corking */, | ||
892 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
893 | tnq->len, | ||
894 | &send_to_peer_notify_callback, | ||
895 | s); | ||
896 | return 0; | ||
897 | } | ||
898 | GNUNET_assert (size >= tnq->len); | ||
899 | GNUNET_memcpy (buf, tnq->payload, tnq->len); | ||
900 | size = tnq->len; | ||
901 | GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head, | ||
902 | s->specifics.tcp_udp.tail, | ||
903 | tnq); | ||
904 | GNUNET_free (tnq); | ||
905 | if (NULL != (tnq = s->specifics.tcp_udp.head)) | ||
906 | s->th = GNUNET_CADET_notify_transmit_ready (channel, | ||
907 | GNUNET_NO /* corking */, | ||
908 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
909 | tnq->len, | ||
910 | &send_to_peer_notify_callback, | ||
911 | s); | ||
912 | GNUNET_STATISTICS_update (stats, | ||
913 | gettext_noop ("# Bytes transmitted via cadet channels"), | ||
914 | size, GNUNET_NO); | ||
915 | return size; | ||
916 | } | ||
917 | |||
918 | |||
919 | /** | ||
920 | * Send the given packet via the cadet channel. | ||
921 | * | ||
922 | * @param s channel destination | ||
923 | * @param tnq message to queue | ||
924 | */ | ||
925 | static void | ||
926 | send_packet_to_cadet_channel (struct ChannelState *s, | ||
927 | struct ChannelMessageQueue *tnq) | ||
928 | { | ||
929 | struct GNUNET_CADET_Channel *cadet_channel; | ||
930 | |||
931 | cadet_channel = s->channel; | ||
932 | GNUNET_assert (NULL != s); | ||
933 | GNUNET_CONTAINER_DLL_insert_tail (s->specifics.tcp_udp.head, | ||
934 | s->specifics.tcp_udp.tail, | ||
935 | tnq); | ||
936 | if (NULL == s->th) | ||
937 | s->th = GNUNET_CADET_notify_transmit_ready (cadet_channel, | ||
938 | GNUNET_NO /* cork */, | ||
939 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
940 | tnq->len, | ||
941 | &send_to_peer_notify_callback, | ||
942 | s); | ||
943 | } | ||
944 | |||
945 | |||
946 | /** | ||
947 | * @brief Handles an ICMP packet received from the helper. | ||
948 | * | 754 | * |
949 | * @param icmp A pointer to the Packet | 755 | * @param payload payload of the packet (starting with UDP payload or |
950 | * @param pktlen number of bytes in @a icmp | 756 | * TCP header, depending on protocol) |
951 | * @param af address family (AFINET or AF_INET6) | 757 | * @param payload_length number of bytes in @a payload |
952 | * @param destination_ip destination IP-address of the IP packet (should | 758 | * @param protocol IPPROTO_UDP or IPPROTO_TCP |
953 | * be our local address) | 759 | * @param tcp_header skeleton of the TCP header, NULL for UDP |
954 | * @param source_ip original source IP-address of the IP packet (should | 760 | * @param src_address source address to use (IP and port) |
955 | * be the original destination address) | 761 | * @param dst_address destination address to use (IP and port) |
762 | * @param pkt4 where to write the assembled packet; must | ||
763 | * contain enough space for the IP header, UDP/TCP header | ||
764 | * AND the payload | ||
956 | */ | 765 | */ |
957 | static void | 766 | static void |
958 | icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp, | 767 | prepare_ipv4_packet (const void *payload, |
959 | size_t pktlen, | 768 | size_t payload_length, |
960 | int af, | 769 | int protocol, |
961 | const void *destination_ip, | 770 | const struct GNUNET_TUN_TcpHeader *tcp_header, |
962 | const void *source_ip) | 771 | const struct SocketAddress *src_address, |
772 | const struct SocketAddress *dst_address, | ||
773 | struct GNUNET_TUN_IPv4Header *pkt4) | ||
963 | { | 774 | { |
964 | struct ChannelState *state; | 775 | size_t len; |
965 | struct ChannelMessageQueue *tnq; | ||
966 | struct GNUNET_EXIT_IcmpToVPNMessage *i2v; | ||
967 | const struct GNUNET_TUN_IPv4Header *ipv4; | ||
968 | const struct GNUNET_TUN_IPv6Header *ipv6; | ||
969 | const struct GNUNET_TUN_UdpHeader *udp; | ||
970 | size_t mlen; | ||
971 | uint16_t source_port; | ||
972 | uint16_t destination_port; | ||
973 | uint8_t protocol; | ||
974 | 776 | ||
777 | len = payload_length; | ||
778 | switch (protocol) | ||
975 | { | 779 | { |
976 | char sbuf[INET6_ADDRSTRLEN]; | 780 | case IPPROTO_UDP: |
977 | char dbuf[INET6_ADDRSTRLEN]; | 781 | len += sizeof (struct GNUNET_TUN_UdpHeader); |
978 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 782 | break; |
979 | "Received ICMP packet going from %s to %s\n", | 783 | case IPPROTO_TCP: |
980 | inet_ntop (af, | 784 | len += sizeof (struct GNUNET_TUN_TcpHeader); |
981 | source_ip, | 785 | GNUNET_assert (NULL != tcp_header); |
982 | sbuf, sizeof (sbuf)), | 786 | break; |
983 | inet_ntop (af, | 787 | default: |
984 | destination_ip, | 788 | GNUNET_break (0); |
985 | dbuf, sizeof (dbuf))); | 789 | return; |
986 | } | 790 | } |
987 | if (pktlen < sizeof (struct GNUNET_TUN_IcmpHeader)) | 791 | if (len + sizeof (struct GNUNET_TUN_IPv4Header) > UINT16_MAX) |
988 | { | 792 | { |
989 | /* blame kernel */ | ||
990 | GNUNET_break (0); | 793 | GNUNET_break (0); |
991 | return; | 794 | return; |
992 | } | 795 | } |
993 | 796 | ||
994 | /* Find out if this is an ICMP packet in response to an existing | 797 | GNUNET_TUN_initialize_ipv4_header (pkt4, |
995 | TCP/UDP packet and if so, figure out ports / protocol of the | 798 | protocol, |
996 | existing session from the IP data in the ICMP payload */ | 799 | len, |
997 | source_port = 0; | 800 | &src_address->address.ipv4, |
998 | destination_port = 0; | 801 | &dst_address->address.ipv4); |
999 | switch (af) | ||
1000 | { | ||
1001 | case AF_INET: | ||
1002 | protocol = IPPROTO_ICMP; | ||
1003 | switch (icmp->type) | ||
1004 | { | ||
1005 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
1006 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
1007 | break; | ||
1008 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
1009 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
1010 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
1011 | if (pktlen < | ||
1012 | sizeof (struct GNUNET_TUN_IcmpHeader) + | ||
1013 | sizeof (struct GNUNET_TUN_IPv4Header) + 8) | ||
1014 | { | ||
1015 | /* blame kernel */ | ||
1016 | GNUNET_break (0); | ||
1017 | return; | ||
1018 | } | ||
1019 | ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1020 | protocol = ipv4->protocol; | ||
1021 | /* could be TCP or UDP, but both have the ports in the right | ||
1022 | place, so that doesn't matter here */ | ||
1023 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
1024 | /* swap ports, as they are from the original message */ | ||
1025 | destination_port = ntohs (udp->source_port); | ||
1026 | source_port = ntohs (udp->destination_port); | ||
1027 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
1028 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1029 | break; | ||
1030 | default: | ||
1031 | GNUNET_STATISTICS_update (stats, | ||
1032 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
1033 | 1, GNUNET_NO); | ||
1034 | return; | ||
1035 | } | ||
1036 | break; | ||
1037 | case AF_INET6: | ||
1038 | protocol = IPPROTO_ICMPV6; | ||
1039 | switch (icmp->type) | ||
1040 | { | ||
1041 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
1042 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
1043 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
1044 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
1045 | if (pktlen < | ||
1046 | sizeof (struct GNUNET_TUN_IcmpHeader) + | ||
1047 | sizeof (struct GNUNET_TUN_IPv6Header) + 8) | ||
1048 | { | ||
1049 | /* blame kernel */ | ||
1050 | GNUNET_break (0); | ||
1051 | return; | ||
1052 | } | ||
1053 | ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1054 | protocol = ipv6->next_header; | ||
1055 | /* could be TCP or UDP, but both have the ports in the right | ||
1056 | place, so that doesn't matter here */ | ||
1057 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
1058 | /* swap ports, as they are from the original message */ | ||
1059 | destination_port = ntohs (udp->source_port); | ||
1060 | source_port = ntohs (udp->destination_port); | ||
1061 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
1062 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1063 | break; | ||
1064 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
1065 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
1066 | break; | ||
1067 | default: | ||
1068 | GNUNET_STATISTICS_update (stats, | ||
1069 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
1070 | 1, GNUNET_NO); | ||
1071 | return; | ||
1072 | } | ||
1073 | break; | ||
1074 | default: | ||
1075 | GNUNET_assert (0); | ||
1076 | } | ||
1077 | switch (protocol) | 802 | switch (protocol) |
1078 | { | 803 | { |
1079 | case IPPROTO_ICMP: | ||
1080 | state = get_redirect_state (af, | ||
1081 | IPPROTO_ICMP, | ||
1082 | source_ip, | ||
1083 | 0, | ||
1084 | destination_ip, | ||
1085 | 0, | ||
1086 | NULL); | ||
1087 | break; | ||
1088 | case IPPROTO_ICMPV6: | ||
1089 | state = get_redirect_state (af, | ||
1090 | IPPROTO_ICMPV6, | ||
1091 | source_ip, | ||
1092 | 0, | ||
1093 | destination_ip, | ||
1094 | 0, | ||
1095 | NULL); | ||
1096 | break; | ||
1097 | case IPPROTO_UDP: | 804 | case IPPROTO_UDP: |
1098 | state = get_redirect_state (af, | 805 | { |
1099 | IPPROTO_UDP, | 806 | struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1]; |
1100 | source_ip, | 807 | |
1101 | source_port, | 808 | pkt4_udp->source_port = htons (src_address->port); |
1102 | destination_ip, | 809 | pkt4_udp->destination_port = htons (dst_address->port); |
1103 | destination_port, | 810 | pkt4_udp->len = htons ((uint16_t) payload_length); |
1104 | NULL); | 811 | GNUNET_TUN_calculate_udp4_checksum (pkt4, |
812 | pkt4_udp, | ||
813 | payload, | ||
814 | payload_length); | ||
815 | GNUNET_memcpy (&pkt4_udp[1], | ||
816 | payload, | ||
817 | payload_length); | ||
818 | } | ||
1105 | break; | 819 | break; |
1106 | case IPPROTO_TCP: | 820 | case IPPROTO_TCP: |
1107 | state = get_redirect_state (af, | 821 | { |
1108 | IPPROTO_TCP, | 822 | struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1]; |
1109 | source_ip, | 823 | |
1110 | source_port, | 824 | *pkt4_tcp = *tcp_header; |
1111 | destination_ip, | 825 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1112 | destination_port, | 826 | "Sending TCP packet from port %u to port %u\n", |
1113 | NULL); | 827 | src_address->port, |
828 | dst_address->port); | ||
829 | pkt4_tcp->source_port = htons (src_address->port); | ||
830 | pkt4_tcp->destination_port = htons (dst_address->port); | ||
831 | GNUNET_TUN_calculate_tcp4_checksum (pkt4, | ||
832 | pkt4_tcp, | ||
833 | payload, | ||
834 | payload_length); | ||
835 | GNUNET_memcpy (&pkt4_tcp[1], | ||
836 | payload, | ||
837 | payload_length); | ||
838 | } | ||
1114 | break; | 839 | break; |
1115 | default: | 840 | default: |
1116 | GNUNET_STATISTICS_update (stats, | 841 | GNUNET_assert (0); |
1117 | gettext_noop ("# ICMP packets dropped (not allowed)"), | ||
1118 | 1, | ||
1119 | GNUNET_NO); | ||
1120 | return; | ||
1121 | } | ||
1122 | if (NULL == state) | ||
1123 | { | ||
1124 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1125 | _("ICMP Packet dropped, have no matching connection information\n")); | ||
1126 | return; | ||
1127 | } | 842 | } |
1128 | mlen = sizeof (struct GNUNET_EXIT_IcmpToVPNMessage) + pktlen - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1129 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueue) + mlen); | ||
1130 | tnq->payload = &tnq[1]; | ||
1131 | tnq->len = mlen; | ||
1132 | i2v = (struct GNUNET_EXIT_IcmpToVPNMessage *) &tnq[1]; | ||
1133 | i2v->header.size = htons ((uint16_t) mlen); | ||
1134 | i2v->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN); | ||
1135 | i2v->af = htonl (af); | ||
1136 | GNUNET_memcpy (&i2v->icmp_header, | ||
1137 | icmp, | ||
1138 | pktlen); | ||
1139 | send_packet_to_cadet_channel (state, tnq); | ||
1140 | } | 843 | } |
1141 | 844 | ||
1142 | 845 | ||
1143 | /** | 846 | /** |
1144 | * @brief Handles an UDP packet received from the helper. | 847 | * Prepare an IPv6 packet for transmission via the TUN interface. |
848 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). | ||
849 | * For UDP, the UDP header will be fully created, whereas for TCP | ||
850 | * only the ports and checksum will be filled in. So for TCP, | ||
851 | * a skeleton TCP header must be part of the provided payload. | ||
1145 | * | 852 | * |
1146 | * @param udp A pointer to the Packet | 853 | * @param payload payload of the packet (starting with UDP payload or |
1147 | * @param pktlen number of bytes in 'udp' | 854 | * TCP header, depending on protocol) |
1148 | * @param af address family (AFINET or AF_INET6) | 855 | * @param payload_length number of bytes in @a payload |
1149 | * @param destination_ip destination IP-address of the IP packet (should | 856 | * @param protocol IPPROTO_UDP or IPPROTO_TCP |
1150 | * be our local address) | 857 | * @param tcp_header skeleton TCP header data to send, NULL for UDP |
1151 | * @param source_ip original source IP-address of the IP packet (should | 858 | * @param src_address source address to use (IP and port) |
1152 | * be the original destination address) | 859 | * @param dst_address destination address to use (IP and port) |
860 | * @param pkt6 where to write the assembled packet; must | ||
861 | * contain enough space for the IP header, UDP/TCP header | ||
862 | * AND the payload | ||
1153 | */ | 863 | */ |
1154 | static void | 864 | static void |
1155 | udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp, | 865 | prepare_ipv6_packet (const void *payload, |
1156 | size_t pktlen, | 866 | size_t payload_length, |
1157 | int af, | 867 | int protocol, |
1158 | const void *destination_ip, | 868 | const struct GNUNET_TUN_TcpHeader *tcp_header, |
1159 | const void *source_ip) | 869 | const struct SocketAddress *src_address, |
870 | const struct SocketAddress *dst_address, | ||
871 | struct GNUNET_TUN_IPv6Header *pkt6) | ||
1160 | { | 872 | { |
1161 | struct ChannelState *state; | 873 | size_t len; |
1162 | struct ChannelMessageQueue *tnq; | ||
1163 | struct GNUNET_EXIT_UdpReplyMessage *urm; | ||
1164 | size_t mlen; | ||
1165 | 874 | ||
875 | len = payload_length; | ||
876 | switch (protocol) | ||
1166 | { | 877 | { |
1167 | char sbuf[INET6_ADDRSTRLEN]; | 878 | case IPPROTO_UDP: |
1168 | char dbuf[INET6_ADDRSTRLEN]; | 879 | len += sizeof (struct GNUNET_TUN_UdpHeader); |
1169 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 880 | break; |
1170 | "Received UDP packet going from %s:%u to %s:%u\n", | 881 | case IPPROTO_TCP: |
1171 | inet_ntop (af, | 882 | len += sizeof (struct GNUNET_TUN_TcpHeader); |
1172 | source_ip, | 883 | break; |
1173 | sbuf, sizeof (sbuf)), | 884 | default: |
1174 | (unsigned int) ntohs (udp->source_port), | ||
1175 | inet_ntop (af, | ||
1176 | destination_ip, | ||
1177 | dbuf, sizeof (dbuf)), | ||
1178 | (unsigned int) ntohs (udp->destination_port)); | ||
1179 | } | ||
1180 | if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader)) | ||
1181 | { | ||
1182 | /* blame kernel */ | ||
1183 | GNUNET_break (0); | 885 | GNUNET_break (0); |
1184 | return; | 886 | return; |
1185 | } | 887 | } |
1186 | if (pktlen != ntohs (udp->len)) | 888 | if (len > UINT16_MAX) |
1187 | { | 889 | { |
1188 | /* blame kernel */ | ||
1189 | GNUNET_break (0); | 890 | GNUNET_break (0); |
1190 | return; | 891 | return; |
1191 | } | 892 | } |
1192 | state = get_redirect_state (af, | 893 | |
1193 | IPPROTO_UDP, | 894 | GNUNET_TUN_initialize_ipv6_header (pkt6, |
1194 | source_ip, | 895 | protocol, |
1195 | ntohs (udp->source_port), | 896 | len, |
1196 | destination_ip, | 897 | &src_address->address.ipv6, |
1197 | ntohs (udp->destination_port), | 898 | &dst_address->address.ipv6); |
1198 | NULL); | 899 | |
1199 | if (NULL == state) | 900 | switch (protocol) |
1200 | { | 901 | { |
1201 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 902 | case IPPROTO_UDP: |
1202 | _("UDP Packet dropped, have no matching connection information\n")); | 903 | { |
1203 | return; | 904 | struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1]; |
905 | |||
906 | pkt6_udp->source_port = htons (src_address->port); | ||
907 | pkt6_udp->destination_port = htons (dst_address->port); | ||
908 | pkt6_udp->len = htons ((uint16_t) payload_length); | ||
909 | GNUNET_TUN_calculate_udp6_checksum (pkt6, | ||
910 | pkt6_udp, | ||
911 | payload, | ||
912 | payload_length); | ||
913 | GNUNET_memcpy (&pkt6_udp[1], | ||
914 | payload, | ||
915 | payload_length); | ||
916 | } | ||
917 | break; | ||
918 | case IPPROTO_TCP: | ||
919 | { | ||
920 | struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt6[1]; | ||
921 | |||
922 | /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */ | ||
923 | *pkt6_tcp = *tcp_header; | ||
924 | pkt6_tcp->source_port = htons (src_address->port); | ||
925 | pkt6_tcp->destination_port = htons (dst_address->port); | ||
926 | GNUNET_TUN_calculate_tcp6_checksum (pkt6, | ||
927 | pkt6_tcp, | ||
928 | payload, | ||
929 | payload_length); | ||
930 | GNUNET_memcpy (&pkt6_tcp[1], | ||
931 | payload, | ||
932 | payload_length); | ||
933 | } | ||
934 | break; | ||
935 | default: | ||
936 | GNUNET_assert (0); | ||
937 | break; | ||
1204 | } | 938 | } |
1205 | mlen = sizeof (struct GNUNET_EXIT_UdpReplyMessage) + pktlen - sizeof (struct GNUNET_TUN_UdpHeader); | ||
1206 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueue) + mlen); | ||
1207 | tnq->payload = &tnq[1]; | ||
1208 | tnq->len = mlen; | ||
1209 | urm = (struct GNUNET_EXIT_UdpReplyMessage *) &tnq[1]; | ||
1210 | urm->header.size = htons ((uint16_t) mlen); | ||
1211 | urm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY); | ||
1212 | urm->source_port = htons (0); | ||
1213 | urm->destination_port = htons (0); | ||
1214 | GNUNET_memcpy (&urm[1], | ||
1215 | &udp[1], | ||
1216 | pktlen - sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1217 | send_packet_to_cadet_channel (state, tnq); | ||
1218 | } | 939 | } |
1219 | 940 | ||
1220 | 941 | ||
1221 | /** | 942 | /** |
1222 | * @brief Handles a TCP packet received from the helper. | 943 | * Send a TCP packet via the TUN interface. |
1223 | * | 944 | * |
1224 | * @param tcp A pointer to the Packet | 945 | * @param destination_address IP and port to use for the TCP packet's destination |
1225 | * @param pktlen the length of the packet, including its TCP header | 946 | * @param source_address IP and port to use for the TCP packet's source |
1226 | * @param af address family (AFINET or AF_INET6) | 947 | * @param tcp_header header template to use |
1227 | * @param destination_ip destination IP-address of the IP packet (should | 948 | * @param payload payload of the TCP packet |
1228 | * be our local address) | 949 | * @param payload_length number of bytes in @a payload |
1229 | * @param source_ip original source IP-address of the IP packet (should | ||
1230 | * be the original destination address) | ||
1231 | */ | 950 | */ |
1232 | static void | 951 | static void |
1233 | tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, | 952 | send_tcp_packet_via_tun (const struct SocketAddress *destination_address, |
1234 | size_t pktlen, | 953 | const struct SocketAddress *source_address, |
1235 | int af, | 954 | const struct GNUNET_TUN_TcpHeader *tcp_header, |
1236 | const void *destination_ip, | 955 | const void *payload, |
1237 | const void *source_ip) | 956 | size_t payload_length) |
1238 | { | 957 | { |
1239 | struct ChannelState *state; | 958 | size_t len; |
1240 | char buf[pktlen] GNUNET_ALIGN; | ||
1241 | struct GNUNET_TUN_TcpHeader *mtcp; | ||
1242 | struct GNUNET_EXIT_TcpDataMessage *tdm; | ||
1243 | struct ChannelMessageQueue *tnq; | ||
1244 | size_t mlen; | ||
1245 | 959 | ||
960 | GNUNET_STATISTICS_update (stats, | ||
961 | gettext_noop ("# TCP packets sent via TUN"), | ||
962 | 1, | ||
963 | GNUNET_NO); | ||
964 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
965 | "Sending packet with %u bytes TCP payload via TUN\n", | ||
966 | (unsigned int) payload_length); | ||
967 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | ||
968 | switch (source_address->af) | ||
1246 | { | 969 | { |
1247 | char sbuf[INET6_ADDRSTRLEN]; | 970 | case AF_INET: |
1248 | char dbuf[INET6_ADDRSTRLEN]; | 971 | len += sizeof (struct GNUNET_TUN_IPv4Header); |
1249 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 972 | break; |
1250 | "Received TCP packet with %u bytes going from %s:%u to %s:%u\n", | 973 | case AF_INET6: |
1251 | (unsigned int) (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)), | 974 | len += sizeof (struct GNUNET_TUN_IPv6Header); |
1252 | inet_ntop (af, | 975 | break; |
1253 | source_ip, | 976 | default: |
1254 | sbuf, sizeof (sbuf)), | 977 | GNUNET_break (0); |
1255 | (unsigned int) ntohs (tcp->source_port), | 978 | return; |
1256 | inet_ntop (af, | ||
1257 | destination_ip, | ||
1258 | dbuf, sizeof (dbuf)), | ||
1259 | (unsigned int) ntohs (tcp->destination_port)); | ||
1260 | } | 979 | } |
1261 | if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader)) | 980 | len += sizeof (struct GNUNET_TUN_TcpHeader); |
981 | len += payload_length; | ||
982 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1262 | { | 983 | { |
1263 | /* blame kernel */ | ||
1264 | GNUNET_break (0); | 984 | GNUNET_break (0); |
1265 | return; | 985 | return; |
1266 | } | 986 | } |
1267 | state = get_redirect_state (af, | ||
1268 | IPPROTO_TCP, | ||
1269 | source_ip, | ||
1270 | ntohs (tcp->source_port), | ||
1271 | destination_ip, | ||
1272 | ntohs (tcp->destination_port), | ||
1273 | NULL); | ||
1274 | if (NULL == state) | ||
1275 | { | 987 | { |
1276 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 988 | char buf[len] GNUNET_ALIGN; |
1277 | _("TCP Packet dropped, have no matching connection information\n")); | 989 | struct GNUNET_MessageHeader *hdr; |
990 | struct GNUNET_TUN_Layer2PacketHeader *tun; | ||
1278 | 991 | ||
1279 | return; | 992 | hdr = (struct GNUNET_MessageHeader *) buf; |
1280 | } | 993 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1281 | /* mug port numbers and crc to avoid information leakage; | 994 | hdr->size = htons (len); |
1282 | sender will need to lookup the correct values anyway */ | 995 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; |
1283 | GNUNET_memcpy (buf, tcp, pktlen); | 996 | tun->flags = htons (0); |
1284 | mtcp = (struct GNUNET_TUN_TcpHeader *) buf; | 997 | switch (source_address->af) |
1285 | mtcp->source_port = 0; | 998 | { |
1286 | mtcp->destination_port = 0; | 999 | case AF_INET: |
1287 | mtcp->crc = 0; | 1000 | { |
1001 | struct GNUNET_TUN_IPv4Header *ipv4 | ||
1002 | = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | ||
1288 | 1003 | ||
1289 | mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)); | 1004 | tun->proto = htons (ETH_P_IPV4); |
1290 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 1005 | prepare_ipv4_packet (payload, |
1291 | { | 1006 | payload_length, |
1292 | GNUNET_break (0); | 1007 | IPPROTO_TCP, |
1293 | return; | 1008 | tcp_header, |
1294 | } | 1009 | source_address, |
1010 | destination_address, | ||
1011 | ipv4); | ||
1012 | } | ||
1013 | break; | ||
1014 | case AF_INET6: | ||
1015 | { | ||
1016 | struct GNUNET_TUN_IPv6Header *ipv6 | ||
1017 | = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
1295 | 1018 | ||
1296 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueue) + mlen); | 1019 | tun->proto = htons (ETH_P_IPV6); |
1297 | tnq->payload = &tnq[1]; | 1020 | prepare_ipv6_packet (payload, |
1298 | tnq->len = mlen; | 1021 | payload_length, |
1299 | tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1]; | 1022 | IPPROTO_TCP, |
1300 | tdm->header.size = htons ((uint16_t) mlen); | 1023 | tcp_header, |
1301 | tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN); | 1024 | source_address, |
1302 | tdm->reserved = htonl (0); | 1025 | destination_address, |
1303 | GNUNET_memcpy (&tdm->tcp_header, | 1026 | ipv6); |
1304 | buf, | 1027 | } |
1305 | pktlen); | 1028 | break; |
1306 | send_packet_to_cadet_channel (state, tnq); | 1029 | default: |
1030 | GNUNET_assert (0); | ||
1031 | break; | ||
1032 | } | ||
1033 | if (NULL != helper_handle) | ||
1034 | (void) GNUNET_HELPER_send (helper_handle, | ||
1035 | (const struct GNUNET_MessageHeader*) buf, | ||
1036 | GNUNET_YES, | ||
1037 | NULL, | ||
1038 | NULL); | ||
1039 | } | ||
1307 | } | 1040 | } |
1308 | 1041 | ||
1309 | 1042 | ||
1310 | /** | 1043 | /** |
1311 | * Receive packets from the helper-process | 1044 | * Send an ICMP packet via the TUN interface. |
1312 | * | 1045 | * |
1313 | * @param cls unused | 1046 | * @param destination_address IP to use for the ICMP packet's destination |
1314 | * @param client unsued | 1047 | * @param source_address IP to use for the ICMP packet's source |
1315 | * @param message message received from helper | 1048 | * @param icmp_header ICMP header to send |
1049 | * @param payload payload of the ICMP packet (does NOT include ICMP header) | ||
1050 | * @param payload_length number of bytes of data in @a payload | ||
1316 | */ | 1051 | */ |
1317 | static int | 1052 | static void |
1318 | message_token (void *cls GNUNET_UNUSED, | 1053 | send_icmp_packet_via_tun (const struct SocketAddress *destination_address, |
1319 | void *client GNUNET_UNUSED, | 1054 | const struct SocketAddress *source_address, |
1320 | const struct GNUNET_MessageHeader *message) | 1055 | const struct GNUNET_TUN_IcmpHeader *icmp_header, |
1056 | const void *payload, size_t payload_length) | ||
1321 | { | 1057 | { |
1322 | const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun; | 1058 | size_t len; |
1323 | size_t size; | 1059 | struct GNUNET_TUN_IcmpHeader *icmp; |
1324 | 1060 | ||
1325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1326 | "Got %u-byte message of type %u from gnunet-helper-exit\n", | ||
1327 | ntohs (message->size), | ||
1328 | ntohs (message->type)); | ||
1329 | GNUNET_STATISTICS_update (stats, | 1061 | GNUNET_STATISTICS_update (stats, |
1330 | gettext_noop ("# Packets received from TUN"), | 1062 | gettext_noop ("# ICMP packets sent via TUN"), |
1331 | 1, GNUNET_NO); | 1063 | 1, GNUNET_NO); |
1332 | if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) | 1064 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1065 | "Sending packet with %u bytes ICMP payload via TUN\n", | ||
1066 | (unsigned int) payload_length); | ||
1067 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | ||
1068 | switch (destination_address->af) | ||
1333 | { | 1069 | { |
1070 | case AF_INET: | ||
1071 | len += sizeof (struct GNUNET_TUN_IPv4Header); | ||
1072 | break; | ||
1073 | case AF_INET6: | ||
1074 | len += sizeof (struct GNUNET_TUN_IPv6Header); | ||
1075 | break; | ||
1076 | default: | ||
1334 | GNUNET_break (0); | 1077 | GNUNET_break (0); |
1335 | return GNUNET_OK; | 1078 | return; |
1336 | } | 1079 | } |
1337 | size = ntohs (message->size); | 1080 | len += sizeof (struct GNUNET_TUN_IcmpHeader); |
1338 | if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader)) | 1081 | len += payload_length; |
1082 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1339 | { | 1083 | { |
1340 | GNUNET_break (0); | 1084 | GNUNET_break (0); |
1341 | return GNUNET_OK; | 1085 | return; |
1342 | } | 1086 | } |
1343 | GNUNET_STATISTICS_update (stats, | ||
1344 | gettext_noop ("# Bytes received from TUN"), | ||
1345 | size, GNUNET_NO); | ||
1346 | pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1]; | ||
1347 | size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader); | ||
1348 | switch (ntohs (pkt_tun->proto)) | ||
1349 | { | 1087 | { |
1350 | case ETH_P_IPV4: | 1088 | char buf[len] GNUNET_ALIGN; |
1351 | { | 1089 | struct GNUNET_MessageHeader *hdr; |
1352 | const struct GNUNET_TUN_IPv4Header *pkt4; | 1090 | struct GNUNET_TUN_Layer2PacketHeader *tun; |
1353 | |||
1354 | if (size < sizeof (struct GNUNET_TUN_IPv4Header)) | ||
1355 | { | ||
1356 | /* Kernel to blame? */ | ||
1357 | GNUNET_break (0); | ||
1358 | return GNUNET_OK; | ||
1359 | } | ||
1360 | pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1]; | ||
1361 | if (size != ntohs (pkt4->total_length)) | ||
1362 | { | ||
1363 | /* Kernel to blame? */ | ||
1364 | GNUNET_break (0); | ||
1365 | return GNUNET_OK; | ||
1366 | } | ||
1367 | if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header)) | ||
1368 | { | ||
1369 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1370 | _("IPv4 packet options received. Ignored.\n")); | ||
1371 | return GNUNET_OK; | ||
1372 | } | ||
1373 | 1091 | ||
1374 | size -= sizeof (struct GNUNET_TUN_IPv4Header); | 1092 | hdr= (struct GNUNET_MessageHeader *) buf; |
1375 | switch (pkt4->protocol) | 1093 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1376 | { | 1094 | hdr->size = htons (len); |
1377 | case IPPROTO_UDP: | 1095 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; |
1378 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size, | 1096 | tun->flags = htons (0); |
1379 | AF_INET, | 1097 | switch (source_address->af) |
1380 | &pkt4->destination_address, | ||
1381 | &pkt4->source_address); | ||
1382 | break; | ||
1383 | case IPPROTO_TCP: | ||
1384 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size, | ||
1385 | AF_INET, | ||
1386 | &pkt4->destination_address, | ||
1387 | &pkt4->source_address); | ||
1388 | break; | ||
1389 | case IPPROTO_ICMP: | ||
1390 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size, | ||
1391 | AF_INET, | ||
1392 | &pkt4->destination_address, | ||
1393 | &pkt4->source_address); | ||
1394 | break; | ||
1395 | default: | ||
1396 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1397 | _("IPv4 packet with unsupported next header %u received. Ignored.\n"), | ||
1398 | (int) pkt4->protocol); | ||
1399 | return GNUNET_OK; | ||
1400 | } | ||
1401 | } | ||
1402 | break; | ||
1403 | case ETH_P_IPV6: | ||
1404 | { | 1098 | { |
1405 | const struct GNUNET_TUN_IPv6Header *pkt6; | 1099 | case AF_INET: |
1406 | |||
1407 | if (size < sizeof (struct GNUNET_TUN_IPv6Header)) | ||
1408 | { | ||
1409 | /* Kernel to blame? */ | ||
1410 | GNUNET_break (0); | ||
1411 | return GNUNET_OK; | ||
1412 | } | ||
1413 | pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1]; | ||
1414 | if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header)) | ||
1415 | { | 1100 | { |
1416 | /* Kernel to blame? */ | 1101 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; |
1417 | GNUNET_break (0); | 1102 | |
1418 | return GNUNET_OK; | 1103 | tun->proto = htons (ETH_P_IPV4); |
1104 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1105 | IPPROTO_ICMP, | ||
1106 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, | ||
1107 | &source_address->address.ipv4, | ||
1108 | &destination_address->address.ipv4); | ||
1109 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1]; | ||
1419 | } | 1110 | } |
1420 | size -= sizeof (struct GNUNET_TUN_IPv6Header); | 1111 | break; |
1421 | switch (pkt6->next_header) | 1112 | case AF_INET6: |
1422 | { | 1113 | { |
1423 | case IPPROTO_UDP: | 1114 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; |
1424 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size, | 1115 | |
1425 | AF_INET6, | 1116 | tun->proto = htons (ETH_P_IPV6); |
1426 | &pkt6->destination_address, | 1117 | GNUNET_TUN_initialize_ipv6_header (ipv6, |
1427 | &pkt6->source_address); | 1118 | IPPROTO_ICMPV6, |
1428 | break; | 1119 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, |
1429 | case IPPROTO_TCP: | 1120 | &source_address->address.ipv6, |
1430 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size, | 1121 | &destination_address->address.ipv6); |
1431 | AF_INET6, | 1122 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1]; |
1432 | &pkt6->destination_address, | ||
1433 | &pkt6->source_address); | ||
1434 | break; | ||
1435 | case IPPROTO_ICMPV6: | ||
1436 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size, | ||
1437 | AF_INET6, | ||
1438 | &pkt6->destination_address, | ||
1439 | &pkt6->source_address); | ||
1440 | break; | ||
1441 | default: | ||
1442 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1443 | _("IPv6 packet with unsupported next header %d received. Ignored.\n"), | ||
1444 | pkt6->next_header); | ||
1445 | return GNUNET_OK; | ||
1446 | } | 1123 | } |
1124 | break; | ||
1125 | default: | ||
1126 | GNUNET_assert (0); | ||
1127 | break; | ||
1447 | } | 1128 | } |
1448 | break; | 1129 | *icmp = *icmp_header; |
1449 | default: | 1130 | GNUNET_memcpy (&icmp[1], |
1450 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1131 | payload, |
1451 | _("Packet from unknown protocol %u received. Ignored.\n"), | 1132 | payload_length); |
1452 | ntohs (pkt_tun->proto)); | 1133 | GNUNET_TUN_calculate_icmp_checksum (icmp, |
1453 | break; | 1134 | payload, |
1135 | payload_length); | ||
1136 | if (NULL != helper_handle) | ||
1137 | (void) GNUNET_HELPER_send (helper_handle, | ||
1138 | (const struct GNUNET_MessageHeader*) buf, | ||
1139 | GNUNET_YES, | ||
1140 | NULL, NULL); | ||
1454 | } | 1141 | } |
1455 | return GNUNET_OK; | ||
1456 | } | 1142 | } |
1457 | 1143 | ||
1458 | 1144 | ||
@@ -1637,223 +1323,25 @@ setup_state_record (struct ChannelState *state) | |||
1637 | 1323 | ||
1638 | 1324 | ||
1639 | /** | 1325 | /** |
1640 | * Prepare an IPv4 packet for transmission via the TUN interface. | 1326 | * Send a UDP packet via the TUN interface. |
1641 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). | ||
1642 | * For UDP, the UDP header will be fully created, whereas for TCP | ||
1643 | * only the ports and checksum will be filled in. So for TCP, | ||
1644 | * a skeleton TCP header must be part of the provided payload. | ||
1645 | * | ||
1646 | * @param payload payload of the packet (starting with UDP payload or | ||
1647 | * TCP header, depending on protocol) | ||
1648 | * @param payload_length number of bytes in @a payload | ||
1649 | * @param protocol IPPROTO_UDP or IPPROTO_TCP | ||
1650 | * @param tcp_header skeleton of the TCP header, NULL for UDP | ||
1651 | * @param src_address source address to use (IP and port) | ||
1652 | * @param dst_address destination address to use (IP and port) | ||
1653 | * @param pkt4 where to write the assembled packet; must | ||
1654 | * contain enough space for the IP header, UDP/TCP header | ||
1655 | * AND the payload | ||
1656 | */ | ||
1657 | static void | ||
1658 | prepare_ipv4_packet (const void *payload, | ||
1659 | size_t payload_length, | ||
1660 | int protocol, | ||
1661 | const struct GNUNET_TUN_TcpHeader *tcp_header, | ||
1662 | const struct SocketAddress *src_address, | ||
1663 | const struct SocketAddress *dst_address, | ||
1664 | struct GNUNET_TUN_IPv4Header *pkt4) | ||
1665 | { | ||
1666 | size_t len; | ||
1667 | |||
1668 | len = payload_length; | ||
1669 | switch (protocol) | ||
1670 | { | ||
1671 | case IPPROTO_UDP: | ||
1672 | len += sizeof (struct GNUNET_TUN_UdpHeader); | ||
1673 | break; | ||
1674 | case IPPROTO_TCP: | ||
1675 | len += sizeof (struct GNUNET_TUN_TcpHeader); | ||
1676 | GNUNET_assert (NULL != tcp_header); | ||
1677 | break; | ||
1678 | default: | ||
1679 | GNUNET_break (0); | ||
1680 | return; | ||
1681 | } | ||
1682 | if (len + sizeof (struct GNUNET_TUN_IPv4Header) > UINT16_MAX) | ||
1683 | { | ||
1684 | GNUNET_break (0); | ||
1685 | return; | ||
1686 | } | ||
1687 | |||
1688 | GNUNET_TUN_initialize_ipv4_header (pkt4, | ||
1689 | protocol, | ||
1690 | len, | ||
1691 | &src_address->address.ipv4, | ||
1692 | &dst_address->address.ipv4); | ||
1693 | switch (protocol) | ||
1694 | { | ||
1695 | case IPPROTO_UDP: | ||
1696 | { | ||
1697 | struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1]; | ||
1698 | |||
1699 | pkt4_udp->source_port = htons (src_address->port); | ||
1700 | pkt4_udp->destination_port = htons (dst_address->port); | ||
1701 | pkt4_udp->len = htons ((uint16_t) payload_length); | ||
1702 | GNUNET_TUN_calculate_udp4_checksum (pkt4, | ||
1703 | pkt4_udp, | ||
1704 | payload, | ||
1705 | payload_length); | ||
1706 | GNUNET_memcpy (&pkt4_udp[1], | ||
1707 | payload, | ||
1708 | payload_length); | ||
1709 | } | ||
1710 | break; | ||
1711 | case IPPROTO_TCP: | ||
1712 | { | ||
1713 | struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1]; | ||
1714 | |||
1715 | *pkt4_tcp = *tcp_header; | ||
1716 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1717 | "Sending TCP packet from port %u to port %u\n", | ||
1718 | src_address->port, | ||
1719 | dst_address->port); | ||
1720 | pkt4_tcp->source_port = htons (src_address->port); | ||
1721 | pkt4_tcp->destination_port = htons (dst_address->port); | ||
1722 | GNUNET_TUN_calculate_tcp4_checksum (pkt4, | ||
1723 | pkt4_tcp, | ||
1724 | payload, | ||
1725 | payload_length); | ||
1726 | GNUNET_memcpy (&pkt4_tcp[1], | ||
1727 | payload, | ||
1728 | payload_length); | ||
1729 | } | ||
1730 | break; | ||
1731 | default: | ||
1732 | GNUNET_assert (0); | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | |||
1737 | /** | ||
1738 | * Prepare an IPv6 packet for transmission via the TUN interface. | ||
1739 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). | ||
1740 | * For UDP, the UDP header will be fully created, whereas for TCP | ||
1741 | * only the ports and checksum will be filled in. So for TCP, | ||
1742 | * a skeleton TCP header must be part of the provided payload. | ||
1743 | * | ||
1744 | * @param payload payload of the packet (starting with UDP payload or | ||
1745 | * TCP header, depending on protocol) | ||
1746 | * @param payload_length number of bytes in @a payload | ||
1747 | * @param protocol IPPROTO_UDP or IPPROTO_TCP | ||
1748 | * @param tcp_header skeleton TCP header data to send, NULL for UDP | ||
1749 | * @param src_address source address to use (IP and port) | ||
1750 | * @param dst_address destination address to use (IP and port) | ||
1751 | * @param pkt6 where to write the assembled packet; must | ||
1752 | * contain enough space for the IP header, UDP/TCP header | ||
1753 | * AND the payload | ||
1754 | */ | ||
1755 | static void | ||
1756 | prepare_ipv6_packet (const void *payload, | ||
1757 | size_t payload_length, | ||
1758 | int protocol, | ||
1759 | const struct GNUNET_TUN_TcpHeader *tcp_header, | ||
1760 | const struct SocketAddress *src_address, | ||
1761 | const struct SocketAddress *dst_address, | ||
1762 | struct GNUNET_TUN_IPv6Header *pkt6) | ||
1763 | { | ||
1764 | size_t len; | ||
1765 | |||
1766 | len = payload_length; | ||
1767 | switch (protocol) | ||
1768 | { | ||
1769 | case IPPROTO_UDP: | ||
1770 | len += sizeof (struct GNUNET_TUN_UdpHeader); | ||
1771 | break; | ||
1772 | case IPPROTO_TCP: | ||
1773 | len += sizeof (struct GNUNET_TUN_TcpHeader); | ||
1774 | break; | ||
1775 | default: | ||
1776 | GNUNET_break (0); | ||
1777 | return; | ||
1778 | } | ||
1779 | if (len > UINT16_MAX) | ||
1780 | { | ||
1781 | GNUNET_break (0); | ||
1782 | return; | ||
1783 | } | ||
1784 | |||
1785 | GNUNET_TUN_initialize_ipv6_header (pkt6, | ||
1786 | protocol, | ||
1787 | len, | ||
1788 | &src_address->address.ipv6, | ||
1789 | &dst_address->address.ipv6); | ||
1790 | |||
1791 | switch (protocol) | ||
1792 | { | ||
1793 | case IPPROTO_UDP: | ||
1794 | { | ||
1795 | struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1]; | ||
1796 | |||
1797 | pkt6_udp->source_port = htons (src_address->port); | ||
1798 | pkt6_udp->destination_port = htons (dst_address->port); | ||
1799 | pkt6_udp->len = htons ((uint16_t) payload_length); | ||
1800 | GNUNET_TUN_calculate_udp6_checksum (pkt6, | ||
1801 | pkt6_udp, | ||
1802 | payload, | ||
1803 | payload_length); | ||
1804 | GNUNET_memcpy (&pkt6_udp[1], | ||
1805 | payload, | ||
1806 | payload_length); | ||
1807 | } | ||
1808 | break; | ||
1809 | case IPPROTO_TCP: | ||
1810 | { | ||
1811 | struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt6[1]; | ||
1812 | |||
1813 | /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */ | ||
1814 | *pkt6_tcp = *tcp_header; | ||
1815 | pkt6_tcp->source_port = htons (src_address->port); | ||
1816 | pkt6_tcp->destination_port = htons (dst_address->port); | ||
1817 | GNUNET_TUN_calculate_tcp6_checksum (pkt6, | ||
1818 | pkt6_tcp, | ||
1819 | payload, | ||
1820 | payload_length); | ||
1821 | GNUNET_memcpy (&pkt6_tcp[1], | ||
1822 | payload, | ||
1823 | payload_length); | ||
1824 | } | ||
1825 | break; | ||
1826 | default: | ||
1827 | GNUNET_assert (0); | ||
1828 | break; | ||
1829 | } | ||
1830 | } | ||
1831 | |||
1832 | |||
1833 | /** | ||
1834 | * Send a TCP packet via the TUN interface. | ||
1835 | * | 1327 | * |
1836 | * @param destination_address IP and port to use for the TCP packet's destination | 1328 | * @param destination_address IP and port to use for the UDP packet's destination |
1837 | * @param source_address IP and port to use for the TCP packet's source | 1329 | * @param source_address IP and port to use for the UDP packet's source |
1838 | * @param tcp_header header template to use | 1330 | * @param payload payload of the UDP packet (does NOT include UDP header) |
1839 | * @param payload payload of the TCP packet | 1331 | * @param payload_length number of bytes of data in @a payload |
1840 | * @param payload_length number of bytes in @a payload | ||
1841 | */ | 1332 | */ |
1842 | static void | 1333 | static void |
1843 | send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | 1334 | send_udp_packet_via_tun (const struct SocketAddress *destination_address, |
1844 | const struct SocketAddress *source_address, | 1335 | const struct SocketAddress *source_address, |
1845 | const struct GNUNET_TUN_TcpHeader *tcp_header, | 1336 | const void *payload, size_t payload_length) |
1846 | const void *payload, | ||
1847 | size_t payload_length) | ||
1848 | { | 1337 | { |
1849 | size_t len; | 1338 | size_t len; |
1850 | 1339 | ||
1851 | GNUNET_STATISTICS_update (stats, | 1340 | GNUNET_STATISTICS_update (stats, |
1852 | gettext_noop ("# TCP packets sent via TUN"), | 1341 | gettext_noop ("# UDP packets sent via TUN"), |
1853 | 1, | 1342 | 1, GNUNET_NO); |
1854 | GNUNET_NO); | ||
1855 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1343 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1856 | "Sending packet with %u bytes TCP payload via TUN\n", | 1344 | "Sending packet with %u bytes UDP payload via TUN\n", |
1857 | (unsigned int) payload_length); | 1345 | (unsigned int) payload_length); |
1858 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | 1346 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); |
1859 | switch (source_address->af) | 1347 | switch (source_address->af) |
@@ -1868,7 +1356,7 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1868 | GNUNET_break (0); | 1356 | GNUNET_break (0); |
1869 | return; | 1357 | return; |
1870 | } | 1358 | } |
1871 | len += sizeof (struct GNUNET_TUN_TcpHeader); | 1359 | len += sizeof (struct GNUNET_TUN_UdpHeader); |
1872 | len += payload_length; | 1360 | len += payload_length; |
1873 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 1361 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
1874 | { | 1362 | { |
@@ -1880,7 +1368,7 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1880 | struct GNUNET_MessageHeader *hdr; | 1368 | struct GNUNET_MessageHeader *hdr; |
1881 | struct GNUNET_TUN_Layer2PacketHeader *tun; | 1369 | struct GNUNET_TUN_Layer2PacketHeader *tun; |
1882 | 1370 | ||
1883 | hdr = (struct GNUNET_MessageHeader *) buf; | 1371 | hdr= (struct GNUNET_MessageHeader *) buf; |
1884 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | 1372 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1885 | hdr->size = htons (len); | 1373 | hdr->size = htons (len); |
1886 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; | 1374 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; |
@@ -1889,14 +1377,13 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1889 | { | 1377 | { |
1890 | case AF_INET: | 1378 | case AF_INET: |
1891 | { | 1379 | { |
1892 | struct GNUNET_TUN_IPv4Header *ipv4 | 1380 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; |
1893 | = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | ||
1894 | 1381 | ||
1895 | tun->proto = htons (ETH_P_IPV4); | 1382 | tun->proto = htons (ETH_P_IPV4); |
1896 | prepare_ipv4_packet (payload, | 1383 | prepare_ipv4_packet (payload, |
1897 | payload_length, | 1384 | payload_length, |
1898 | IPPROTO_TCP, | 1385 | IPPROTO_UDP, |
1899 | tcp_header, | 1386 | NULL, |
1900 | source_address, | 1387 | source_address, |
1901 | destination_address, | 1388 | destination_address, |
1902 | ipv4); | 1389 | ipv4); |
@@ -1904,14 +1391,13 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1904 | break; | 1391 | break; |
1905 | case AF_INET6: | 1392 | case AF_INET6: |
1906 | { | 1393 | { |
1907 | struct GNUNET_TUN_IPv6Header *ipv6 | 1394 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; |
1908 | = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
1909 | 1395 | ||
1910 | tun->proto = htons (ETH_P_IPV6); | 1396 | tun->proto = htons (ETH_P_IPV6); |
1911 | prepare_ipv6_packet (payload, | 1397 | prepare_ipv6_packet (payload, |
1912 | payload_length, | 1398 | payload_length, |
1913 | IPPROTO_TCP, | 1399 | IPPROTO_UDP, |
1914 | tcp_header, | 1400 | NULL, |
1915 | source_address, | 1401 | source_address, |
1916 | destination_address, | 1402 | destination_address, |
1917 | ipv6); | 1403 | ipv6); |
@@ -1925,48 +1411,202 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1925 | (void) GNUNET_HELPER_send (helper_handle, | 1411 | (void) GNUNET_HELPER_send (helper_handle, |
1926 | (const struct GNUNET_MessageHeader*) buf, | 1412 | (const struct GNUNET_MessageHeader*) buf, |
1927 | GNUNET_YES, | 1413 | GNUNET_YES, |
1928 | NULL, | 1414 | NULL, NULL); |
1929 | NULL); | ||
1930 | } | 1415 | } |
1931 | } | 1416 | } |
1932 | 1417 | ||
1933 | 1418 | ||
1934 | /** | 1419 | /** |
1935 | * Process a request via cadet to send a request to a TCP service | 1420 | * Check a request to forward UDP data to the Internet via this peer. |
1936 | * offered by this system. | ||
1937 | * | 1421 | * |
1938 | * @param cls closure, NULL | 1422 | * @param cls our `struct ChannelState *` |
1939 | * @param channel connection to the other end | 1423 | * @param msg the actual message |
1940 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
1941 | * @param message the actual message | ||
1942 | * @return #GNUNET_OK to keep the connection open, | 1424 | * @return #GNUNET_OK to keep the connection open, |
1943 | * #GNUNET_SYSERR to close it (signal serious error) | 1425 | * #GNUNET_SYSERR to close it (signal serious error) |
1944 | */ | 1426 | */ |
1945 | static int | 1427 | static int |
1946 | receive_tcp_service (void *cls, | 1428 | check_udp_remote (void *cls, |
1947 | struct GNUNET_CADET_Channel *channel, | 1429 | const struct GNUNET_EXIT_UdpInternetMessage *msg) |
1948 | void **channel_ctx, | ||
1949 | const struct GNUNET_MessageHeader *message) | ||
1950 | { | 1430 | { |
1951 | struct ChannelState *state = *channel_ctx; | 1431 | struct ChannelState *state = cls; |
1952 | const struct GNUNET_EXIT_TcpServiceStartMessage *start; | ||
1953 | uint16_t pkt_len = ntohs (message->size); | ||
1954 | 1432 | ||
1955 | if (NULL == state) | 1433 | if (GNUNET_YES == state->is_dns) |
1956 | { | 1434 | { |
1957 | GNUNET_break_op (0); | 1435 | GNUNET_break_op (0); |
1958 | return GNUNET_SYSERR; | 1436 | return GNUNET_SYSERR; |
1959 | } | 1437 | } |
1960 | if (GNUNET_YES == state->is_dns) | 1438 | return GNUNET_OK; |
1439 | } | ||
1440 | |||
1441 | |||
1442 | /** | ||
1443 | * Process a request to forward UDP data to the Internet via this peer. | ||
1444 | * | ||
1445 | * @param cls our `struct ChannelState *` | ||
1446 | * @param msg the actual message | ||
1447 | */ | ||
1448 | static void | ||
1449 | handle_udp_remote (void *cls, | ||
1450 | const struct GNUNET_EXIT_UdpInternetMessage *msg) | ||
1451 | { | ||
1452 | struct ChannelState *state = cls; | ||
1453 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_UdpInternetMessage); | ||
1454 | const struct in_addr *v4; | ||
1455 | const struct in6_addr *v6; | ||
1456 | const void *payload; | ||
1457 | int af; | ||
1458 | |||
1459 | if (GNUNET_SYSERR == state->is_dns) | ||
1460 | { | ||
1461 | /* channel is UDP/TCP from now on */ | ||
1462 | state->is_dns = GNUNET_NO; | ||
1463 | } | ||
1464 | GNUNET_STATISTICS_update (stats, | ||
1465 | gettext_noop ("# Bytes received from CADET"), | ||
1466 | pkt_len, GNUNET_NO); | ||
1467 | GNUNET_STATISTICS_update (stats, | ||
1468 | gettext_noop ("# UDP IP-exit requests received via cadet"), | ||
1469 | 1, GNUNET_NO); | ||
1470 | af = (int) ntohl (msg->af); | ||
1471 | state->specifics.tcp_udp.ri.remote_address.af = af; | ||
1472 | switch (af) | ||
1961 | { | 1473 | { |
1474 | case AF_INET: | ||
1475 | if (pkt_len < sizeof (struct in_addr)) | ||
1476 | { | ||
1477 | GNUNET_break_op (0); | ||
1478 | return; | ||
1479 | } | ||
1480 | if (! ipv4_exit) | ||
1481 | { | ||
1482 | GNUNET_break_op (0); | ||
1483 | return; | ||
1484 | } | ||
1485 | v4 = (const struct in_addr*) &msg[1]; | ||
1486 | payload = &v4[1]; | ||
1487 | pkt_len -= sizeof (struct in_addr); | ||
1488 | state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4; | ||
1489 | break; | ||
1490 | case AF_INET6: | ||
1491 | if (pkt_len < sizeof (struct in6_addr)) | ||
1492 | { | ||
1493 | GNUNET_break_op (0); | ||
1494 | return; | ||
1495 | } | ||
1496 | if (! ipv6_exit) | ||
1497 | { | ||
1498 | GNUNET_break_op (0); | ||
1499 | return; | ||
1500 | } | ||
1501 | v6 = (const struct in6_addr*) &msg[1]; | ||
1502 | payload = &v6[1]; | ||
1503 | pkt_len -= sizeof (struct in6_addr); | ||
1504 | state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6; | ||
1505 | break; | ||
1506 | default: | ||
1962 | GNUNET_break_op (0); | 1507 | GNUNET_break_op (0); |
1963 | return GNUNET_SYSERR; | 1508 | return; |
1964 | } | 1509 | } |
1510 | { | ||
1511 | char buf[INET6_ADDRSTRLEN]; | ||
1512 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1513 | "Received data from %s for forwarding to UDP %s:%u\n", | ||
1514 | GNUNET_i2s (&state->peer), | ||
1515 | inet_ntop (af, | ||
1516 | &state->specifics.tcp_udp.ri.remote_address.address, | ||
1517 | buf, sizeof (buf)), | ||
1518 | (unsigned int) ntohs (msg->destination_port)); | ||
1519 | } | ||
1520 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP; | ||
1521 | state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port; | ||
1522 | if (NULL == state->specifics.tcp_udp.heap_node) | ||
1523 | setup_state_record (state); | ||
1524 | if (0 != ntohs (msg->source_port)) | ||
1525 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | ||
1526 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | ||
1527 | &state->specifics.tcp_udp.ri.local_address, | ||
1528 | payload, | ||
1529 | pkt_len); | ||
1530 | GNUNET_CADET_receive_done (state->channel); | ||
1531 | } | ||
1532 | |||
1533 | |||
1534 | /** | ||
1535 | * Check a request via cadet to send a request to a UDP service | ||
1536 | * offered by this system. | ||
1537 | * | ||
1538 | * @param cls our `struct ChannelState *` | ||
1539 | * @param msg the actual message | ||
1540 | * @return #GNUNET_OK to keep the connection open, | ||
1541 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1542 | */ | ||
1543 | static int | ||
1544 | check_udp_service (void *cls, | ||
1545 | const struct GNUNET_EXIT_UdpServiceMessage *msg) | ||
1546 | { | ||
1547 | struct ChannelState *state = cls; | ||
1548 | |||
1965 | if (NULL == state->specifics.tcp_udp.serv) | 1549 | if (NULL == state->specifics.tcp_udp.serv) |
1966 | { | 1550 | { |
1967 | GNUNET_break_op (0); | 1551 | GNUNET_break_op (0); |
1968 | return GNUNET_SYSERR; | 1552 | return GNUNET_SYSERR; |
1969 | } | 1553 | } |
1554 | return GNUNET_OK; | ||
1555 | } | ||
1556 | |||
1557 | |||
1558 | /** | ||
1559 | * Process a request via cadet to send a request to a UDP service | ||
1560 | * offered by this system. | ||
1561 | * | ||
1562 | * @param cls our `struct ChannelState *` | ||
1563 | * @param msg the actual message | ||
1564 | */ | ||
1565 | static void | ||
1566 | handle_udp_service (void *cls, | ||
1567 | const struct GNUNET_EXIT_UdpServiceMessage *msg) | ||
1568 | { | ||
1569 | struct ChannelState *state = cls; | ||
1570 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_UdpServiceMessage); | ||
1571 | |||
1572 | GNUNET_STATISTICS_update (stats, | ||
1573 | gettext_noop ("# Bytes received from CADET"), | ||
1574 | pkt_len, GNUNET_NO); | ||
1575 | GNUNET_STATISTICS_update (stats, | ||
1576 | gettext_noop ("# UDP service requests received via cadet"), | ||
1577 | 1, GNUNET_NO); | ||
1578 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1579 | "Received data from %s for forwarding to UDP service %s on port %u\n", | ||
1580 | GNUNET_i2s (&state->peer), | ||
1581 | GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor), | ||
1582 | (unsigned int) ntohs (msg->destination_port)); | ||
1583 | setup_state_record (state); | ||
1584 | if (0 != ntohs (msg->source_port)) | ||
1585 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | ||
1586 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | ||
1587 | &state->specifics.tcp_udp.ri.local_address, | ||
1588 | &msg[1], | ||
1589 | pkt_len); | ||
1590 | GNUNET_CADET_receive_done (state->channel); | ||
1591 | } | ||
1592 | |||
1593 | |||
1594 | /** | ||
1595 | * Process a request via cadet to send a request to a TCP service | ||
1596 | * offered by this system. | ||
1597 | * | ||
1598 | * @param cls our `struct ChannelState *` | ||
1599 | * @param start the actual message | ||
1600 | * @return #GNUNET_OK to keep the connection open, | ||
1601 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1602 | */ | ||
1603 | static void | ||
1604 | handle_tcp_service (void *cls, | ||
1605 | const struct GNUNET_EXIT_TcpServiceStartMessage *start) | ||
1606 | { | ||
1607 | struct ChannelState *state = cls; | ||
1608 | uint16_t pkt_len = ntohs (start->header.size) - sizeof (struct GNUNET_EXIT_TcpServiceStartMessage); | ||
1609 | |||
1970 | if (GNUNET_SYSERR == state->is_dns) | 1610 | if (GNUNET_SYSERR == state->is_dns) |
1971 | { | 1611 | { |
1972 | /* channel is UDP/TCP from now on */ | 1612 | /* channel is UDP/TCP from now on */ |
@@ -1980,24 +1620,6 @@ receive_tcp_service (void *cls, | |||
1980 | gettext_noop ("# Bytes received from CADET"), | 1620 | gettext_noop ("# Bytes received from CADET"), |
1981 | pkt_len, | 1621 | pkt_len, |
1982 | GNUNET_NO); | 1622 | GNUNET_NO); |
1983 | /* check that we got at least a valid header */ | ||
1984 | if (pkt_len < sizeof (struct GNUNET_EXIT_TcpServiceStartMessage)) | ||
1985 | { | ||
1986 | GNUNET_break_op (0); | ||
1987 | return GNUNET_SYSERR; | ||
1988 | } | ||
1989 | start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message; | ||
1990 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage); | ||
1991 | if (NULL != state->specifics.tcp_udp.heap_node) | ||
1992 | { | ||
1993 | GNUNET_break_op (0); | ||
1994 | return GNUNET_SYSERR; | ||
1995 | } | ||
1996 | if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
1997 | { | ||
1998 | GNUNET_break_op (0); | ||
1999 | return GNUNET_SYSERR; | ||
2000 | } | ||
2001 | GNUNET_break_op (ntohl (start->reserved) == 0); | 1623 | GNUNET_break_op (ntohl (start->reserved) == 0); |
2002 | /* setup fresh connection */ | 1624 | /* setup fresh connection */ |
2003 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1625 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2011,34 +1633,23 @@ receive_tcp_service (void *cls, | |||
2011 | &start->tcp_header, | 1633 | &start->tcp_header, |
2012 | &start[1], | 1634 | &start[1], |
2013 | pkt_len); | 1635 | pkt_len); |
2014 | GNUNET_CADET_receive_done (channel); | 1636 | GNUNET_CADET_receive_done (state->channel); |
2015 | return GNUNET_YES; | ||
2016 | } | 1637 | } |
2017 | 1638 | ||
2018 | 1639 | ||
2019 | /** | 1640 | /** |
2020 | * Process a request to forward TCP data to the Internet via this peer. | 1641 | * Check a request to forward TCP data to the Internet via this peer. |
2021 | * | 1642 | * |
2022 | * @param cls closure, NULL | 1643 | * @param cls our `struct ChannelState *` |
2023 | * @param channel connection to the other end | 1644 | * @param start the actual message |
2024 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
2025 | * @param message the actual message | ||
2026 | * @return #GNUNET_OK to keep the connection open, | 1645 | * @return #GNUNET_OK to keep the connection open, |
2027 | * #GNUNET_SYSERR to close it (signal serious error) | 1646 | * #GNUNET_SYSERR to close it (signal serious error) |
2028 | */ | 1647 | */ |
2029 | static int | 1648 | static int |
2030 | receive_tcp_remote (void *cls GNUNET_UNUSED, | 1649 | check_tcp_remote (void *cls, |
2031 | struct GNUNET_CADET_Channel *channel, | 1650 | const struct GNUNET_EXIT_TcpInternetStartMessage *start) |
2032 | void **channel_ctx GNUNET_UNUSED, | ||
2033 | const struct GNUNET_MessageHeader *message) | ||
2034 | { | 1651 | { |
2035 | struct ChannelState *state = *channel_ctx; | 1652 | struct ChannelState *state = cls; |
2036 | const struct GNUNET_EXIT_TcpInternetStartMessage *start; | ||
2037 | uint16_t pkt_len = ntohs (message->size); | ||
2038 | const struct in_addr *v4; | ||
2039 | const struct in6_addr *v6; | ||
2040 | const void *payload; | ||
2041 | int af; | ||
2042 | 1653 | ||
2043 | if (NULL == state) | 1654 | if (NULL == state) |
2044 | { | 1655 | { |
@@ -2050,24 +1661,6 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2050 | GNUNET_break_op (0); | 1661 | GNUNET_break_op (0); |
2051 | return GNUNET_SYSERR; | 1662 | return GNUNET_SYSERR; |
2052 | } | 1663 | } |
2053 | if (GNUNET_SYSERR == state->is_dns) | ||
2054 | { | ||
2055 | /* channel is UDP/TCP from now on */ | ||
2056 | state->is_dns = GNUNET_NO; | ||
2057 | } | ||
2058 | GNUNET_STATISTICS_update (stats, | ||
2059 | gettext_noop ("# Bytes received from CADET"), | ||
2060 | pkt_len, GNUNET_NO); | ||
2061 | GNUNET_STATISTICS_update (stats, | ||
2062 | gettext_noop ("# TCP IP-exit creation requests received via cadet"), | ||
2063 | 1, GNUNET_NO); | ||
2064 | if (pkt_len < sizeof (struct GNUNET_EXIT_TcpInternetStartMessage)) | ||
2065 | { | ||
2066 | GNUNET_break_op (0); | ||
2067 | return GNUNET_SYSERR; | ||
2068 | } | ||
2069 | start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message; | ||
2070 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage); | ||
2071 | if ( (NULL != state->specifics.tcp_udp.serv) || | 1664 | if ( (NULL != state->specifics.tcp_udp.serv) || |
2072 | (NULL != state->specifics.tcp_udp.heap_node) ) | 1665 | (NULL != state->specifics.tcp_udp.heap_node) ) |
2073 | { | 1666 | { |
@@ -2079,6 +1672,38 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2079 | GNUNET_break_op (0); | 1672 | GNUNET_break_op (0); |
2080 | return GNUNET_SYSERR; | 1673 | return GNUNET_SYSERR; |
2081 | } | 1674 | } |
1675 | return GNUNET_OK; | ||
1676 | } | ||
1677 | |||
1678 | |||
1679 | /** | ||
1680 | * Process a request to forward TCP data to the Internet via this peer. | ||
1681 | * | ||
1682 | * @param cls our `struct ChannelState *` | ||
1683 | * @param start the actual message | ||
1684 | */ | ||
1685 | static void | ||
1686 | handle_tcp_remote (void *cls, | ||
1687 | const struct GNUNET_EXIT_TcpInternetStartMessage *start) | ||
1688 | { | ||
1689 | struct ChannelState *state = cls; | ||
1690 | uint16_t pkt_len = ntohs (start->header.size) - sizeof (struct GNUNET_EXIT_TcpInternetStartMessage); | ||
1691 | const struct in_addr *v4; | ||
1692 | const struct in6_addr *v6; | ||
1693 | const void *payload; | ||
1694 | int af; | ||
1695 | |||
1696 | if (GNUNET_SYSERR == state->is_dns) | ||
1697 | { | ||
1698 | /* channel is UDP/TCP from now on */ | ||
1699 | state->is_dns = GNUNET_NO; | ||
1700 | } | ||
1701 | GNUNET_STATISTICS_update (stats, | ||
1702 | gettext_noop ("# Bytes received from CADET"), | ||
1703 | pkt_len, GNUNET_NO); | ||
1704 | GNUNET_STATISTICS_update (stats, | ||
1705 | gettext_noop ("# TCP IP-exit creation requests received via cadet"), | ||
1706 | 1, GNUNET_NO); | ||
2082 | af = (int) ntohl (start->af); | 1707 | af = (int) ntohl (start->af); |
2083 | state->specifics.tcp_udp.ri.remote_address.af = af; | 1708 | state->specifics.tcp_udp.ri.remote_address.af = af; |
2084 | switch (af) | 1709 | switch (af) |
@@ -2087,12 +1712,12 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2087 | if (pkt_len < sizeof (struct in_addr)) | 1712 | if (pkt_len < sizeof (struct in_addr)) |
2088 | { | 1713 | { |
2089 | GNUNET_break_op (0); | 1714 | GNUNET_break_op (0); |
2090 | return GNUNET_SYSERR; | 1715 | return; |
2091 | } | 1716 | } |
2092 | if (! ipv4_exit) | 1717 | if (! ipv4_exit) |
2093 | { | 1718 | { |
2094 | GNUNET_break_op (0); | 1719 | GNUNET_break_op (0); |
2095 | return GNUNET_SYSERR; | 1720 | return; |
2096 | } | 1721 | } |
2097 | v4 = (const struct in_addr*) &start[1]; | 1722 | v4 = (const struct in_addr*) &start[1]; |
2098 | payload = &v4[1]; | 1723 | payload = &v4[1]; |
@@ -2103,12 +1728,12 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2103 | if (pkt_len < sizeof (struct in6_addr)) | 1728 | if (pkt_len < sizeof (struct in6_addr)) |
2104 | { | 1729 | { |
2105 | GNUNET_break_op (0); | 1730 | GNUNET_break_op (0); |
2106 | return GNUNET_SYSERR; | 1731 | return; |
2107 | } | 1732 | } |
2108 | if (! ipv6_exit) | 1733 | if (! ipv6_exit) |
2109 | { | 1734 | { |
2110 | GNUNET_break_op (0); | 1735 | GNUNET_break_op (0); |
2111 | return GNUNET_SYSERR; | 1736 | return; |
2112 | } | 1737 | } |
2113 | v6 = (const struct in6_addr*) &start[1]; | 1738 | v6 = (const struct in6_addr*) &start[1]; |
2114 | payload = &v6[1]; | 1739 | payload = &v6[1]; |
@@ -2117,7 +1742,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2117 | break; | 1742 | break; |
2118 | default: | 1743 | default: |
2119 | GNUNET_break_op (0); | 1744 | GNUNET_break_op (0); |
2120 | return GNUNET_SYSERR; | 1745 | return; |
2121 | } | 1746 | } |
2122 | { | 1747 | { |
2123 | char buf[INET6_ADDRSTRLEN]; | 1748 | char buf[INET6_ADDRSTRLEN]; |
@@ -2135,46 +1760,27 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2135 | send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 1760 | send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2136 | &state->specifics.tcp_udp.ri.local_address, | 1761 | &state->specifics.tcp_udp.ri.local_address, |
2137 | &start->tcp_header, | 1762 | &start->tcp_header, |
2138 | payload, pkt_len); | 1763 | payload, |
2139 | GNUNET_CADET_receive_done (channel); | 1764 | pkt_len); |
2140 | return GNUNET_YES; | 1765 | GNUNET_CADET_receive_done (state->channel); |
2141 | } | 1766 | } |
2142 | 1767 | ||
2143 | 1768 | ||
2144 | /** | 1769 | /** |
2145 | * Process a request to forward TCP data on an established | 1770 | * Check a request to forward TCP data on an established |
2146 | * connection via this peer. | 1771 | * connection via this peer. |
2147 | * | 1772 | * |
2148 | * @param cls closure, NULL | 1773 | * @param cls our `struct ChannelState *` |
2149 | * @param channel connection to the other end | ||
2150 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
2151 | * @param message the actual message | 1774 | * @param message the actual message |
2152 | * @return #GNUNET_OK to keep the connection open, | 1775 | * @return #GNUNET_OK to keep the connection open, |
2153 | * #GNUNET_SYSERR to close it (signal serious error) | 1776 | * #GNUNET_SYSERR to close it (signal serious error) |
2154 | */ | 1777 | */ |
2155 | static int | 1778 | static int |
2156 | receive_tcp_data (void *cls GNUNET_UNUSED, | 1779 | check_tcp_data (void *cls, |
2157 | struct GNUNET_CADET_Channel *channel, | 1780 | const struct GNUNET_EXIT_TcpDataMessage *data) |
2158 | void **channel_ctx GNUNET_UNUSED, | ||
2159 | const struct GNUNET_MessageHeader *message) | ||
2160 | { | 1781 | { |
2161 | struct ChannelState *state = *channel_ctx; | 1782 | struct ChannelState *state = cls; |
2162 | const struct GNUNET_EXIT_TcpDataMessage *data; | ||
2163 | uint16_t pkt_len = ntohs (message->size); | ||
2164 | 1783 | ||
2165 | GNUNET_STATISTICS_update (stats, | ||
2166 | gettext_noop ("# Bytes received from CADET"), | ||
2167 | pkt_len, GNUNET_NO); | ||
2168 | GNUNET_STATISTICS_update (stats, | ||
2169 | gettext_noop ("# TCP data requests received via cadet"), | ||
2170 | 1, GNUNET_NO); | ||
2171 | if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage)) | ||
2172 | { | ||
2173 | GNUNET_break_op (0); | ||
2174 | return GNUNET_SYSERR; | ||
2175 | } | ||
2176 | data = (const struct GNUNET_EXIT_TcpDataMessage*) message; | ||
2177 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
2178 | if ( (NULL == state) || | 1784 | if ( (NULL == state) || |
2179 | (NULL == state->specifics.tcp_udp.heap_node) ) | 1785 | (NULL == state->specifics.tcp_udp.heap_node) ) |
2180 | { | 1786 | { |
@@ -2195,6 +1801,30 @@ receive_tcp_data (void *cls GNUNET_UNUSED, | |||
2195 | GNUNET_break_op (0); | 1801 | GNUNET_break_op (0); |
2196 | return GNUNET_SYSERR; | 1802 | return GNUNET_SYSERR; |
2197 | } | 1803 | } |
1804 | return GNUNET_OK; | ||
1805 | } | ||
1806 | |||
1807 | |||
1808 | /** | ||
1809 | * Process a request to forward TCP data on an established | ||
1810 | * connection via this peer. | ||
1811 | * | ||
1812 | * @param cls our `struct ChannelState *` | ||
1813 | * @param message the actual message | ||
1814 | */ | ||
1815 | static void | ||
1816 | handle_tcp_data (void *cls, | ||
1817 | const struct GNUNET_EXIT_TcpDataMessage *data) | ||
1818 | { | ||
1819 | struct ChannelState *state = cls; | ||
1820 | uint16_t pkt_len = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
1821 | |||
1822 | GNUNET_STATISTICS_update (stats, | ||
1823 | gettext_noop ("# Bytes received from CADET"), | ||
1824 | pkt_len, GNUNET_NO); | ||
1825 | GNUNET_STATISTICS_update (stats, | ||
1826 | gettext_noop ("# TCP data requests received via cadet"), | ||
1827 | 1, GNUNET_NO); | ||
2198 | if (GNUNET_SYSERR == state->is_dns) | 1828 | if (GNUNET_SYSERR == state->is_dns) |
2199 | { | 1829 | { |
2200 | /* channel is UDP/TCP from now on */ | 1830 | /* channel is UDP/TCP from now on */ |
@@ -2218,110 +1848,7 @@ receive_tcp_data (void *cls GNUNET_UNUSED, | |||
2218 | &state->specifics.tcp_udp.ri.local_address, | 1848 | &state->specifics.tcp_udp.ri.local_address, |
2219 | &data->tcp_header, | 1849 | &data->tcp_header, |
2220 | &data[1], pkt_len); | 1850 | &data[1], pkt_len); |
2221 | GNUNET_CADET_receive_done (channel); | 1851 | GNUNET_CADET_receive_done (state->channel); |
2222 | return GNUNET_YES; | ||
2223 | } | ||
2224 | |||
2225 | |||
2226 | /** | ||
2227 | * Send an ICMP packet via the TUN interface. | ||
2228 | * | ||
2229 | * @param destination_address IP to use for the ICMP packet's destination | ||
2230 | * @param source_address IP to use for the ICMP packet's source | ||
2231 | * @param icmp_header ICMP header to send | ||
2232 | * @param payload payload of the ICMP packet (does NOT include ICMP header) | ||
2233 | * @param payload_length number of bytes of data in @a payload | ||
2234 | */ | ||
2235 | static void | ||
2236 | send_icmp_packet_via_tun (const struct SocketAddress *destination_address, | ||
2237 | const struct SocketAddress *source_address, | ||
2238 | const struct GNUNET_TUN_IcmpHeader *icmp_header, | ||
2239 | const void *payload, size_t payload_length) | ||
2240 | { | ||
2241 | size_t len; | ||
2242 | struct GNUNET_TUN_IcmpHeader *icmp; | ||
2243 | |||
2244 | GNUNET_STATISTICS_update (stats, | ||
2245 | gettext_noop ("# ICMP packets sent via TUN"), | ||
2246 | 1, GNUNET_NO); | ||
2247 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2248 | "Sending packet with %u bytes ICMP payload via TUN\n", | ||
2249 | (unsigned int) payload_length); | ||
2250 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | ||
2251 | switch (destination_address->af) | ||
2252 | { | ||
2253 | case AF_INET: | ||
2254 | len += sizeof (struct GNUNET_TUN_IPv4Header); | ||
2255 | break; | ||
2256 | case AF_INET6: | ||
2257 | len += sizeof (struct GNUNET_TUN_IPv6Header); | ||
2258 | break; | ||
2259 | default: | ||
2260 | GNUNET_break (0); | ||
2261 | return; | ||
2262 | } | ||
2263 | len += sizeof (struct GNUNET_TUN_IcmpHeader); | ||
2264 | len += payload_length; | ||
2265 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
2266 | { | ||
2267 | GNUNET_break (0); | ||
2268 | return; | ||
2269 | } | ||
2270 | { | ||
2271 | char buf[len] GNUNET_ALIGN; | ||
2272 | struct GNUNET_MessageHeader *hdr; | ||
2273 | struct GNUNET_TUN_Layer2PacketHeader *tun; | ||
2274 | |||
2275 | hdr= (struct GNUNET_MessageHeader *) buf; | ||
2276 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2277 | hdr->size = htons (len); | ||
2278 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; | ||
2279 | tun->flags = htons (0); | ||
2280 | switch (source_address->af) | ||
2281 | { | ||
2282 | case AF_INET: | ||
2283 | { | ||
2284 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | ||
2285 | |||
2286 | tun->proto = htons (ETH_P_IPV4); | ||
2287 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
2288 | IPPROTO_ICMP, | ||
2289 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, | ||
2290 | &source_address->address.ipv4, | ||
2291 | &destination_address->address.ipv4); | ||
2292 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1]; | ||
2293 | } | ||
2294 | break; | ||
2295 | case AF_INET6: | ||
2296 | { | ||
2297 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
2298 | |||
2299 | tun->proto = htons (ETH_P_IPV6); | ||
2300 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
2301 | IPPROTO_ICMPV6, | ||
2302 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, | ||
2303 | &source_address->address.ipv6, | ||
2304 | &destination_address->address.ipv6); | ||
2305 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1]; | ||
2306 | } | ||
2307 | break; | ||
2308 | default: | ||
2309 | GNUNET_assert (0); | ||
2310 | break; | ||
2311 | } | ||
2312 | *icmp = *icmp_header; | ||
2313 | GNUNET_memcpy (&icmp[1], | ||
2314 | payload, | ||
2315 | payload_length); | ||
2316 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
2317 | payload, | ||
2318 | payload_length); | ||
2319 | if (NULL != helper_handle) | ||
2320 | (void) GNUNET_HELPER_send (helper_handle, | ||
2321 | (const struct GNUNET_MessageHeader*) buf, | ||
2322 | GNUNET_YES, | ||
2323 | NULL, NULL); | ||
2324 | } | ||
2325 | } | 1852 | } |
2326 | 1853 | ||
2327 | 1854 | ||
@@ -2378,35 +1905,46 @@ make_up_icmpv6_payload (struct ChannelState *state, | |||
2378 | 1905 | ||
2379 | 1906 | ||
2380 | /** | 1907 | /** |
2381 | * Process a request to forward ICMP data to the Internet via this peer. | 1908 | * Check a request to forward ICMP data to the Internet via this peer. |
2382 | * | 1909 | * |
2383 | * @param cls closure, NULL | 1910 | * @param cls our `struct ChannelState *` |
2384 | * @param channel connection to the other end | 1911 | * @param msg the actual message |
2385 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
2386 | * @param message the actual message | ||
2387 | * @return #GNUNET_OK to keep the connection open, | 1912 | * @return #GNUNET_OK to keep the connection open, |
2388 | * #GNUNET_SYSERR to close it (signal serious error) | 1913 | * #GNUNET_SYSERR to close it (signal serious error) |
2389 | */ | 1914 | */ |
2390 | static int | 1915 | static int |
2391 | receive_icmp_remote (void *cls, | 1916 | check_icmp_remote (void *cls, |
2392 | struct GNUNET_CADET_Channel *channel, | 1917 | const struct GNUNET_EXIT_IcmpInternetMessage *msg) |
2393 | void **channel_ctx, | ||
2394 | const struct GNUNET_MessageHeader *message) | ||
2395 | { | 1918 | { |
2396 | struct ChannelState *state = *channel_ctx; | 1919 | struct ChannelState *state = cls; |
2397 | const struct GNUNET_EXIT_IcmpInternetMessage *msg; | ||
2398 | uint16_t pkt_len = ntohs (message->size); | ||
2399 | const struct in_addr *v4; | ||
2400 | const struct in6_addr *v6; | ||
2401 | const void *payload; | ||
2402 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
2403 | int af; | ||
2404 | 1920 | ||
2405 | if (GNUNET_YES == state->is_dns) | 1921 | if (GNUNET_YES == state->is_dns) |
2406 | { | 1922 | { |
2407 | GNUNET_break_op (0); | 1923 | GNUNET_break_op (0); |
2408 | return GNUNET_SYSERR; | 1924 | return GNUNET_SYSERR; |
2409 | } | 1925 | } |
1926 | return GNUNET_OK; | ||
1927 | } | ||
1928 | |||
1929 | |||
1930 | /** | ||
1931 | * Process a request to forward ICMP data to the Internet via this peer. | ||
1932 | * | ||
1933 | * @param cls our `struct ChannelState *` | ||
1934 | * @param msg the actual message | ||
1935 | */ | ||
1936 | static void | ||
1937 | handle_icmp_remote (void *cls, | ||
1938 | const struct GNUNET_EXIT_IcmpInternetMessage *msg) | ||
1939 | { | ||
1940 | struct ChannelState *state = cls; | ||
1941 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_IcmpInternetMessage); | ||
1942 | const struct in_addr *v4; | ||
1943 | const struct in6_addr *v6; | ||
1944 | const void *payload; | ||
1945 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
1946 | int af; | ||
1947 | |||
2410 | if (GNUNET_SYSERR == state->is_dns) | 1948 | if (GNUNET_SYSERR == state->is_dns) |
2411 | { | 1949 | { |
2412 | /* channel is UDP/TCP from now on */ | 1950 | /* channel is UDP/TCP from now on */ |
@@ -2418,13 +1956,6 @@ receive_icmp_remote (void *cls, | |||
2418 | GNUNET_STATISTICS_update (stats, | 1956 | GNUNET_STATISTICS_update (stats, |
2419 | gettext_noop ("# ICMP IP-exit requests received via cadet"), | 1957 | gettext_noop ("# ICMP IP-exit requests received via cadet"), |
2420 | 1, GNUNET_NO); | 1958 | 1, GNUNET_NO); |
2421 | if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpInternetMessage)) | ||
2422 | { | ||
2423 | GNUNET_break_op (0); | ||
2424 | return GNUNET_SYSERR; | ||
2425 | } | ||
2426 | msg = (const struct GNUNET_EXIT_IcmpInternetMessage*) message; | ||
2427 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage); | ||
2428 | 1959 | ||
2429 | af = (int) ntohl (msg->af); | 1960 | af = (int) ntohl (msg->af); |
2430 | if ( (NULL != state->specifics.tcp_udp.heap_node) && | 1961 | if ( (NULL != state->specifics.tcp_udp.heap_node) && |
@@ -2432,7 +1963,7 @@ receive_icmp_remote (void *cls, | |||
2432 | { | 1963 | { |
2433 | /* other peer switched AF on this channel; not allowed */ | 1964 | /* other peer switched AF on this channel; not allowed */ |
2434 | GNUNET_break_op (0); | 1965 | GNUNET_break_op (0); |
2435 | return GNUNET_SYSERR; | 1966 | return; |
2436 | } | 1967 | } |
2437 | 1968 | ||
2438 | switch (af) | 1969 | switch (af) |
@@ -2441,12 +1972,12 @@ receive_icmp_remote (void *cls, | |||
2441 | if (pkt_len < sizeof (struct in_addr)) | 1972 | if (pkt_len < sizeof (struct in_addr)) |
2442 | { | 1973 | { |
2443 | GNUNET_break_op (0); | 1974 | GNUNET_break_op (0); |
2444 | return GNUNET_SYSERR; | 1975 | return; |
2445 | } | 1976 | } |
2446 | if (! ipv4_exit) | 1977 | if (! ipv4_exit) |
2447 | { | 1978 | { |
2448 | GNUNET_break_op (0); | 1979 | GNUNET_break_op (0); |
2449 | return GNUNET_SYSERR; | 1980 | return; |
2450 | } | 1981 | } |
2451 | v4 = (const struct in_addr*) &msg[1]; | 1982 | v4 = (const struct in_addr*) &msg[1]; |
2452 | payload = &v4[1]; | 1983 | payload = &v4[1]; |
@@ -2471,7 +2002,7 @@ receive_icmp_remote (void *cls, | |||
2471 | if (0 != pkt_len) | 2002 | if (0 != pkt_len) |
2472 | { | 2003 | { |
2473 | GNUNET_break_op (0); | 2004 | GNUNET_break_op (0); |
2474 | return GNUNET_SYSERR; | 2005 | return; |
2475 | } | 2006 | } |
2476 | /* make up payload */ | 2007 | /* make up payload */ |
2477 | { | 2008 | { |
@@ -2491,7 +2022,7 @@ receive_icmp_remote (void *cls, | |||
2491 | GNUNET_STATISTICS_update (stats, | 2022 | GNUNET_STATISTICS_update (stats, |
2492 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | 2023 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), |
2493 | 1, GNUNET_NO); | 2024 | 1, GNUNET_NO); |
2494 | return GNUNET_SYSERR; | 2025 | return; |
2495 | } | 2026 | } |
2496 | /* end AF_INET */ | 2027 | /* end AF_INET */ |
2497 | break; | 2028 | break; |
@@ -2499,12 +2030,12 @@ receive_icmp_remote (void *cls, | |||
2499 | if (pkt_len < sizeof (struct in6_addr)) | 2030 | if (pkt_len < sizeof (struct in6_addr)) |
2500 | { | 2031 | { |
2501 | GNUNET_break_op (0); | 2032 | GNUNET_break_op (0); |
2502 | return GNUNET_SYSERR; | 2033 | return; |
2503 | } | 2034 | } |
2504 | if (! ipv6_exit) | 2035 | if (! ipv6_exit) |
2505 | { | 2036 | { |
2506 | GNUNET_break_op (0); | 2037 | GNUNET_break_op (0); |
2507 | return GNUNET_SYSERR; | 2038 | return; |
2508 | } | 2039 | } |
2509 | v6 = (const struct in6_addr*) &msg[1]; | 2040 | v6 = (const struct in6_addr*) &msg[1]; |
2510 | payload = &v6[1]; | 2041 | payload = &v6[1]; |
@@ -2530,7 +2061,7 @@ receive_icmp_remote (void *cls, | |||
2530 | if (0 != pkt_len) | 2061 | if (0 != pkt_len) |
2531 | { | 2062 | { |
2532 | GNUNET_break_op (0); | 2063 | GNUNET_break_op (0); |
2533 | return GNUNET_SYSERR; | 2064 | return; |
2534 | } | 2065 | } |
2535 | /* make up payload */ | 2066 | /* make up payload */ |
2536 | { | 2067 | { |
@@ -2550,14 +2081,14 @@ receive_icmp_remote (void *cls, | |||
2550 | GNUNET_STATISTICS_update (stats, | 2081 | GNUNET_STATISTICS_update (stats, |
2551 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | 2082 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), |
2552 | 1, GNUNET_NO); | 2083 | 1, GNUNET_NO); |
2553 | return GNUNET_SYSERR; | 2084 | return; |
2554 | } | 2085 | } |
2555 | /* end AF_INET6 */ | 2086 | /* end AF_INET6 */ |
2556 | break; | 2087 | break; |
2557 | default: | 2088 | default: |
2558 | /* bad AF */ | 2089 | /* bad AF */ |
2559 | GNUNET_break_op (0); | 2090 | GNUNET_break_op (0); |
2560 | return GNUNET_SYSERR; | 2091 | return; |
2561 | } | 2092 | } |
2562 | 2093 | ||
2563 | { | 2094 | { |
@@ -2573,8 +2104,7 @@ receive_icmp_remote (void *cls, | |||
2573 | &state->specifics.tcp_udp.ri.local_address, | 2104 | &state->specifics.tcp_udp.ri.local_address, |
2574 | &msg->icmp_header, | 2105 | &msg->icmp_header, |
2575 | payload, pkt_len); | 2106 | payload, pkt_len); |
2576 | GNUNET_CADET_receive_done (channel); | 2107 | GNUNET_CADET_receive_done (state->channel); |
2577 | return GNUNET_YES; | ||
2578 | } | 2108 | } |
2579 | 2109 | ||
2580 | 2110 | ||
@@ -2629,28 +2159,19 @@ make_up_icmp_service_payload (struct ChannelState *state, | |||
2629 | 2159 | ||
2630 | 2160 | ||
2631 | /** | 2161 | /** |
2632 | * Process a request via cadet to send ICMP data to a service | 2162 | * Check a request via cadet to send ICMP data to a service |
2633 | * offered by this system. | 2163 | * offered by this system. |
2634 | * | 2164 | * |
2635 | * @param cls closure, NULL | 2165 | * @param cls our `struct ChannelState *` |
2636 | * @param channel connection to the other end | 2166 | * @param msg the actual message |
2637 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
2638 | * @param message the actual message | ||
2639 | * @return #GNUNET_OK to keep the connection open, | 2167 | * @return #GNUNET_OK to keep the connection open, |
2640 | * #GNUNET_SYSERR to close it (signal serious error) | 2168 | * #GNUNET_SYSERR to close it (signal serious error) |
2641 | */ | 2169 | */ |
2642 | static int | 2170 | static int |
2643 | receive_icmp_service (void *cls, | 2171 | check_icmp_service (void *cls, |
2644 | struct GNUNET_CADET_Channel *channel, | 2172 | const struct GNUNET_EXIT_IcmpServiceMessage *msg) |
2645 | void **channel_ctx, | ||
2646 | const struct GNUNET_MessageHeader *message) | ||
2647 | { | 2173 | { |
2648 | struct ChannelState *state = *channel_ctx; | 2174 | struct ChannelState *state = cls; |
2649 | const struct GNUNET_EXIT_IcmpServiceMessage *msg; | ||
2650 | uint16_t pkt_len = ntohs (message->size); | ||
2651 | struct GNUNET_TUN_IcmpHeader icmp; | ||
2652 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
2653 | const void *payload; | ||
2654 | 2175 | ||
2655 | if (GNUNET_YES == state->is_dns) | 2176 | if (GNUNET_YES == state->is_dns) |
2656 | { | 2177 | { |
@@ -2662,6 +2183,27 @@ receive_icmp_service (void *cls, | |||
2662 | GNUNET_break_op (0); | 2183 | GNUNET_break_op (0); |
2663 | return GNUNET_SYSERR; | 2184 | return GNUNET_SYSERR; |
2664 | } | 2185 | } |
2186 | return GNUNET_OK; | ||
2187 | } | ||
2188 | |||
2189 | |||
2190 | /** | ||
2191 | * Process a request via cadet to send ICMP data to a service | ||
2192 | * offered by this system. | ||
2193 | * | ||
2194 | * @param cls our `struct ChannelState *` | ||
2195 | * @param msg the actual message | ||
2196 | */ | ||
2197 | static void | ||
2198 | handle_icmp_service (void *cls, | ||
2199 | const struct GNUNET_EXIT_IcmpServiceMessage *msg) | ||
2200 | { | ||
2201 | struct ChannelState *state = cls; | ||
2202 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_IcmpServiceMessage); | ||
2203 | struct GNUNET_TUN_IcmpHeader icmp; | ||
2204 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
2205 | const void *payload; | ||
2206 | |||
2665 | GNUNET_STATISTICS_update (stats, | 2207 | GNUNET_STATISTICS_update (stats, |
2666 | gettext_noop ("# Bytes received from CADET"), | 2208 | gettext_noop ("# Bytes received from CADET"), |
2667 | pkt_len, GNUNET_NO); | 2209 | pkt_len, GNUNET_NO); |
@@ -2669,13 +2211,6 @@ receive_icmp_service (void *cls, | |||
2669 | gettext_noop ("# ICMP service requests received via cadet"), | 2211 | gettext_noop ("# ICMP service requests received via cadet"), |
2670 | 1, GNUNET_NO); | 2212 | 1, GNUNET_NO); |
2671 | /* check that we got at least a valid header */ | 2213 | /* check that we got at least a valid header */ |
2672 | if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpServiceMessage)) | ||
2673 | { | ||
2674 | GNUNET_break_op (0); | ||
2675 | return GNUNET_SYSERR; | ||
2676 | } | ||
2677 | msg = (const struct GNUNET_EXIT_IcmpServiceMessage*) message; | ||
2678 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpServiceMessage); | ||
2679 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2680 | "Received data from %s for forwarding to ICMP service %s\n", | 2215 | "Received data from %s for forwarding to ICMP service %s\n", |
2681 | GNUNET_i2s (&state->peer), | 2216 | GNUNET_i2s (&state->peer), |
@@ -2707,7 +2242,7 @@ receive_icmp_service (void *cls, | |||
2707 | if (0 != pkt_len) | 2242 | if (0 != pkt_len) |
2708 | { | 2243 | { |
2709 | GNUNET_break_op (0); | 2244 | GNUNET_break_op (0); |
2710 | return GNUNET_SYSERR; | 2245 | return; |
2711 | } | 2246 | } |
2712 | payload = buf; | 2247 | payload = buf; |
2713 | pkt_len = make_up_icmp_service_payload (state, buf); | 2248 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2718,7 +2253,7 @@ receive_icmp_service (void *cls, | |||
2718 | if (0 != pkt_len) | 2253 | if (0 != pkt_len) |
2719 | { | 2254 | { |
2720 | GNUNET_break_op (0); | 2255 | GNUNET_break_op (0); |
2721 | return GNUNET_SYSERR; | 2256 | return; |
2722 | } | 2257 | } |
2723 | payload = buf; | 2258 | payload = buf; |
2724 | pkt_len = make_up_icmp_service_payload (state, buf); | 2259 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2729,12 +2264,12 @@ receive_icmp_service (void *cls, | |||
2729 | GNUNET_STATISTICS_update (stats, | 2264 | GNUNET_STATISTICS_update (stats, |
2730 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | 2265 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), |
2731 | 1, GNUNET_NO); | 2266 | 1, GNUNET_NO); |
2732 | return GNUNET_OK; | 2267 | return; |
2733 | } | 2268 | } |
2734 | if (0 != pkt_len) | 2269 | if (0 != pkt_len) |
2735 | { | 2270 | { |
2736 | GNUNET_break_op (0); | 2271 | GNUNET_break_op (0); |
2737 | return GNUNET_SYSERR; | 2272 | return; |
2738 | } | 2273 | } |
2739 | payload = buf; | 2274 | payload = buf; |
2740 | pkt_len = make_up_icmp_service_payload (state, buf); | 2275 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2744,7 +2279,7 @@ receive_icmp_service (void *cls, | |||
2744 | GNUNET_STATISTICS_update (stats, | 2279 | GNUNET_STATISTICS_update (stats, |
2745 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | 2280 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), |
2746 | 1, GNUNET_NO); | 2281 | 1, GNUNET_NO); |
2747 | return GNUNET_SYSERR; | 2282 | return; |
2748 | } | 2283 | } |
2749 | /* end of AF_INET */ | 2284 | /* end of AF_INET */ |
2750 | break; | 2285 | break; |
@@ -2765,7 +2300,7 @@ receive_icmp_service (void *cls, | |||
2765 | if (0 != pkt_len) | 2300 | if (0 != pkt_len) |
2766 | { | 2301 | { |
2767 | GNUNET_break_op (0); | 2302 | GNUNET_break_op (0); |
2768 | return GNUNET_SYSERR; | 2303 | return; |
2769 | } | 2304 | } |
2770 | payload = buf; | 2305 | payload = buf; |
2771 | pkt_len = make_up_icmp_service_payload (state, buf); | 2306 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2776,7 +2311,7 @@ receive_icmp_service (void *cls, | |||
2776 | if (0 != pkt_len) | 2311 | if (0 != pkt_len) |
2777 | { | 2312 | { |
2778 | GNUNET_break_op (0); | 2313 | GNUNET_break_op (0); |
2779 | return GNUNET_SYSERR; | 2314 | return; |
2780 | } | 2315 | } |
2781 | payload = buf; | 2316 | payload = buf; |
2782 | pkt_len = make_up_icmp_service_payload (state, buf); | 2317 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2788,12 +2323,12 @@ receive_icmp_service (void *cls, | |||
2788 | GNUNET_STATISTICS_update (stats, | 2323 | GNUNET_STATISTICS_update (stats, |
2789 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | 2324 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), |
2790 | 1, GNUNET_NO); | 2325 | 1, GNUNET_NO); |
2791 | return GNUNET_OK; | 2326 | return; |
2792 | } | 2327 | } |
2793 | if (0 != pkt_len) | 2328 | if (0 != pkt_len) |
2794 | { | 2329 | { |
2795 | GNUNET_break_op (0); | 2330 | GNUNET_break_op (0); |
2796 | return GNUNET_SYSERR; | 2331 | return; |
2797 | } | 2332 | } |
2798 | payload = buf; | 2333 | payload = buf; |
2799 | pkt_len = make_up_icmp_service_payload (state, buf); | 2334 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2803,283 +2338,715 @@ receive_icmp_service (void *cls, | |||
2803 | GNUNET_STATISTICS_update (stats, | 2338 | GNUNET_STATISTICS_update (stats, |
2804 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | 2339 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), |
2805 | 1, GNUNET_NO); | 2340 | 1, GNUNET_NO); |
2806 | return GNUNET_SYSERR; | 2341 | return; |
2807 | } | 2342 | } |
2808 | /* end of AF_INET6 */ | 2343 | /* end of AF_INET6 */ |
2809 | break; | 2344 | break; |
2810 | default: | 2345 | default: |
2811 | GNUNET_break_op (0); | 2346 | GNUNET_break_op (0); |
2812 | return GNUNET_SYSERR; | 2347 | return; |
2813 | } | 2348 | } |
2814 | 2349 | ||
2815 | send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 2350 | send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2816 | &state->specifics.tcp_udp.ri.local_address, | 2351 | &state->specifics.tcp_udp.ri.local_address, |
2817 | &icmp, | 2352 | &icmp, |
2818 | payload, pkt_len); | 2353 | payload, |
2819 | GNUNET_CADET_receive_done (channel); | 2354 | pkt_len); |
2820 | return GNUNET_YES; | 2355 | GNUNET_CADET_receive_done (state->channel); |
2821 | } | 2356 | } |
2822 | 2357 | ||
2823 | 2358 | ||
2824 | /** | 2359 | /** |
2825 | * Send a UDP packet via the TUN interface. | 2360 | * Free memory associated with a service record. |
2826 | * | 2361 | * |
2827 | * @param destination_address IP and port to use for the UDP packet's destination | 2362 | * @param cls unused |
2828 | * @param source_address IP and port to use for the UDP packet's source | 2363 | * @param key service descriptor |
2829 | * @param payload payload of the UDP packet (does NOT include UDP header) | 2364 | * @param value service record to free |
2830 | * @param payload_length number of bytes of data in @a payload | 2365 | * @return #GNUNET_OK |
2831 | */ | 2366 | */ |
2832 | static void | 2367 | static int |
2833 | send_udp_packet_via_tun (const struct SocketAddress *destination_address, | 2368 | free_service_record (void *cls, |
2834 | const struct SocketAddress *source_address, | 2369 | const struct GNUNET_HashCode *key, |
2835 | const void *payload, size_t payload_length) | 2370 | void *value) |
2836 | { | 2371 | { |
2837 | size_t len; | 2372 | struct LocalService *service = value; |
2373 | |||
2374 | GNUNET_assert (GNUNET_YES == | ||
2375 | GNUNET_CONTAINER_multihashmap_remove (services, | ||
2376 | key, | ||
2377 | service)); | ||
2378 | GNUNET_CADET_close_port (service->port); | ||
2379 | GNUNET_free_non_null (service->name); | ||
2380 | GNUNET_free (service); | ||
2381 | return GNUNET_OK; | ||
2382 | } | ||
2838 | 2383 | ||
2384 | |||
2385 | /** | ||
2386 | * Callback from CADET for new channels. | ||
2387 | * | ||
2388 | * @param cls closure | ||
2389 | * @param channel new handle to the channel | ||
2390 | * @param initiator peer that started the channel | ||
2391 | * @return initial channel context for the channel | ||
2392 | */ | ||
2393 | static void * | ||
2394 | new_service_channel (void *cls, | ||
2395 | struct GNUNET_CADET_Channel *channel, | ||
2396 | const struct GNUNET_PeerIdentity *initiator) | ||
2397 | { | ||
2398 | struct LocalService *ls = cls; | ||
2399 | struct ChannelState *s = GNUNET_new (struct ChannelState); | ||
2400 | |||
2401 | s->peer = *initiator; | ||
2839 | GNUNET_STATISTICS_update (stats, | 2402 | GNUNET_STATISTICS_update (stats, |
2840 | gettext_noop ("# UDP packets sent via TUN"), | 2403 | gettext_noop ("# Inbound CADET channels created"), |
2841 | 1, GNUNET_NO); | 2404 | 1, |
2405 | GNUNET_NO); | ||
2842 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2406 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2843 | "Sending packet with %u bytes UDP payload via TUN\n", | 2407 | "Received inbound channel from `%s'\n", |
2844 | (unsigned int) payload_length); | 2408 | GNUNET_i2s (initiator)); |
2845 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | 2409 | s->channel = channel; |
2846 | switch (source_address->af) | 2410 | s->specifics.tcp_udp.serv = ls; |
2411 | s->specifics.tcp_udp.ri.remote_address = ls->address; | ||
2412 | return s; | ||
2413 | } | ||
2414 | |||
2415 | |||
2416 | /** | ||
2417 | * Function called by cadet whenever an inbound channel is destroyed. | ||
2418 | * Should clean up any associated state. | ||
2419 | * | ||
2420 | * @param cls our `struct ChannelState *` | ||
2421 | * @param channel connection to the other end (henceforth invalid) | ||
2422 | */ | ||
2423 | static void | ||
2424 | clean_channel (void *cls, | ||
2425 | const struct GNUNET_CADET_Channel *channel) | ||
2426 | { | ||
2427 | struct ChannelState *s = cls; | ||
2428 | |||
2429 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2430 | "Channel destroyed\n"); | ||
2431 | if (GNUNET_SYSERR == s->is_dns) | ||
2847 | { | 2432 | { |
2848 | case AF_INET: | 2433 | GNUNET_free (s); |
2849 | len += sizeof (struct GNUNET_TUN_IPv4Header); | ||
2850 | break; | ||
2851 | case AF_INET6: | ||
2852 | len += sizeof (struct GNUNET_TUN_IPv6Header); | ||
2853 | break; | ||
2854 | default: | ||
2855 | GNUNET_break (0); | ||
2856 | return; | 2434 | return; |
2857 | } | 2435 | } |
2858 | len += sizeof (struct GNUNET_TUN_UdpHeader); | 2436 | if (GNUNET_YES == s->is_dns) |
2859 | len += payload_length; | ||
2860 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
2861 | { | 2437 | { |
2862 | GNUNET_break (0); | 2438 | if (channels[s->specifics.dns.my_id] == s) |
2863 | return; | 2439 | channels[s->specifics.dns.my_id] = NULL; |
2864 | } | 2440 | } |
2441 | else | ||
2865 | { | 2442 | { |
2866 | char buf[len] GNUNET_ALIGN; | 2443 | if (NULL != s->specifics.tcp_udp.heap_node) |
2867 | struct GNUNET_MessageHeader *hdr; | ||
2868 | struct GNUNET_TUN_Layer2PacketHeader *tun; | ||
2869 | |||
2870 | hdr= (struct GNUNET_MessageHeader *) buf; | ||
2871 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2872 | hdr->size = htons (len); | ||
2873 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; | ||
2874 | tun->flags = htons (0); | ||
2875 | switch (source_address->af) | ||
2876 | { | 2444 | { |
2877 | case AF_INET: | 2445 | GNUNET_assert (GNUNET_YES == |
2878 | { | 2446 | GNUNET_CONTAINER_multihashmap_remove (connections_map, |
2879 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | 2447 | &s->specifics.tcp_udp.state_key, |
2880 | 2448 | s)); | |
2881 | tun->proto = htons (ETH_P_IPV4); | 2449 | GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node); |
2882 | prepare_ipv4_packet (payload, | 2450 | s->specifics.tcp_udp.heap_node = NULL; |
2883 | payload_length, | ||
2884 | IPPROTO_UDP, | ||
2885 | NULL, | ||
2886 | source_address, | ||
2887 | destination_address, | ||
2888 | ipv4); | ||
2889 | } | ||
2890 | break; | ||
2891 | case AF_INET6: | ||
2892 | { | ||
2893 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
2894 | |||
2895 | tun->proto = htons (ETH_P_IPV6); | ||
2896 | prepare_ipv6_packet (payload, | ||
2897 | payload_length, | ||
2898 | IPPROTO_UDP, | ||
2899 | NULL, | ||
2900 | source_address, | ||
2901 | destination_address, | ||
2902 | ipv6); | ||
2903 | } | ||
2904 | break; | ||
2905 | default: | ||
2906 | GNUNET_assert (0); | ||
2907 | break; | ||
2908 | } | 2451 | } |
2909 | if (NULL != helper_handle) | ||
2910 | (void) GNUNET_HELPER_send (helper_handle, | ||
2911 | (const struct GNUNET_MessageHeader*) buf, | ||
2912 | GNUNET_YES, | ||
2913 | NULL, NULL); | ||
2914 | } | 2452 | } |
2453 | GNUNET_free (s); | ||
2915 | } | 2454 | } |
2916 | 2455 | ||
2917 | 2456 | ||
2918 | /** | 2457 | /** |
2919 | * Process a request to forward UDP data to the Internet via this peer. | 2458 | * Given a service descriptor and a destination port, find the |
2459 | * respective service entry. | ||
2920 | * | 2460 | * |
2921 | * @param cls closure, NULL | 2461 | * @param proto IPPROTO_TCP or IPPROTO_UDP |
2922 | * @param channel connection to the other end | 2462 | * @param name name of the service |
2923 | * @param channel_ctx pointer to our 'struct ChannelState *' | 2463 | * @param destination_port destination port |
2924 | * @param message the actual message | 2464 | * @param service service information record to store (service->name will be set). |
2925 | * @return #GNUNET_OK to keep the connection open, | ||
2926 | * #GNUNET_SYSERR to close it (signal serious error) | ||
2927 | */ | 2465 | */ |
2928 | static int | 2466 | static void |
2929 | receive_udp_remote (void *cls, | 2467 | store_service (int proto, |
2930 | struct GNUNET_CADET_Channel *channel, | 2468 | const char *name, |
2931 | void **channel_ctx, | 2469 | uint16_t destination_port, |
2932 | const struct GNUNET_MessageHeader *message) | 2470 | struct LocalService *service) |
2933 | { | 2471 | { |
2934 | struct ChannelState *state = *channel_ctx; | 2472 | struct GNUNET_MQ_MessageHandler handlers[] = { |
2935 | const struct GNUNET_EXIT_UdpInternetMessage *msg; | 2473 | GNUNET_MQ_hd_var_size (icmp_service, |
2936 | uint16_t pkt_len = ntohs (message->size); | 2474 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, |
2937 | const struct in_addr *v4; | 2475 | struct GNUNET_EXIT_IcmpServiceMessage, |
2938 | const struct in6_addr *v6; | 2476 | service), |
2939 | const void *payload; | 2477 | GNUNET_MQ_hd_var_size (udp_service, |
2940 | int af; | 2478 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, |
2479 | struct GNUNET_EXIT_UdpServiceMessage, | ||
2480 | service), | ||
2481 | GNUNET_MQ_hd_var_size (tcp_service, | ||
2482 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, | ||
2483 | struct GNUNET_EXIT_TcpServiceStartMessage, | ||
2484 | service), | ||
2485 | GNUNET_MQ_hd_var_size (tcp_data, | ||
2486 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, | ||
2487 | struct GNUNET_EXIT_TcpDataMessage, | ||
2488 | service), | ||
2489 | GNUNET_MQ_handler_end () | ||
2490 | }; | ||
2941 | 2491 | ||
2942 | if (GNUNET_YES == state->is_dns) | 2492 | struct GNUNET_HashCode cadet_port; |
2493 | |||
2494 | service->name = GNUNET_strdup (name); | ||
2495 | GNUNET_TUN_service_name_to_hash (name, | ||
2496 | &service->descriptor); | ||
2497 | GNUNET_TUN_compute_service_cadet_port (&service->descriptor, | ||
2498 | destination_port, | ||
2499 | &cadet_port); | ||
2500 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2501 | "Opening CADET port %s for SERVICE exit %s on port %u\n", | ||
2502 | GNUNET_h2s (&cadet_port), | ||
2503 | name, | ||
2504 | (unsigned int) destination_port); | ||
2505 | service->port = GNUNET_CADET_open_porT (cadet_handle, | ||
2506 | &cadet_port, | ||
2507 | &new_service_channel, | ||
2508 | service, | ||
2509 | NULL, | ||
2510 | &clean_channel, | ||
2511 | handlers); | ||
2512 | service->is_udp = (IPPROTO_UDP == proto); | ||
2513 | if (GNUNET_OK != | ||
2514 | GNUNET_CONTAINER_multihashmap_put (services, | ||
2515 | &cadet_port, | ||
2516 | service, | ||
2517 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
2943 | { | 2518 | { |
2944 | GNUNET_break_op (0); | 2519 | GNUNET_CADET_close_port (service->port); |
2945 | return GNUNET_SYSERR; | 2520 | GNUNET_free_non_null (service->name); |
2521 | GNUNET_free (service); | ||
2522 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2523 | _("Got duplicate service records for `%s:%u'\n"), | ||
2524 | name, | ||
2525 | (unsigned int) destination_port); | ||
2946 | } | 2526 | } |
2947 | if (GNUNET_SYSERR == state->is_dns) | 2527 | } |
2528 | |||
2529 | |||
2530 | /** | ||
2531 | * Send the given packet via the cadet channel. | ||
2532 | * | ||
2533 | * @param s channel destination | ||
2534 | * @param env message to queue | ||
2535 | */ | ||
2536 | static void | ||
2537 | send_packet_to_cadet_channel (struct ChannelState *s, | ||
2538 | struct GNUNET_MQ_Envelope *env) | ||
2539 | { | ||
2540 | GNUNET_assert (NULL != s); | ||
2541 | GNUNET_STATISTICS_update (stats, | ||
2542 | gettext_noop ("# Messages transmitted via cadet channels"), | ||
2543 | 1, | ||
2544 | GNUNET_NO); | ||
2545 | GNUNET_MQ_send (GNUNET_CADET_get_mq (s->channel), | ||
2546 | env); | ||
2547 | } | ||
2548 | |||
2549 | |||
2550 | /** | ||
2551 | * @brief Handles an ICMP packet received from the helper. | ||
2552 | * | ||
2553 | * @param icmp A pointer to the Packet | ||
2554 | * @param pktlen number of bytes in @a icmp | ||
2555 | * @param af address family (AFINET or AF_INET6) | ||
2556 | * @param destination_ip destination IP-address of the IP packet (should | ||
2557 | * be our local address) | ||
2558 | * @param source_ip original source IP-address of the IP packet (should | ||
2559 | * be the original destination address) | ||
2560 | */ | ||
2561 | static void | ||
2562 | icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp, | ||
2563 | size_t pktlen, | ||
2564 | int af, | ||
2565 | const void *destination_ip, | ||
2566 | const void *source_ip) | ||
2567 | { | ||
2568 | struct ChannelState *state; | ||
2569 | struct GNUNET_MQ_Envelope *env; | ||
2570 | struct GNUNET_EXIT_IcmpToVPNMessage *i2v; | ||
2571 | const struct GNUNET_TUN_IPv4Header *ipv4; | ||
2572 | const struct GNUNET_TUN_IPv6Header *ipv6; | ||
2573 | const struct GNUNET_TUN_UdpHeader *udp; | ||
2574 | uint16_t source_port; | ||
2575 | uint16_t destination_port; | ||
2576 | uint8_t protocol; | ||
2577 | |||
2948 | { | 2578 | { |
2949 | /* channel is UDP/TCP from now on */ | 2579 | char sbuf[INET6_ADDRSTRLEN]; |
2950 | state->is_dns = GNUNET_NO; | 2580 | char dbuf[INET6_ADDRSTRLEN]; |
2581 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2582 | "Received ICMP packet going from %s to %s\n", | ||
2583 | inet_ntop (af, | ||
2584 | source_ip, | ||
2585 | sbuf, sizeof (sbuf)), | ||
2586 | inet_ntop (af, | ||
2587 | destination_ip, | ||
2588 | dbuf, sizeof (dbuf))); | ||
2951 | } | 2589 | } |
2952 | GNUNET_STATISTICS_update (stats, | 2590 | if (pktlen < sizeof (struct GNUNET_TUN_IcmpHeader)) |
2953 | gettext_noop ("# Bytes received from CADET"), | ||
2954 | pkt_len, GNUNET_NO); | ||
2955 | GNUNET_STATISTICS_update (stats, | ||
2956 | gettext_noop ("# UDP IP-exit requests received via cadet"), | ||
2957 | 1, GNUNET_NO); | ||
2958 | if (pkt_len < sizeof (struct GNUNET_EXIT_UdpInternetMessage)) | ||
2959 | { | 2591 | { |
2960 | GNUNET_break_op (0); | 2592 | /* blame kernel */ |
2961 | return GNUNET_SYSERR; | 2593 | GNUNET_break (0); |
2594 | return; | ||
2962 | } | 2595 | } |
2963 | msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message; | 2596 | |
2964 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage); | 2597 | /* Find out if this is an ICMP packet in response to an existing |
2965 | af = (int) ntohl (msg->af); | 2598 | TCP/UDP packet and if so, figure out ports / protocol of the |
2966 | state->specifics.tcp_udp.ri.remote_address.af = af; | 2599 | existing session from the IP data in the ICMP payload */ |
2600 | source_port = 0; | ||
2601 | destination_port = 0; | ||
2967 | switch (af) | 2602 | switch (af) |
2968 | { | 2603 | { |
2969 | case AF_INET: | 2604 | case AF_INET: |
2970 | if (pkt_len < sizeof (struct in_addr)) | 2605 | protocol = IPPROTO_ICMP; |
2971 | { | 2606 | switch (icmp->type) |
2972 | GNUNET_break_op (0); | 2607 | { |
2973 | return GNUNET_SYSERR; | 2608 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: |
2974 | } | 2609 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: |
2975 | if (! ipv4_exit) | 2610 | break; |
2976 | { | 2611 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: |
2977 | GNUNET_break_op (0); | 2612 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: |
2978 | return GNUNET_SYSERR; | 2613 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: |
2979 | } | 2614 | if (pktlen < |
2980 | v4 = (const struct in_addr*) &msg[1]; | 2615 | sizeof (struct GNUNET_TUN_IcmpHeader) + |
2981 | payload = &v4[1]; | 2616 | sizeof (struct GNUNET_TUN_IPv4Header) + 8) |
2982 | pkt_len -= sizeof (struct in_addr); | 2617 | { |
2983 | state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4; | 2618 | /* blame kernel */ |
2619 | GNUNET_break (0); | ||
2620 | return; | ||
2621 | } | ||
2622 | ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
2623 | protocol = ipv4->protocol; | ||
2624 | /* could be TCP or UDP, but both have the ports in the right | ||
2625 | place, so that doesn't matter here */ | ||
2626 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
2627 | /* swap ports, as they are from the original message */ | ||
2628 | destination_port = ntohs (udp->source_port); | ||
2629 | source_port = ntohs (udp->destination_port); | ||
2630 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
2631 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
2632 | break; | ||
2633 | default: | ||
2634 | GNUNET_STATISTICS_update (stats, | ||
2635 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
2636 | 1, GNUNET_NO); | ||
2637 | return; | ||
2638 | } | ||
2984 | break; | 2639 | break; |
2985 | case AF_INET6: | 2640 | case AF_INET6: |
2986 | if (pkt_len < sizeof (struct in6_addr)) | 2641 | protocol = IPPROTO_ICMPV6; |
2987 | { | 2642 | switch (icmp->type) |
2988 | GNUNET_break_op (0); | 2643 | { |
2989 | return GNUNET_SYSERR; | 2644 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: |
2990 | } | 2645 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: |
2991 | if (! ipv6_exit) | 2646 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: |
2992 | { | 2647 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: |
2993 | GNUNET_break_op (0); | 2648 | if (pktlen < |
2994 | return GNUNET_SYSERR; | 2649 | sizeof (struct GNUNET_TUN_IcmpHeader) + |
2995 | } | 2650 | sizeof (struct GNUNET_TUN_IPv6Header) + 8) |
2996 | v6 = (const struct in6_addr*) &msg[1]; | 2651 | { |
2997 | payload = &v6[1]; | 2652 | /* blame kernel */ |
2998 | pkt_len -= sizeof (struct in6_addr); | 2653 | GNUNET_break (0); |
2999 | state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6; | 2654 | return; |
2655 | } | ||
2656 | ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
2657 | protocol = ipv6->next_header; | ||
2658 | /* could be TCP or UDP, but both have the ports in the right | ||
2659 | place, so that doesn't matter here */ | ||
2660 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
2661 | /* swap ports, as they are from the original message */ | ||
2662 | destination_port = ntohs (udp->source_port); | ||
2663 | source_port = ntohs (udp->destination_port); | ||
2664 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
2665 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
2666 | break; | ||
2667 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
2668 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
2669 | break; | ||
2670 | default: | ||
2671 | GNUNET_STATISTICS_update (stats, | ||
2672 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
2673 | 1, GNUNET_NO); | ||
2674 | return; | ||
2675 | } | ||
3000 | break; | 2676 | break; |
3001 | default: | 2677 | default: |
3002 | GNUNET_break_op (0); | 2678 | GNUNET_assert (0); |
3003 | return GNUNET_SYSERR; | ||
3004 | } | 2679 | } |
2680 | switch (protocol) | ||
3005 | { | 2681 | { |
3006 | char buf[INET6_ADDRSTRLEN]; | 2682 | case IPPROTO_ICMP: |
2683 | state = get_redirect_state (af, | ||
2684 | IPPROTO_ICMP, | ||
2685 | source_ip, | ||
2686 | 0, | ||
2687 | destination_ip, | ||
2688 | 0, | ||
2689 | NULL); | ||
2690 | break; | ||
2691 | case IPPROTO_ICMPV6: | ||
2692 | state = get_redirect_state (af, | ||
2693 | IPPROTO_ICMPV6, | ||
2694 | source_ip, | ||
2695 | 0, | ||
2696 | destination_ip, | ||
2697 | 0, | ||
2698 | NULL); | ||
2699 | break; | ||
2700 | case IPPROTO_UDP: | ||
2701 | state = get_redirect_state (af, | ||
2702 | IPPROTO_UDP, | ||
2703 | source_ip, | ||
2704 | source_port, | ||
2705 | destination_ip, | ||
2706 | destination_port, | ||
2707 | NULL); | ||
2708 | break; | ||
2709 | case IPPROTO_TCP: | ||
2710 | state = get_redirect_state (af, | ||
2711 | IPPROTO_TCP, | ||
2712 | source_ip, | ||
2713 | source_port, | ||
2714 | destination_ip, | ||
2715 | destination_port, | ||
2716 | NULL); | ||
2717 | break; | ||
2718 | default: | ||
2719 | GNUNET_STATISTICS_update (stats, | ||
2720 | gettext_noop ("# ICMP packets dropped (not allowed)"), | ||
2721 | 1, | ||
2722 | GNUNET_NO); | ||
2723 | return; | ||
2724 | } | ||
2725 | if (NULL == state) | ||
2726 | { | ||
2727 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2728 | _("ICMP Packet dropped, have no matching connection information\n")); | ||
2729 | return; | ||
2730 | } | ||
2731 | env = GNUNET_MQ_msg_extra (i2v, | ||
2732 | pktlen - sizeof (struct GNUNET_TUN_IcmpHeader), | ||
2733 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN); | ||
2734 | i2v->af = htonl (af); | ||
2735 | GNUNET_memcpy (&i2v->icmp_header, | ||
2736 | icmp, | ||
2737 | pktlen); | ||
2738 | send_packet_to_cadet_channel (state, | ||
2739 | env); | ||
2740 | } | ||
2741 | |||
2742 | |||
2743 | /** | ||
2744 | * @brief Handles an UDP packet received from the helper. | ||
2745 | * | ||
2746 | * @param udp A pointer to the Packet | ||
2747 | * @param pktlen number of bytes in 'udp' | ||
2748 | * @param af address family (AFINET or AF_INET6) | ||
2749 | * @param destination_ip destination IP-address of the IP packet (should | ||
2750 | * be our local address) | ||
2751 | * @param source_ip original source IP-address of the IP packet (should | ||
2752 | * be the original destination address) | ||
2753 | */ | ||
2754 | static void | ||
2755 | udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp, | ||
2756 | size_t pktlen, | ||
2757 | int af, | ||
2758 | const void *destination_ip, | ||
2759 | const void *source_ip) | ||
2760 | { | ||
2761 | struct ChannelState *state; | ||
2762 | struct GNUNET_MQ_Envelope *env; | ||
2763 | struct GNUNET_EXIT_UdpReplyMessage *urm; | ||
2764 | |||
2765 | { | ||
2766 | char sbuf[INET6_ADDRSTRLEN]; | ||
2767 | char dbuf[INET6_ADDRSTRLEN]; | ||
2768 | |||
3007 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2769 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3008 | "Received data from %s for forwarding to UDP %s:%u\n", | 2770 | "Received UDP packet going from %s:%u to %s:%u\n", |
3009 | GNUNET_i2s (&state->peer), | ||
3010 | inet_ntop (af, | 2771 | inet_ntop (af, |
3011 | &state->specifics.tcp_udp.ri.remote_address.address, | 2772 | source_ip, |
3012 | buf, sizeof (buf)), | 2773 | sbuf, sizeof (sbuf)), |
3013 | (unsigned int) ntohs (msg->destination_port)); | 2774 | (unsigned int) ntohs (udp->source_port), |
2775 | inet_ntop (af, | ||
2776 | destination_ip, | ||
2777 | dbuf, sizeof (dbuf)), | ||
2778 | (unsigned int) ntohs (udp->destination_port)); | ||
3014 | } | 2779 | } |
3015 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP; | 2780 | if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader)) |
3016 | state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port; | 2781 | { |
3017 | if (NULL == state->specifics.tcp_udp.heap_node) | 2782 | /* blame kernel */ |
3018 | setup_state_record (state); | 2783 | GNUNET_break (0); |
3019 | if (0 != ntohs (msg->source_port)) | 2784 | return; |
3020 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | 2785 | } |
3021 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 2786 | if (pktlen != ntohs (udp->len)) |
3022 | &state->specifics.tcp_udp.ri.local_address, | 2787 | { |
3023 | payload, pkt_len); | 2788 | /* blame kernel */ |
3024 | GNUNET_CADET_receive_done (channel); | 2789 | GNUNET_break (0); |
3025 | return GNUNET_YES; | 2790 | return; |
2791 | } | ||
2792 | state = get_redirect_state (af, | ||
2793 | IPPROTO_UDP, | ||
2794 | source_ip, | ||
2795 | ntohs (udp->source_port), | ||
2796 | destination_ip, | ||
2797 | ntohs (udp->destination_port), | ||
2798 | NULL); | ||
2799 | if (NULL == state) | ||
2800 | { | ||
2801 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2802 | _("UDP Packet dropped, have no matching connection information\n")); | ||
2803 | return; | ||
2804 | } | ||
2805 | env = GNUNET_MQ_msg_extra (urm, | ||
2806 | pktlen - sizeof (struct GNUNET_TUN_UdpHeader), | ||
2807 | GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY); | ||
2808 | urm->source_port = htons (0); | ||
2809 | urm->destination_port = htons (0); | ||
2810 | GNUNET_memcpy (&urm[1], | ||
2811 | &udp[1], | ||
2812 | pktlen - sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2813 | send_packet_to_cadet_channel (state, | ||
2814 | env); | ||
3026 | } | 2815 | } |
3027 | 2816 | ||
3028 | 2817 | ||
3029 | /** | 2818 | /** |
3030 | * Process a request via cadet to send a request to a UDP service | 2819 | * @brief Handles a TCP packet received from the helper. |
3031 | * offered by this system. | ||
3032 | * | 2820 | * |
3033 | * @param cls closure, NULL | 2821 | * @param tcp A pointer to the Packet |
3034 | * @param channel connection to the other end | 2822 | * @param pktlen the length of the packet, including its TCP header |
3035 | * @param channel_ctx pointer to our 'struct ChannelState *' | 2823 | * @param af address family (AFINET or AF_INET6) |
3036 | * @param message the actual message | 2824 | * @param destination_ip destination IP-address of the IP packet (should |
3037 | * @return #GNUNET_OK to keep the connection open, | 2825 | * be our local address) |
3038 | * #GNUNET_SYSERR to close it (signal serious error) | 2826 | * @param source_ip original source IP-address of the IP packet (should |
2827 | * be the original destination address) | ||
3039 | */ | 2828 | */ |
3040 | static int | 2829 | static void |
3041 | receive_udp_service (void *cls, | 2830 | tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, |
3042 | struct GNUNET_CADET_Channel *channel, | 2831 | size_t pktlen, |
3043 | void **channel_ctx, | 2832 | int af, |
3044 | const struct GNUNET_MessageHeader *message) | 2833 | const void *destination_ip, |
2834 | const void *source_ip) | ||
3045 | { | 2835 | { |
3046 | struct ChannelState *state = *channel_ctx; | 2836 | struct ChannelState *state; |
3047 | const struct GNUNET_EXIT_UdpServiceMessage *msg; | 2837 | char buf[pktlen] GNUNET_ALIGN; |
3048 | uint16_t pkt_len = ntohs (message->size); | 2838 | struct GNUNET_TUN_TcpHeader *mtcp; |
2839 | struct GNUNET_EXIT_TcpDataMessage *tdm; | ||
2840 | struct GNUNET_MQ_Envelope *env; | ||
2841 | size_t mlen; | ||
3049 | 2842 | ||
3050 | if (NULL == state->specifics.tcp_udp.serv) | ||
3051 | { | 2843 | { |
3052 | GNUNET_break_op (0); | 2844 | char sbuf[INET6_ADDRSTRLEN]; |
3053 | return GNUNET_SYSERR; | 2845 | char dbuf[INET6_ADDRSTRLEN]; |
2846 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2847 | "Received TCP packet with %u bytes going from %s:%u to %s:%u\n", | ||
2848 | (unsigned int) (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)), | ||
2849 | inet_ntop (af, | ||
2850 | source_ip, | ||
2851 | sbuf, sizeof (sbuf)), | ||
2852 | (unsigned int) ntohs (tcp->source_port), | ||
2853 | inet_ntop (af, | ||
2854 | destination_ip, | ||
2855 | dbuf, sizeof (dbuf)), | ||
2856 | (unsigned int) ntohs (tcp->destination_port)); | ||
3054 | } | 2857 | } |
2858 | if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
2859 | { | ||
2860 | /* blame kernel */ | ||
2861 | GNUNET_break (0); | ||
2862 | return; | ||
2863 | } | ||
2864 | state = get_redirect_state (af, | ||
2865 | IPPROTO_TCP, | ||
2866 | source_ip, | ||
2867 | ntohs (tcp->source_port), | ||
2868 | destination_ip, | ||
2869 | ntohs (tcp->destination_port), | ||
2870 | NULL); | ||
2871 | if (NULL == state) | ||
2872 | { | ||
2873 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2874 | _("TCP Packet dropped, have no matching connection information\n")); | ||
2875 | |||
2876 | return; | ||
2877 | } | ||
2878 | /* mug port numbers and crc to avoid information leakage; | ||
2879 | sender will need to lookup the correct values anyway */ | ||
2880 | GNUNET_memcpy (buf, tcp, pktlen); | ||
2881 | mtcp = (struct GNUNET_TUN_TcpHeader *) buf; | ||
2882 | mtcp->source_port = 0; | ||
2883 | mtcp->destination_port = 0; | ||
2884 | mtcp->crc = 0; | ||
2885 | |||
2886 | mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)); | ||
2887 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
2888 | { | ||
2889 | GNUNET_break (0); | ||
2890 | return; | ||
2891 | } | ||
2892 | env = GNUNET_MQ_msg_extra (tdm, | ||
2893 | pktlen - sizeof (struct GNUNET_TUN_TcpHeader), | ||
2894 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN); | ||
2895 | tdm->reserved = htonl (0); | ||
2896 | GNUNET_memcpy (&tdm->tcp_header, | ||
2897 | buf, | ||
2898 | pktlen); | ||
2899 | send_packet_to_cadet_channel (state, | ||
2900 | env); | ||
2901 | } | ||
2902 | |||
2903 | |||
2904 | /** | ||
2905 | * Receive packets from the helper-process | ||
2906 | * | ||
2907 | * @param cls unused | ||
2908 | * @param client unsued | ||
2909 | * @param message message received from helper | ||
2910 | */ | ||
2911 | static int | ||
2912 | message_token (void *cls GNUNET_UNUSED, | ||
2913 | void *client GNUNET_UNUSED, | ||
2914 | const struct GNUNET_MessageHeader *message) | ||
2915 | { | ||
2916 | const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun; | ||
2917 | size_t size; | ||
2918 | |||
2919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2920 | "Got %u-byte message of type %u from gnunet-helper-exit\n", | ||
2921 | ntohs (message->size), | ||
2922 | ntohs (message->type)); | ||
3055 | GNUNET_STATISTICS_update (stats, | 2923 | GNUNET_STATISTICS_update (stats, |
3056 | gettext_noop ("# Bytes received from CADET"), | 2924 | gettext_noop ("# Packets received from TUN"), |
3057 | pkt_len, GNUNET_NO); | ||
3058 | GNUNET_STATISTICS_update (stats, | ||
3059 | gettext_noop ("# UDP service requests received via cadet"), | ||
3060 | 1, GNUNET_NO); | 2925 | 1, GNUNET_NO); |
3061 | /* check that we got at least a valid header */ | 2926 | if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) |
3062 | if (pkt_len < sizeof (struct GNUNET_EXIT_UdpServiceMessage)) | ||
3063 | { | 2927 | { |
3064 | GNUNET_break_op (0); | 2928 | GNUNET_break (0); |
3065 | return GNUNET_SYSERR; | 2929 | return GNUNET_OK; |
3066 | } | 2930 | } |
3067 | msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message; | 2931 | size = ntohs (message->size); |
3068 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage); | 2932 | if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader)) |
3069 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2933 | { |
3070 | "Received data from %s for forwarding to UDP service %s on port %u\n", | 2934 | GNUNET_break (0); |
3071 | GNUNET_i2s (&state->peer), | 2935 | return GNUNET_OK; |
3072 | GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor), | 2936 | } |
3073 | (unsigned int) ntohs (msg->destination_port)); | 2937 | GNUNET_STATISTICS_update (stats, |
3074 | setup_state_record (state); | 2938 | gettext_noop ("# Bytes received from TUN"), |
3075 | if (0 != ntohs (msg->source_port)) | 2939 | size, GNUNET_NO); |
3076 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | 2940 | pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1]; |
3077 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 2941 | size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader); |
3078 | &state->specifics.tcp_udp.ri.local_address, | 2942 | switch (ntohs (pkt_tun->proto)) |
3079 | &msg[1], | 2943 | { |
3080 | pkt_len); | 2944 | case ETH_P_IPV4: |
3081 | GNUNET_CADET_receive_done (channel); | 2945 | { |
3082 | return GNUNET_YES; | 2946 | const struct GNUNET_TUN_IPv4Header *pkt4; |
2947 | |||
2948 | if (size < sizeof (struct GNUNET_TUN_IPv4Header)) | ||
2949 | { | ||
2950 | /* Kernel to blame? */ | ||
2951 | GNUNET_break (0); | ||
2952 | return GNUNET_OK; | ||
2953 | } | ||
2954 | pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1]; | ||
2955 | if (size != ntohs (pkt4->total_length)) | ||
2956 | { | ||
2957 | /* Kernel to blame? */ | ||
2958 | GNUNET_break (0); | ||
2959 | return GNUNET_OK; | ||
2960 | } | ||
2961 | if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header)) | ||
2962 | { | ||
2963 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2964 | _("IPv4 packet options received. Ignored.\n")); | ||
2965 | return GNUNET_OK; | ||
2966 | } | ||
2967 | |||
2968 | size -= sizeof (struct GNUNET_TUN_IPv4Header); | ||
2969 | switch (pkt4->protocol) | ||
2970 | { | ||
2971 | case IPPROTO_UDP: | ||
2972 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size, | ||
2973 | AF_INET, | ||
2974 | &pkt4->destination_address, | ||
2975 | &pkt4->source_address); | ||
2976 | break; | ||
2977 | case IPPROTO_TCP: | ||
2978 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size, | ||
2979 | AF_INET, | ||
2980 | &pkt4->destination_address, | ||
2981 | &pkt4->source_address); | ||
2982 | break; | ||
2983 | case IPPROTO_ICMP: | ||
2984 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size, | ||
2985 | AF_INET, | ||
2986 | &pkt4->destination_address, | ||
2987 | &pkt4->source_address); | ||
2988 | break; | ||
2989 | default: | ||
2990 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2991 | _("IPv4 packet with unsupported next header %u received. Ignored.\n"), | ||
2992 | (int) pkt4->protocol); | ||
2993 | return GNUNET_OK; | ||
2994 | } | ||
2995 | } | ||
2996 | break; | ||
2997 | case ETH_P_IPV6: | ||
2998 | { | ||
2999 | const struct GNUNET_TUN_IPv6Header *pkt6; | ||
3000 | |||
3001 | if (size < sizeof (struct GNUNET_TUN_IPv6Header)) | ||
3002 | { | ||
3003 | /* Kernel to blame? */ | ||
3004 | GNUNET_break (0); | ||
3005 | return GNUNET_OK; | ||
3006 | } | ||
3007 | pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1]; | ||
3008 | if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header)) | ||
3009 | { | ||
3010 | /* Kernel to blame? */ | ||
3011 | GNUNET_break (0); | ||
3012 | return GNUNET_OK; | ||
3013 | } | ||
3014 | size -= sizeof (struct GNUNET_TUN_IPv6Header); | ||
3015 | switch (pkt6->next_header) | ||
3016 | { | ||
3017 | case IPPROTO_UDP: | ||
3018 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size, | ||
3019 | AF_INET6, | ||
3020 | &pkt6->destination_address, | ||
3021 | &pkt6->source_address); | ||
3022 | break; | ||
3023 | case IPPROTO_TCP: | ||
3024 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size, | ||
3025 | AF_INET6, | ||
3026 | &pkt6->destination_address, | ||
3027 | &pkt6->source_address); | ||
3028 | break; | ||
3029 | case IPPROTO_ICMPV6: | ||
3030 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size, | ||
3031 | AF_INET6, | ||
3032 | &pkt6->destination_address, | ||
3033 | &pkt6->source_address); | ||
3034 | break; | ||
3035 | default: | ||
3036 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3037 | _("IPv6 packet with unsupported next header %d received. Ignored.\n"), | ||
3038 | pkt6->next_header); | ||
3039 | return GNUNET_OK; | ||
3040 | } | ||
3041 | } | ||
3042 | break; | ||
3043 | default: | ||
3044 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3045 | _("Packet from unknown protocol %u received. Ignored.\n"), | ||
3046 | ntohs (pkt_tun->proto)); | ||
3047 | break; | ||
3048 | } | ||
3049 | return GNUNET_OK; | ||
3083 | } | 3050 | } |
3084 | 3051 | ||
3085 | 3052 | ||
@@ -3089,16 +3056,12 @@ receive_udp_service (void *cls, | |||
3089 | * @param cls closure | 3056 | * @param cls closure |
3090 | * @param channel new handle to the channel | 3057 | * @param channel new handle to the channel |
3091 | * @param initiator peer that started the channel | 3058 | * @param initiator peer that started the channel |
3092 | * @param port destination port | ||
3093 | * @param options channel options flags | ||
3094 | * @return initial channel context for the channel | 3059 | * @return initial channel context for the channel |
3095 | */ | 3060 | */ |
3096 | static void * | 3061 | static void * |
3097 | new_channel (void *cls, | 3062 | new_channel (void *cls, |
3098 | struct GNUNET_CADET_Channel *channel, | 3063 | struct GNUNET_CADET_Channel *channel, |
3099 | const struct GNUNET_PeerIdentity *initiator, | 3064 | const struct GNUNET_PeerIdentity *initiator) |
3100 | const struct GNUNET_HashCode *port, | ||
3101 | enum GNUNET_CADET_ChannelOption options) | ||
3102 | { | 3065 | { |
3103 | struct ChannelState *s = GNUNET_new (struct ChannelState); | 3066 | struct ChannelState *s = GNUNET_new (struct ChannelState); |
3104 | 3067 | ||
@@ -3106,7 +3069,8 @@ new_channel (void *cls, | |||
3106 | s->peer = *initiator; | 3069 | s->peer = *initiator; |
3107 | GNUNET_STATISTICS_update (stats, | 3070 | GNUNET_STATISTICS_update (stats, |
3108 | gettext_noop ("# Inbound CADET channels created"), | 3071 | gettext_noop ("# Inbound CADET channels created"), |
3109 | 1, GNUNET_NO); | 3072 | 1, |
3073 | GNUNET_NO); | ||
3110 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3074 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3111 | "Received inbound channel from `%s'\n", | 3075 | "Received inbound channel from `%s'\n", |
3112 | GNUNET_i2s (initiator)); | 3076 | GNUNET_i2s (initiator)); |
@@ -3116,64 +3080,6 @@ new_channel (void *cls, | |||
3116 | 3080 | ||
3117 | 3081 | ||
3118 | /** | 3082 | /** |
3119 | * Function called by cadet whenever an inbound channel is destroyed. | ||
3120 | * Should clean up any associated state. | ||
3121 | * | ||
3122 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
3123 | * @param channel connection to the other end (henceforth invalid) | ||
3124 | * @param channel_ctx place where local state associated | ||
3125 | * with the channel is stored | ||
3126 | */ | ||
3127 | static void | ||
3128 | clean_channel (void *cls, | ||
3129 | const struct GNUNET_CADET_Channel *channel, | ||
3130 | void *channel_ctx) | ||
3131 | { | ||
3132 | struct ChannelState *s = channel_ctx; | ||
3133 | struct ChannelMessageQueue *tnq; | ||
3134 | |||
3135 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3136 | "Channel destroyed\n"); | ||
3137 | if (GNUNET_SYSERR == s->is_dns) | ||
3138 | { | ||
3139 | GNUNET_free (s); | ||
3140 | return; | ||
3141 | } | ||
3142 | if (GNUNET_YES == s->is_dns) | ||
3143 | { | ||
3144 | if (channels[s->specifics.dns.my_id] == s) | ||
3145 | channels[s->specifics.dns.my_id] = NULL; | ||
3146 | GNUNET_free_non_null (s->specifics.dns.reply); | ||
3147 | } | ||
3148 | else | ||
3149 | { | ||
3150 | while (NULL != (tnq = s->specifics.tcp_udp.head)) | ||
3151 | { | ||
3152 | GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head, | ||
3153 | s->specifics.tcp_udp.tail, | ||
3154 | tnq); | ||
3155 | GNUNET_free (tnq); | ||
3156 | } | ||
3157 | if (NULL != s->specifics.tcp_udp.heap_node) | ||
3158 | { | ||
3159 | GNUNET_assert (GNUNET_YES == | ||
3160 | GNUNET_CONTAINER_multihashmap_remove (connections_map, | ||
3161 | &s->specifics.tcp_udp.state_key, | ||
3162 | s)); | ||
3163 | GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node); | ||
3164 | s->specifics.tcp_udp.heap_node = NULL; | ||
3165 | } | ||
3166 | } | ||
3167 | if (NULL != s->th) | ||
3168 | { | ||
3169 | GNUNET_CADET_notify_transmit_ready_cancel (s->th); | ||
3170 | s->th = NULL; | ||
3171 | } | ||
3172 | GNUNET_free (s); | ||
3173 | } | ||
3174 | |||
3175 | |||
3176 | /** | ||
3177 | * Function that frees everything from a hashmap | 3083 | * Function that frees everything from a hashmap |
3178 | * | 3084 | * |
3179 | * @param cls unused | 3085 | * @param cls unused |
@@ -3241,6 +3147,21 @@ cleanup (void *cls) | |||
3241 | NULL); | 3147 | NULL); |
3242 | GNUNET_CONTAINER_multihashmap_destroy (services); | 3148 | GNUNET_CONTAINER_multihashmap_destroy (services); |
3243 | } | 3149 | } |
3150 | if (NULL != dns_port) | ||
3151 | { | ||
3152 | GNUNET_CADET_close_port (dns_port); | ||
3153 | dns_port = NULL; | ||
3154 | } | ||
3155 | if (NULL != cadet_port4) | ||
3156 | { | ||
3157 | GNUNET_CADET_close_port (cadet_port4); | ||
3158 | cadet_port4 = NULL; | ||
3159 | } | ||
3160 | if (NULL != cadet_port6) | ||
3161 | { | ||
3162 | GNUNET_CADET_close_port (cadet_port6); | ||
3163 | cadet_port6 = NULL; | ||
3164 | } | ||
3244 | if (NULL != cadet_handle) | 3165 | if (NULL != cadet_handle) |
3245 | { | 3166 | { |
3246 | GNUNET_CADET_disconnect (cadet_handle); | 3167 | GNUNET_CADET_disconnect (cadet_handle); |
@@ -3286,7 +3207,8 @@ cleanup (void *cls) | |||
3286 | } | 3207 | } |
3287 | if (NULL != stats) | 3208 | if (NULL != stats) |
3288 | { | 3209 | { |
3289 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 3210 | GNUNET_STATISTICS_destroy (stats, |
3211 | GNUNET_NO); | ||
3290 | stats = NULL; | 3212 | stats = NULL; |
3291 | } | 3213 | } |
3292 | for (i=0;i<8;i++) | 3214 | for (i=0;i<8;i++) |
@@ -3614,6 +3536,13 @@ parse_ip_options () | |||
3614 | static void | 3536 | static void |
3615 | advertise_dns_exit () | 3537 | advertise_dns_exit () |
3616 | { | 3538 | { |
3539 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
3540 | GNUNET_MQ_hd_var_size (dns_request, | ||
3541 | GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, | ||
3542 | struct DnsResponseMessage, | ||
3543 | NULL), | ||
3544 | GNUNET_MQ_handler_end () | ||
3545 | }; | ||
3617 | char *dns_exit; | 3546 | char *dns_exit; |
3618 | struct GNUNET_HashCode port; | 3547 | struct GNUNET_HashCode port; |
3619 | struct in_addr dns_exit4; | 3548 | struct in_addr dns_exit4; |
@@ -3650,10 +3579,13 @@ advertise_dns_exit () | |||
3650 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3579 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3651 | "Opening CADET port %s for DNS exit service\n", | 3580 | "Opening CADET port %s for DNS exit service\n", |
3652 | GNUNET_h2s (&port)); | 3581 | GNUNET_h2s (&port)); |
3653 | GNUNET_CADET_open_port (cadet_handle, | 3582 | dns_port = GNUNET_CADET_open_porT (cadet_handle, |
3654 | &port, | 3583 | &port, |
3655 | &new_channel, | 3584 | &new_channel, |
3656 | NULL); | 3585 | NULL, |
3586 | NULL, | ||
3587 | &clean_channel, | ||
3588 | handlers); | ||
3657 | /* advertise exit */ | 3589 | /* advertise exit */ |
3658 | dht = GNUNET_DHT_connect (cfg, | 3590 | dht = GNUNET_DHT_connect (cfg, |
3659 | 1); | 3591 | 1); |
@@ -3833,16 +3765,24 @@ run (void *cls, | |||
3833 | const char *cfgfile, | 3765 | const char *cfgfile, |
3834 | const struct GNUNET_CONFIGURATION_Handle *cfg_) | 3766 | const struct GNUNET_CONFIGURATION_Handle *cfg_) |
3835 | { | 3767 | { |
3836 | static struct GNUNET_CADET_MessageHandler handlers[] = { | 3768 | struct GNUNET_MQ_MessageHandler handlers[] = { |
3837 | {&receive_icmp_service, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, 0}, | 3769 | GNUNET_MQ_hd_var_size (icmp_remote, |
3838 | {&receive_icmp_remote, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, 0}, | 3770 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, |
3839 | {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0}, | 3771 | struct GNUNET_EXIT_IcmpInternetMessage, |
3840 | {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0}, | 3772 | NULL), |
3841 | {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0}, | 3773 | GNUNET_MQ_hd_var_size (udp_remote, |
3842 | {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0}, | 3774 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, |
3843 | {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0}, | 3775 | struct GNUNET_EXIT_UdpInternetMessage, |
3844 | {&receive_dns_request, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, 0}, | 3776 | NULL), |
3845 | {NULL, 0, 0} | 3777 | GNUNET_MQ_hd_var_size (tcp_remote, |
3778 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, | ||
3779 | struct GNUNET_EXIT_TcpInternetStartMessage, | ||
3780 | NULL), | ||
3781 | GNUNET_MQ_hd_var_size (tcp_data, | ||
3782 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, | ||
3783 | struct GNUNET_EXIT_TcpDataMessage, | ||
3784 | NULL), | ||
3785 | GNUNET_MQ_handler_end () | ||
3846 | }; | 3786 | }; |
3847 | struct GNUNET_HashCode port; | 3787 | struct GNUNET_HashCode port; |
3848 | char *policy; | 3788 | char *policy; |
@@ -3889,10 +3829,7 @@ run (void *cls, | |||
3889 | NULL); | 3829 | NULL); |
3890 | stats = GNUNET_STATISTICS_create ("exit", | 3830 | stats = GNUNET_STATISTICS_create ("exit", |
3891 | cfg); | 3831 | cfg); |
3892 | cadet_handle = GNUNET_CADET_connect (cfg, | 3832 | cadet_handle = GNUNET_CADET_connecT (cfg); |
3893 | NULL, | ||
3894 | &clean_channel, | ||
3895 | handlers); | ||
3896 | if (NULL == cadet_handle) | 3833 | if (NULL == cadet_handle) |
3897 | { | 3834 | { |
3898 | GNUNET_SCHEDULER_shutdown (); | 3835 | GNUNET_SCHEDULER_shutdown (); |
@@ -3925,10 +3862,13 @@ run (void *cls, | |||
3925 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3862 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3926 | "Opening CADET port %s for IPv4 gateway service\n", | 3863 | "Opening CADET port %s for IPv4 gateway service\n", |
3927 | GNUNET_h2s (&port)); | 3864 | GNUNET_h2s (&port)); |
3928 | GNUNET_CADET_open_port (cadet_handle, | 3865 | cadet_port4 = GNUNET_CADET_open_porT (cadet_handle, |
3929 | &port, | 3866 | &port, |
3930 | &new_channel, | 3867 | &new_channel, |
3931 | NULL); | 3868 | NULL, |
3869 | NULL, | ||
3870 | &clean_channel, | ||
3871 | handlers); | ||
3932 | policy = NULL; | 3872 | policy = NULL; |
3933 | if (GNUNET_OK != | 3873 | if (GNUNET_OK != |
3934 | GNUNET_CONFIGURATION_get_value_string (cfg, | 3874 | GNUNET_CONFIGURATION_get_value_string (cfg, |
@@ -3962,10 +3902,13 @@ run (void *cls, | |||
3962 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3902 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3963 | "Opening CADET port %s for IPv6 gateway service\n", | 3903 | "Opening CADET port %s for IPv6 gateway service\n", |
3964 | GNUNET_h2s (&port)); | 3904 | GNUNET_h2s (&port)); |
3965 | GNUNET_CADET_open_port (cadet_handle, | 3905 | cadet_port6 = GNUNET_CADET_open_porT (cadet_handle, |
3966 | &port, | 3906 | &port, |
3967 | &new_channel, | 3907 | &new_channel, |
3968 | NULL); | 3908 | NULL, |
3909 | NULL, | ||
3910 | &clean_channel, | ||
3911 | handlers); | ||
3969 | policy = NULL; | 3912 | policy = NULL; |
3970 | if (GNUNET_OK != | 3913 | if (GNUNET_OK != |
3971 | GNUNET_CONFIGURATION_get_value_string (cfg, | 3914 | GNUNET_CONFIGURATION_get_value_string (cfg, |
diff --git a/src/fs/fs.conf.in b/src/fs/fs.conf.in index 3534378ae..d46de387f 100644 --- a/src/fs/fs.conf.in +++ b/src/fs/fs.conf.in | |||
@@ -36,7 +36,7 @@ MAX_PENDING_REQUESTS = 65536 | |||
36 | 36 | ||
37 | # How many requests do we have at most waiting in the queue towards | 37 | # How many requests do we have at most waiting in the queue towards |
38 | # the datastore? (important for memory consumption) | 38 | # the datastore? (important for memory consumption) |
39 | DATASTORE_QUEUE_SIZE = 1024 | 39 | DATASTORE_QUEUE_SIZE = 32 |
40 | 40 | ||
41 | # Maximum frequency we're allowed to poll the datastore | 41 | # Maximum frequency we're allowed to poll the datastore |
42 | # for content for migration (can be used to reduce | 42 | # for content for migration (can be used to reduce |
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index 8c605c6a2..256d0c2b8 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -1349,7 +1349,7 @@ run (void *cls, | |||
1349 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO, | 1349 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO, |
1350 | "fs", | 1350 | "fs", |
1351 | "DATASTORE_QUEUE_SIZE"); | 1351 | "DATASTORE_QUEUE_SIZE"); |
1352 | dqs = 1024; | 1352 | dqs = 32; |
1353 | } | 1353 | } |
1354 | GSF_datastore_queue_size = (unsigned int) dqs; | 1354 | GSF_datastore_queue_size = (unsigned int) dqs; |
1355 | GSF_enable_randomized_delays = | 1355 | GSF_enable_randomized_delays = |
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 8c952be04..464bbbca1 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am | |||
@@ -69,8 +69,8 @@ endif | |||
69 | 69 | ||
70 | libexec_PROGRAMS = \ | 70 | libexec_PROGRAMS = \ |
71 | gnunet-service-gns \ | 71 | gnunet-service-gns \ |
72 | $(DO_W32_HELPER) \ | ||
73 | gnunet-dns2gns \ | 72 | gnunet-dns2gns \ |
73 | $(DO_W32_HELPER) \ | ||
74 | $(DO_PROXY) | 74 | $(DO_PROXY) |
75 | 75 | ||
76 | bin_PROGRAMS = \ | 76 | bin_PROGRAMS = \ |
@@ -136,6 +136,14 @@ gnunet_dns2gns_LDADD = \ | |||
136 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ | 136 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ |
137 | $(GN_LIBINTL) | 137 | $(GN_LIBINTL) |
138 | 138 | ||
139 | if LINUX | ||
140 | HIJACKBIN = gnunet-dns2gns | ||
141 | install-exec-hook: | ||
142 | $(SUDO_BINARY) setcap 'cap_net_bind_service=+ep' $(DESTDIR)$(libexecdir)/gnunet-dns2gns || true | ||
143 | else | ||
144 | install-exec-hook: | ||
145 | endif | ||
146 | |||
139 | gnunet_gns_proxy_SOURCES = \ | 147 | gnunet_gns_proxy_SOURCES = \ |
140 | gnunet-gns-proxy.c | 148 | gnunet-gns-proxy.c |
141 | gnunet_gns_proxy_CPPFLAGS = $(AM_CPPFLAGS) $(CPP_GNURL) | 149 | gnunet_gns_proxy_CPPFLAGS = $(AM_CPPFLAGS) $(CPP_GNURL) |
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c index bb37a42a3..813ecdf8e 100644 --- a/src/gns/gnunet-dns2gns.c +++ b/src/gns/gnunet-dns2gns.c | |||
@@ -138,7 +138,7 @@ static char *dns_ip; | |||
138 | /** | 138 | /** |
139 | * UDP Port we listen on for inbound DNS requests. | 139 | * UDP Port we listen on for inbound DNS requests. |
140 | */ | 140 | */ |
141 | static unsigned int listen_port = 2853; | 141 | static unsigned int listen_port = 53; |
142 | 142 | ||
143 | /** | 143 | /** |
144 | * Which GNS zone do we translate incoming DNS requests to? | 144 | * Which GNS zone do we translate incoming DNS requests to? |
@@ -796,13 +796,17 @@ main (int argc, | |||
796 | }; | 796 | }; |
797 | int ret; | 797 | int ret; |
798 | 798 | ||
799 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, | 799 | if (GNUNET_OK != |
800 | &argc, &argv)) | 800 | GNUNET_STRINGS_get_utf8_args (argc, argv, |
801 | &argc, &argv)) | ||
801 | return 2; | 802 | return 2; |
802 | GNUNET_log_setup ("gnunet-dns2gns", "WARNING", NULL); | 803 | GNUNET_log_setup ("gnunet-dns2gns", |
804 | "WARNING", | ||
805 | NULL); | ||
803 | ret = | 806 | ret = |
804 | (GNUNET_OK == | 807 | (GNUNET_OK == |
805 | GNUNET_PROGRAM_run (argc, argv, "gnunet-dns2gns", | 808 | GNUNET_PROGRAM_run (argc, argv, |
809 | "gnunet-dns2gns", | ||
806 | _("GNUnet DNS-to-GNS proxy (a DNS server)"), | 810 | _("GNUnet DNS-to-GNS proxy (a DNS server)"), |
807 | options, | 811 | options, |
808 | &run, NULL)) ? 0 : 1; | 812 | &run, NULL)) ? 0 : 1; |
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 570c07fdf..0ca25ac19 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -328,11 +328,12 @@ handle_lookup (void *cls, | |||
328 | char *nameptr = name; | 328 | char *nameptr = name; |
329 | const char *utf_in; | 329 | const char *utf_in; |
330 | 330 | ||
331 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
332 | "Received LOOKUP message\n"); | ||
333 | GNUNET_SERVICE_client_continue (gc->client); | 331 | GNUNET_SERVICE_client_continue (gc->client); |
334 | utf_in = (const char *) &sh_msg[1]; | 332 | utf_in = (const char *) &sh_msg[1]; |
335 | GNUNET_STRINGS_utf8_tolower (utf_in, nameptr); | 333 | GNUNET_STRINGS_utf8_tolower (utf_in, nameptr); |
334 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
335 | "Received LOOKUP `%s' message\n", | ||
336 | name); | ||
336 | 337 | ||
337 | clh = GNUNET_new (struct ClientLookupHandle); | 338 | clh = GNUNET_new (struct ClientLookupHandle); |
338 | GNUNET_CONTAINER_DLL_insert (gc->clh_head, | 339 | GNUNET_CONTAINER_DLL_insert (gc->clh_head, |
diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c index f632aa0a8..8c8485249 100644 --- a/src/identity/gnunet-identity.c +++ b/src/identity/gnunet-identity.c | |||
@@ -29,6 +29,12 @@ | |||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_identity_service.h" | 30 | #include "gnunet_identity_service.h" |
31 | 31 | ||
32 | |||
33 | /** | ||
34 | * Return value from main on timeout. | ||
35 | */ | ||
36 | #define TIMEOUT_STATUS_CODE 40 | ||
37 | |||
32 | /** | 38 | /** |
33 | * Handle to IDENTITY service. | 39 | * Handle to IDENTITY service. |
34 | */ | 40 | */ |
@@ -79,6 +85,11 @@ static struct GNUNET_IDENTITY_Operation *create_op; | |||
79 | */ | 85 | */ |
80 | static struct GNUNET_IDENTITY_Operation *delete_op; | 86 | static struct GNUNET_IDENTITY_Operation *delete_op; |
81 | 87 | ||
88 | /** | ||
89 | * Value to return from #main(). | ||
90 | */ | ||
91 | static int global_ret; | ||
92 | |||
82 | 93 | ||
83 | /** | 94 | /** |
84 | * Task run on shutdown. | 95 | * Task run on shutdown. |
@@ -120,7 +131,11 @@ test_finished () | |||
120 | (NULL == set_ego) && | 131 | (NULL == set_ego) && |
121 | (! list) && | 132 | (! list) && |
122 | (! monitor) ) | 133 | (! monitor) ) |
134 | { | ||
135 | if (TIMEOUT_STATUS_CODE == global_ret) | ||
136 | global_ret = 0; | ||
123 | GNUNET_SCHEDULER_shutdown (); | 137 | GNUNET_SCHEDULER_shutdown (); |
138 | } | ||
124 | } | 139 | } |
125 | 140 | ||
126 | 141 | ||
@@ -159,9 +174,12 @@ create_finished (void *cls, | |||
159 | 174 | ||
160 | *op = NULL; | 175 | *op = NULL; |
161 | if (NULL != emsg) | 176 | if (NULL != emsg) |
177 | { | ||
162 | fprintf (stderr, | 178 | fprintf (stderr, |
163 | _("Failed to create ego: %s\n"), | 179 | _("Failed to create ego: %s\n"), |
164 | emsg); | 180 | emsg); |
181 | global_ret = 1; | ||
182 | } | ||
165 | test_finished (); | 183 | test_finished (); |
166 | } | 184 | } |
167 | 185 | ||
@@ -178,9 +196,12 @@ set_done (void *cls, | |||
178 | { | 196 | { |
179 | set_op = NULL; | 197 | set_op = NULL; |
180 | if (NULL != emsg) | 198 | if (NULL != emsg) |
199 | { | ||
181 | fprintf (stderr, | 200 | fprintf (stderr, |
182 | _("Failed to set default ego: %s\n"), | 201 | _("Failed to set default ego: %s\n"), |
183 | emsg); | 202 | emsg); |
203 | global_ret = 1; | ||
204 | } | ||
184 | test_finished (); | 205 | test_finished (); |
185 | } | 206 | } |
186 | 207 | ||
@@ -257,17 +278,23 @@ print_ego (void *cls, | |||
257 | } | 278 | } |
258 | if ( (NULL == ego) && (! monitor) ) | 279 | if ( (NULL == ego) && (! monitor) ) |
259 | { | 280 | { |
260 | GNUNET_SCHEDULER_shutdown (); | 281 | list = 0; |
282 | test_finished (); | ||
261 | return; | 283 | return; |
262 | } | 284 | } |
263 | if (! (list | monitor)) | 285 | if (! (list | monitor)) |
264 | return; | 286 | return; |
265 | if (NULL == ego) | 287 | if (NULL == ego) |
266 | return; | 288 | return; |
267 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | 289 | GNUNET_IDENTITY_ego_get_public_key (ego, |
290 | &pk); | ||
268 | s = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | 291 | s = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); |
269 | if ( (monitor) || (NULL != identifier) ) | 292 | if ( (monitor) || |
270 | fprintf (stdout, "%s - %s\n", identifier, s); | 293 | (NULL != identifier) ) |
294 | fprintf (stdout, | ||
295 | "%s - %s\n", | ||
296 | identifier, | ||
297 | s); | ||
271 | GNUNET_free (s); | 298 | GNUNET_free (s); |
272 | } | 299 | } |
273 | 300 | ||
@@ -281,7 +308,9 @@ print_ego (void *cls, | |||
281 | * @param cfg configuration | 308 | * @param cfg configuration |
282 | */ | 309 | */ |
283 | static void | 310 | static void |
284 | run (void *cls, char *const *args, const char *cfgfile, | 311 | run (void *cls, |
312 | char *const *args, | ||
313 | const char *cfgfile, | ||
285 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 314 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
286 | { | 315 | { |
287 | if ( (NULL == set_subsystem) ^ | 316 | if ( (NULL == set_subsystem) ^ |
@@ -291,7 +320,9 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
291 | "Options -e and -s must always be specified together\n"); | 320 | "Options -e and -s must always be specified together\n"); |
292 | return; | 321 | return; |
293 | } | 322 | } |
294 | sh = GNUNET_IDENTITY_connect (cfg, &print_ego, NULL); | 323 | sh = GNUNET_IDENTITY_connect (cfg, |
324 | &print_ego, | ||
325 | NULL); | ||
295 | if (NULL != delete_ego) | 326 | if (NULL != delete_ego) |
296 | delete_op = GNUNET_IDENTITY_delete (sh, | 327 | delete_op = GNUNET_IDENTITY_delete (sh, |
297 | delete_ego, | 328 | delete_ego, |
@@ -302,7 +333,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
302 | create_ego, | 333 | create_ego, |
303 | &create_finished, | 334 | &create_finished, |
304 | &create_op); | 335 | &create_op); |
305 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | 336 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
337 | NULL); | ||
306 | test_finished (); | 338 | test_finished (); |
307 | } | 339 | } |
308 | 340 | ||
@@ -317,8 +349,6 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
317 | int | 349 | int |
318 | main (int argc, char *const *argv) | 350 | main (int argc, char *const *argv) |
319 | { | 351 | { |
320 | int res; | ||
321 | |||
322 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | 352 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { |
323 | {'C', "create", "NAME", | 353 | {'C', "create", "NAME", |
324 | gettext_noop ("create ego NAME"), | 354 | gettext_noop ("create ego NAME"), |
@@ -340,19 +370,23 @@ main (int argc, char *const *argv) | |||
340 | 1, &GNUNET_GETOPT_set_string, &set_subsystem}, | 370 | 1, &GNUNET_GETOPT_set_string, &set_subsystem}, |
341 | GNUNET_GETOPT_OPTION_END | 371 | GNUNET_GETOPT_OPTION_END |
342 | }; | 372 | }; |
373 | int res; | ||
343 | 374 | ||
344 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 375 | if (GNUNET_OK != |
345 | return 2; | 376 | GNUNET_STRINGS_get_utf8_args (argc, argv, |
346 | 377 | &argc, &argv)) | |
347 | res = GNUNET_PROGRAM_run (argc, argv, "gnunet-identity", | 378 | return 4; |
379 | global_ret = TIMEOUT_STATUS_CODE; /* timeout */ | ||
380 | res = GNUNET_PROGRAM_run (argc, argv, | ||
381 | "gnunet-identity", | ||
348 | gettext_noop ("Maintain egos"), | 382 | gettext_noop ("Maintain egos"), |
349 | options, &run, | 383 | options, &run, |
350 | NULL); | 384 | NULL); |
351 | GNUNET_free ((void *) argv); | 385 | GNUNET_free ((void *) argv); |
352 | 386 | ||
353 | if (GNUNET_OK != res) | 387 | if (GNUNET_OK != res) |
354 | return 1; | 388 | return 3; |
355 | return 0; | 389 | return global_ret; |
356 | } | 390 | } |
357 | 391 | ||
358 | /* end of gnunet-identity.c */ | 392 | /* end of gnunet-identity.c */ |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index eeb9a8a92..8822a6302 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -1640,6 +1640,12 @@ extern "C" | |||
1640 | * Demand the whole element from the other | 1640 | * Demand the whole element from the other |
1641 | * peer, given only the hash code. | 1641 | * peer, given only the hash code. |
1642 | */ | 1642 | */ |
1643 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL 565 | ||
1644 | |||
1645 | /** | ||
1646 | * Demand the whole element from the other | ||
1647 | * peer, given only the hash code. | ||
1648 | */ | ||
1643 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND 566 | 1649 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND 566 |
1644 | 1650 | ||
1645 | /** | 1651 | /** |
@@ -1795,6 +1801,19 @@ extern "C" | |||
1795 | */ | 1801 | */ |
1796 | #define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT 596 | 1802 | #define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT 596 |
1797 | 1803 | ||
1804 | /** | ||
1805 | * Request all missing elements from the other peer, | ||
1806 | * based on their sets and the elements we previously sent | ||
1807 | * with #GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS. | ||
1808 | */ | ||
1809 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE 597 | ||
1810 | |||
1811 | /** | ||
1812 | * Send a set element, not as response to a demand but because | ||
1813 | * we're sending the full set. | ||
1814 | */ | ||
1815 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT 598 | ||
1816 | |||
1798 | 1817 | ||
1799 | /******************************************************************************* | 1818 | /******************************************************************************* |
1800 | * TESTBED LOGGER message types | 1819 | * TESTBED LOGGER message types |
diff --git a/src/include/gnunet_set_service.h b/src/include/gnunet_set_service.h index 52613ad59..f9b477f47 100644 --- a/src/include/gnunet_set_service.h +++ b/src/include/gnunet_set_service.h | |||
@@ -153,6 +153,7 @@ enum GNUNET_SET_Status | |||
153 | }; | 153 | }; |
154 | 154 | ||
155 | 155 | ||
156 | |||
156 | /** | 157 | /** |
157 | * The way results are given to the client. | 158 | * The way results are given to the client. |
158 | */ | 159 | */ |
@@ -212,6 +213,54 @@ struct GNUNET_SET_Element | |||
212 | 213 | ||
213 | 214 | ||
214 | /** | 215 | /** |
216 | * Possible options to pass to a set operation. | ||
217 | * | ||
218 | * Used as tag for struct #GNUNET_SET_Option. | ||
219 | */ | ||
220 | enum GNUNET_SET_OptionType | ||
221 | { | ||
222 | /** | ||
223 | * Fail set operations when the other peer shows weird behavior | ||
224 | * that might by a Byzantine fault. | ||
225 | * | ||
226 | * For set union, 'v.num' is a lower bound on elements | ||
227 | * that the other peer must have in common with us. | ||
228 | */ | ||
229 | GNUNET_SET_OPTION_BYZANTINE=1, | ||
230 | /** | ||
231 | * Do not use the optimized set operation, but send full sets. | ||
232 | * Might trigger Byzantine fault detection. | ||
233 | */ | ||
234 | GNUNET_SET_OPTION_FORCE_FULL=2, | ||
235 | /** | ||
236 | * Only use optimized set operations, even though for this | ||
237 | * particular set operation they might be much slower. | ||
238 | * Might trigger Byzantine fault detection. | ||
239 | */ | ||
240 | GNUNET_SET_OPTION_FORCE_DELTA=4, | ||
241 | }; | ||
242 | |||
243 | |||
244 | /** | ||
245 | * Option for set operations. | ||
246 | */ | ||
247 | struct GNUNET_SET_Option | ||
248 | { | ||
249 | /** | ||
250 | * Type of the option. | ||
251 | */ | ||
252 | enum GNUNET_SET_OptionType type; | ||
253 | |||
254 | /** | ||
255 | * Value for the option, only used with some options. | ||
256 | */ | ||
257 | union { | ||
258 | uint64_t num; | ||
259 | } v; | ||
260 | }; | ||
261 | |||
262 | |||
263 | /** | ||
215 | * Continuation used for some of the set operations | 264 | * Continuation used for some of the set operations |
216 | * | 265 | * |
217 | * @param cls closure | 266 | * @param cls closure |
@@ -367,6 +416,7 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
367 | const struct GNUNET_HashCode *app_id, | 416 | const struct GNUNET_HashCode *app_id, |
368 | const struct GNUNET_MessageHeader *context_msg, | 417 | const struct GNUNET_MessageHeader *context_msg, |
369 | enum GNUNET_SET_ResultMode result_mode, | 418 | enum GNUNET_SET_ResultMode result_mode, |
419 | struct GNUNET_SET_Option options[], | ||
370 | GNUNET_SET_ResultIterator result_cb, | 420 | GNUNET_SET_ResultIterator result_cb, |
371 | void *result_cls); | 421 | void *result_cls); |
372 | 422 | ||
@@ -420,6 +470,7 @@ GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh); | |||
420 | struct GNUNET_SET_OperationHandle * | 470 | struct GNUNET_SET_OperationHandle * |
421 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, | 471 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, |
422 | enum GNUNET_SET_ResultMode result_mode, | 472 | enum GNUNET_SET_ResultMode result_mode, |
473 | struct GNUNET_SET_Option options[], | ||
423 | GNUNET_SET_ResultIterator result_cb, | 474 | GNUNET_SET_ResultIterator result_cb, |
424 | void *result_cls); | 475 | void *result_cls); |
425 | 476 | ||
diff --git a/src/namecache/.gitignore b/src/namecache/.gitignore index 6d2d8488a..2abc07dfb 100644 --- a/src/namecache/.gitignore +++ b/src/namecache/.gitignore | |||
@@ -4,3 +4,4 @@ test_namecache_api_cache_block | |||
4 | test_plugin_namecache_postgres | 4 | test_plugin_namecache_postgres |
5 | test_plugin_namecache_sqlite | 5 | test_plugin_namecache_sqlite |
6 | zonefiles | 6 | zonefiles |
7 | test_plugin_namecache_flat | ||
diff --git a/src/namestore/.gitignore b/src/namestore/.gitignore index 6943b888a..4995a9e36 100644 --- a/src/namestore/.gitignore +++ b/src/namestore/.gitignore | |||
@@ -18,3 +18,4 @@ test_namestore_api_zone_iteration_specific_zone.nc | |||
18 | test_namestore_api_zone_iteration_stop.nc | 18 | test_namestore_api_zone_iteration_stop.nc |
19 | test_plugin_namestore_postgres | 19 | test_plugin_namestore_postgres |
20 | test_plugin_namestore_sqlite | 20 | test_plugin_namestore_sqlite |
21 | test_plugin_namestore_flat | ||
diff --git a/src/peerstore/.gitignore b/src/peerstore/.gitignore index 33304d90b..7fc22bbdb 100644 --- a/src/peerstore/.gitignore +++ b/src/peerstore/.gitignore | |||
@@ -6,3 +6,4 @@ test_peerstore_api_store | |||
6 | test_peerstore_api_sync | 6 | test_peerstore_api_sync |
7 | test_peerstore_api_watch | 7 | test_peerstore_api_watch |
8 | test_plugin_peerstore_sqlite | 8 | test_plugin_peerstore_sqlite |
9 | test_plugin_peerstore_flat | ||
diff --git a/src/pt/.gitignore b/src/pt/.gitignore index 22f803ed6..ea678ffe5 100644 --- a/src/pt/.gitignore +++ b/src/pt/.gitignore | |||
@@ -1 +1,6 @@ | |||
1 | gnunet-daemon-pt | 1 | gnunet-daemon-pt |
2 | test_gns_vpn | ||
3 | test_gnunet_vpn-4_over | ||
4 | test_gnunet_vpn-4_to_6 | ||
5 | test_gnunet_vpn-6_over | ||
6 | test_gnunet_vpn-6_to_4 | ||
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c index 97ac8e961..54556cc52 100644 --- a/src/pt/gnunet-daemon-pt.c +++ b/src/pt/gnunet-daemon-pt.c | |||
@@ -864,14 +864,13 @@ handle_dns_response (void *cls, | |||
864 | const struct DnsResponseMessage *msg) | 864 | const struct DnsResponseMessage *msg) |
865 | { | 865 | { |
866 | struct CadetExit *exit = cls; | 866 | struct CadetExit *exit = cls; |
867 | struct GNUNET_TUN_DnsHeader dns; | ||
868 | size_t mlen; | 867 | size_t mlen; |
869 | struct RequestContext *rc; | 868 | struct RequestContext *rc; |
870 | 869 | ||
871 | mlen = ntohs (msg->header.size) - sizeof (*msg); | 870 | mlen = ntohs (msg->header.size) - sizeof (*msg); |
872 | for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next) | 871 | for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next) |
873 | { | 872 | { |
874 | if (dns.id == rc->dns_id) | 873 | if (msg->dns.id == rc->dns_id) |
875 | { | 874 | { |
876 | GNUNET_STATISTICS_update (stats, | 875 | GNUNET_STATISTICS_update (stats, |
877 | gettext_noop ("# DNS replies received"), | 876 | gettext_noop ("# DNS replies received"), |
diff --git a/src/pt/test_gns_vpn.c b/src/pt/test_gns_vpn.c index 4b7e817e8..53f27610b 100644 --- a/src/pt/test_gns_vpn.c +++ b/src/pt/test_gns_vpn.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2007, 2009, 2011, 2012, 2015 Christian Grothoff | 3 | Copyright (C) 2007, 2009, 2011, 2012, 2015, 2017 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -22,6 +22,19 @@ | |||
22 | * @file test_gns_vpn.c | 22 | * @file test_gns_vpn.c |
23 | * @brief testcase for accessing VPN services via GNS | 23 | * @brief testcase for accessing VPN services via GNS |
24 | * @author Martin Schanzenbach | 24 | * @author Martin Schanzenbach |
25 | * @author Christian Grothoff | ||
26 | * | ||
27 | * This test requires libcurl/libgnurl *with* support for C-ARES. | ||
28 | * This is NOT the default on most platforms, which means the test | ||
29 | * will be skipped in many cases. Compile libcurl/libgnurl with | ||
30 | * "--enable-ares" to get this test to pass. | ||
31 | * | ||
32 | * Furthermore, the test relies on gnunet-dns2gns being able to bind | ||
33 | * to port 53. This means that 'setcap' has to have worked during | ||
34 | * 'make install'. If this failed, but everything else is OK, the | ||
35 | * test may FAIL hard even though it is just an installation issue (we | ||
36 | * cannot conveniently test for the setcap to have worked). However, | ||
37 | * you should get a warning that gnunet-dns2gns failed to 'bind'. | ||
25 | */ | 38 | */ |
26 | #include "platform.h" | 39 | #include "platform.h" |
27 | #if HAVE_CURL_CURL_H | 40 | #if HAVE_CURL_CURL_H |
@@ -39,7 +52,7 @@ | |||
39 | #define PORT 8080 | 52 | #define PORT 8080 |
40 | #define TEST_DOMAIN "www.gnu" | 53 | #define TEST_DOMAIN "www.gnu" |
41 | 54 | ||
42 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) | 55 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) |
43 | 56 | ||
44 | /** | 57 | /** |
45 | * Return value for #main(). | 58 | * Return value for #main(). |
@@ -96,7 +109,10 @@ static struct CBC cbc; | |||
96 | 109 | ||
97 | 110 | ||
98 | static size_t | 111 | static size_t |
99 | copy_buffer (void *ptr, size_t size, size_t nmemb, void *ctx) | 112 | copy_buffer (void *ptr, |
113 | size_t size, | ||
114 | size_t nmemb, | ||
115 | void *ctx) | ||
100 | { | 116 | { |
101 | struct CBC *cbc = ctx; | 117 | struct CBC *cbc = ctx; |
102 | 118 | ||
@@ -174,6 +190,11 @@ do_shutdown (void *cls) | |||
174 | GNUNET_NAMESTORE_cancel (qe); | 190 | GNUNET_NAMESTORE_cancel (qe); |
175 | qe = NULL; | 191 | qe = NULL; |
176 | } | 192 | } |
193 | if (NULL != namestore) | ||
194 | { | ||
195 | GNUNET_NAMESTORE_disconnect (namestore); | ||
196 | namestore = NULL; | ||
197 | } | ||
177 | GNUNET_free_non_null (url); | 198 | GNUNET_free_non_null (url); |
178 | url = NULL; | 199 | url = NULL; |
179 | } | 200 | } |
@@ -280,6 +301,9 @@ curl_main () | |||
280 | static void | 301 | static void |
281 | start_curl (void *cls) | 302 | start_curl (void *cls) |
282 | { | 303 | { |
304 | CURLcode ec; | ||
305 | |||
306 | curl_task_id = NULL; | ||
283 | GNUNET_asprintf (&url, | 307 | GNUNET_asprintf (&url, |
284 | "http://%s/hello_world", | 308 | "http://%s/hello_world", |
285 | TEST_DOMAIN); | 309 | TEST_DOMAIN); |
@@ -291,7 +315,18 @@ start_curl (void *cls) | |||
291 | curl_easy_setopt (curl, CURLOPT_TIMEOUT, 150L); | 315 | curl_easy_setopt (curl, CURLOPT_TIMEOUT, 150L); |
292 | curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 150L); | 316 | curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 150L); |
293 | curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); | 317 | curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); |
294 | 318 | if (CURLE_OK != | |
319 | (ec = curl_easy_setopt (curl, | ||
320 | CURLOPT_DNS_SERVERS, | ||
321 | "127.0.0.1:53"))) | ||
322 | { | ||
323 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
324 | "curl build without support for CURLOPT_DNS_SERVERS (%s), cannot run test\n", | ||
325 | curl_easy_strerror (ec)); | ||
326 | global_ret = 77; | ||
327 | GNUNET_SCHEDULER_shutdown (); | ||
328 | return; | ||
329 | } | ||
295 | multi = curl_multi_init (); | 330 | multi = curl_multi_init (); |
296 | GNUNET_assert (multi != NULL); | 331 | GNUNET_assert (multi != NULL); |
297 | GNUNET_assert (CURLM_OK == curl_multi_add_handle (multi, curl)); | 332 | GNUNET_assert (CURLM_OK == curl_multi_add_handle (multi, curl)); |
@@ -302,14 +337,6 @@ start_curl (void *cls) | |||
302 | } | 337 | } |
303 | 338 | ||
304 | 339 | ||
305 | static void | ||
306 | disco_ns (void* cls) | ||
307 | { | ||
308 | GNUNET_NAMESTORE_disconnect (namestore); | ||
309 | namestore = NULL; | ||
310 | } | ||
311 | |||
312 | |||
313 | /** | 340 | /** |
314 | * Callback invoked from the namestore service once record is | 341 | * Callback invoked from the namestore service once record is |
315 | * created. | 342 | * created. |
@@ -328,9 +355,8 @@ commence_testing (void *cls, | |||
328 | const char *emsg) | 355 | const char *emsg) |
329 | { | 356 | { |
330 | qe = NULL; | 357 | qe = NULL; |
331 | GNUNET_SCHEDULER_add_now (&disco_ns, NULL); | 358 | if ( (NULL != emsg) && |
332 | 359 | (GNUNET_YES != success) ) | |
333 | if ((emsg != NULL) && (GNUNET_YES != success)) | ||
334 | { | 360 | { |
335 | fprintf (stderr, | 361 | fprintf (stderr, |
336 | "NS failed to create record %s\n", | 362 | "NS failed to create record %s\n", |
@@ -338,11 +364,14 @@ commence_testing (void *cls, | |||
338 | GNUNET_SCHEDULER_shutdown (); | 364 | GNUNET_SCHEDULER_shutdown (); |
339 | return; | 365 | return; |
340 | } | 366 | } |
367 | |||
341 | /* wait a little bit before downloading, as we just created the record */ | 368 | /* wait a little bit before downloading, as we just created the record */ |
342 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 369 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
343 | (GNUNET_TIME_UNIT_SECONDS, 1), | 370 | "Launching cURL request\n"); |
344 | &start_curl, | 371 | curl_task_id |
345 | NULL); | 372 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, |
373 | &start_curl, | ||
374 | NULL); | ||
346 | } | 375 | } |
347 | 376 | ||
348 | 377 | ||
@@ -402,7 +431,6 @@ mhd_main () | |||
402 | 431 | ||
403 | 432 | ||
404 | 433 | ||
405 | |||
406 | /** | 434 | /** |
407 | * Open '/dev/null' and make the result the given | 435 | * Open '/dev/null' and make the result the given |
408 | * file descriptor. | 436 | * file descriptor. |
@@ -448,9 +476,8 @@ fork_and_exec (const char *file, | |||
448 | pid = fork (); | 476 | pid = fork (); |
449 | if (-1 == pid) | 477 | if (-1 == pid) |
450 | { | 478 | { |
451 | fprintf (stderr, | 479 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, |
452 | "fork failed: %s\n", | 480 | "fork"); |
453 | strerror (errno)); | ||
454 | return 1; | 481 | return 1; |
455 | } | 482 | } |
456 | if (0 == pid) | 483 | if (0 == pid) |
@@ -464,10 +491,9 @@ fork_and_exec (const char *file, | |||
464 | open_dev_null (1, O_WRONLY); | 491 | open_dev_null (1, O_WRONLY); |
465 | (void) execv (file, cmd); | 492 | (void) execv (file, cmd); |
466 | /* can only get here on error */ | 493 | /* can only get here on error */ |
467 | fprintf (stderr, | 494 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, |
468 | "exec `%s' failed: %s\n", | 495 | "exec", |
469 | file, | 496 | file); |
470 | strerror (errno)); | ||
471 | _exit (1); | 497 | _exit (1); |
472 | } | 498 | } |
473 | /* keep running waitpid as long as the only error we get is 'EINTR' */ | 499 | /* keep running waitpid as long as the only error we get is 'EINTR' */ |
@@ -475,13 +501,20 @@ fork_and_exec (const char *file, | |||
475 | (errno == EINTR) ); | 501 | (errno == EINTR) ); |
476 | if (-1 == ret) | 502 | if (-1 == ret) |
477 | { | 503 | { |
478 | fprintf (stderr, | 504 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, |
479 | "waitpid failed: %s\n", | 505 | "waitpid"); |
480 | strerror (errno)); | ||
481 | return 1; | 506 | return 1; |
482 | } | 507 | } |
483 | if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) | 508 | if (! (WIFEXITED (status) && |
509 | (0 == WEXITSTATUS (status))) ) | ||
510 | { | ||
511 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
512 | "Process `%s` returned status code %d/%d.\n", | ||
513 | file, | ||
514 | WIFEXITED (status), | ||
515 | WEXITSTATUS (status)); | ||
484 | return 1; | 516 | return 1; |
517 | } | ||
485 | /* child process completed and returned success, we're happy */ | 518 | /* child process completed and returned success, we're happy */ |
486 | return 0; | 519 | return 0; |
487 | } | 520 | } |
@@ -572,6 +605,8 @@ identity_cb (void *cls, | |||
572 | &rd.data_size)); | 605 | &rd.data_size)); |
573 | rd.record_type = GNUNET_GNSRECORD_TYPE_VPN; | 606 | rd.record_type = GNUNET_GNSRECORD_TYPE_VPN; |
574 | 607 | ||
608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
609 | "Creating `www` record\n"); | ||
575 | qe = GNUNET_NAMESTORE_records_store (namestore, | 610 | qe = GNUNET_NAMESTORE_records_store (namestore, |
576 | zone_key, | 611 | zone_key, |
577 | "www", | 612 | "www", |
@@ -593,15 +628,18 @@ run (void *cls, | |||
593 | char *bin; | 628 | char *bin; |
594 | char *bin_identity; | 629 | char *bin_identity; |
595 | char *bin_gns; | 630 | char *bin_gns; |
631 | char *bin_arm; | ||
596 | char *config; | 632 | char *config; |
597 | 633 | ||
634 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
635 | "Test logic starting...\n"); | ||
598 | if (GNUNET_OK != | 636 | if (GNUNET_OK != |
599 | GNUNET_CONFIGURATION_get_value_string (cfg, | 637 | GNUNET_CONFIGURATION_get_value_string (cfg, |
600 | "arm", | 638 | "arm", |
601 | "CONFIG", | 639 | "CONFIG", |
602 | &config)) | 640 | &config)) |
603 | { | 641 | { |
604 | fprintf (stderr, | 642 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
605 | "Failed to locate configuration file. Skipping test.\n"); | 643 | "Failed to locate configuration file. Skipping test.\n"); |
606 | GNUNET_SCHEDULER_shutdown (); | 644 | GNUNET_SCHEDULER_shutdown (); |
607 | return; | 645 | return; |
@@ -626,18 +664,27 @@ run (void *cls, | |||
626 | { | 664 | { |
627 | "gnunet-identity", | 665 | "gnunet-identity", |
628 | "-e", "master-zone", | 666 | "-e", "master-zone", |
629 | "-s", "gns-intercept", | 667 | "-s", "dns2gns", |
668 | "-c", config, | ||
669 | NULL | ||
670 | }; | ||
671 | char *const arm_args[] = | ||
672 | { | ||
673 | "gnunet-arm", | ||
674 | "-i", "dns2gns", | ||
630 | "-c", config, | 675 | "-c", config, |
631 | NULL | 676 | NULL |
632 | }; | 677 | }; |
633 | char *const gns_args[] = | 678 | char *const gns_args[] = |
634 | { | 679 | { |
635 | "gnunet-gns", | 680 | "gnunet-gns", |
636 | "-u", "www.gns", | 681 | "-u", "www.gnu", |
637 | "-c", config, | 682 | "-c", config, |
638 | NULL | 683 | NULL |
639 | }; | 684 | }; |
640 | GNUNET_TESTING_peer_get_identity (peer, &id); | 685 | |
686 | GNUNET_TESTING_peer_get_identity (peer, | ||
687 | &id); | ||
641 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 688 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
642 | NULL); | 689 | NULL); |
643 | timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 690 | timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
@@ -648,20 +695,24 @@ run (void *cls, | |||
648 | "%s/%s", | 695 | "%s/%s", |
649 | bin, | 696 | bin, |
650 | "gnunet-identity"); | 697 | "gnunet-identity"); |
698 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
699 | "Creating `master-zone` ego\n"); | ||
651 | if (0 != fork_and_exec (bin_identity, identity_args)) | 700 | if (0 != fork_and_exec (bin_identity, identity_args)) |
652 | { | 701 | { |
653 | fprintf (stderr, | 702 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
654 | "Failed to run `gnunet-identity -C. Skipping test.\n"); | 703 | "Failed to run `gnunet-identity -C`. Skipping test.\n"); |
655 | GNUNET_SCHEDULER_shutdown (); | 704 | GNUNET_SCHEDULER_shutdown (); |
656 | GNUNET_free (bin_identity); | 705 | GNUNET_free (bin_identity); |
657 | GNUNET_free (config); | 706 | GNUNET_free (config); |
658 | GNUNET_free (bin); | 707 | GNUNET_free (bin); |
659 | return; | 708 | return; |
660 | } | 709 | } |
710 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
711 | "Setting `master-zone` ego as default for `gns-master` and `dns2gns`\n"); | ||
661 | if (0 != fork_and_exec (bin_identity, identity2_args)) | 712 | if (0 != fork_and_exec (bin_identity, identity2_args)) |
662 | { | 713 | { |
663 | fprintf (stderr, | 714 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
664 | "Failed to run `gnunet-identity -e. Skipping test.\n"); | 715 | "Failed to run `gnunet-identity -e`. Skipping test.\n"); |
665 | GNUNET_SCHEDULER_shutdown (); | 716 | GNUNET_SCHEDULER_shutdown (); |
666 | GNUNET_free (bin_identity); | 717 | GNUNET_free (bin_identity); |
667 | GNUNET_free (config); | 718 | GNUNET_free (config); |
@@ -670,8 +721,8 @@ run (void *cls, | |||
670 | } | 721 | } |
671 | if (0 != fork_and_exec (bin_identity, identity3_args)) | 722 | if (0 != fork_and_exec (bin_identity, identity3_args)) |
672 | { | 723 | { |
673 | fprintf (stderr, | 724 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
674 | "Failed to run `gnunet-identity -e. Skipping test.\n"); | 725 | "Failed to run `gnunet-identity -e`. Skipping test.\n"); |
675 | GNUNET_SCHEDULER_shutdown (); | 726 | GNUNET_SCHEDULER_shutdown (); |
676 | GNUNET_free (bin_identity); | 727 | GNUNET_free (bin_identity); |
677 | GNUNET_free (config); | 728 | GNUNET_free (config); |
@@ -681,14 +732,17 @@ run (void *cls, | |||
681 | GNUNET_free (bin_identity); | 732 | GNUNET_free (bin_identity); |
682 | 733 | ||
683 | /* do lookup just to launch GNS service */ | 734 | /* do lookup just to launch GNS service */ |
735 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
736 | "Resolving `www.gnu` zone entry to launch GNS (will yield no answer yet)\n"); | ||
684 | GNUNET_asprintf (&bin_gns, | 737 | GNUNET_asprintf (&bin_gns, |
685 | "%s/%s", | 738 | "%s/%s", |
686 | bin, | 739 | bin, |
687 | "gnunet-gns"); | 740 | "gnunet-gns"); |
688 | if (0 != fork_and_exec (bin_gns, gns_args)) | 741 | if (0 != fork_and_exec (bin_gns, |
742 | gns_args)) | ||
689 | { | 743 | { |
690 | fprintf (stderr, | 744 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
691 | "Failed to run `gnunet-gns -u. Skipping test.\n"); | 745 | "Failed to run `gnunet-gns -u. Skipping test.\n"); |
692 | GNUNET_SCHEDULER_shutdown (); | 746 | GNUNET_SCHEDULER_shutdown (); |
693 | GNUNET_free (bin_gns); | 747 | GNUNET_free (bin_gns); |
694 | GNUNET_free (config); | 748 | GNUNET_free (config); |
@@ -696,9 +750,27 @@ run (void *cls, | |||
696 | return; | 750 | return; |
697 | } | 751 | } |
698 | GNUNET_free (bin_gns); | 752 | GNUNET_free (bin_gns); |
753 | |||
754 | GNUNET_asprintf (&bin_arm, | ||
755 | "%s/%s", | ||
756 | bin, | ||
757 | "gnunet-arm"); | ||
758 | if (0 != fork_and_exec (bin_arm, | ||
759 | arm_args)) | ||
760 | { | ||
761 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
762 | "Failed to run `gnunet-arm -i dns2gns. Skipping test.\n"); | ||
763 | GNUNET_SCHEDULER_shutdown (); | ||
764 | GNUNET_free (bin_arm); | ||
765 | GNUNET_free (config); | ||
766 | GNUNET_free (bin); | ||
767 | return; | ||
768 | } | ||
769 | GNUNET_free (bin_arm); | ||
770 | |||
699 | GNUNET_free (config); | 771 | GNUNET_free (config); |
700 | GNUNET_free (bin); | 772 | GNUNET_free (bin); |
701 | 773 | sleep (1); /* give dns2gns chance to really run */ | |
702 | 774 | ||
703 | namestore = GNUNET_NAMESTORE_connect (cfg); | 775 | namestore = GNUNET_NAMESTORE_connect (cfg); |
704 | GNUNET_assert (NULL != namestore); | 776 | GNUNET_assert (NULL != namestore); |
@@ -720,39 +792,15 @@ run (void *cls, | |||
720 | 792 | ||
721 | 793 | ||
722 | int | 794 | int |
723 | main (int argc, char *const *argv) | 795 | main (int argc, |
796 | char *const *argv) | ||
724 | { | 797 | { |
725 | char *sbin_iptables; | ||
726 | char *bin_vpn; | 798 | char *bin_vpn; |
727 | char *bin_exit; | 799 | char *bin_exit; |
728 | char *bin_dns; | ||
729 | char *srv_dns; | ||
730 | struct stat s; | ||
731 | gid_t my_gid; | ||
732 | char *const iptables_args[] = | ||
733 | { | ||
734 | "iptables", "-t", "mangle", "-L", "-v", NULL | ||
735 | }; | ||
736 | |||
737 | if (0 == access ("/sbin/iptables", X_OK)) | ||
738 | sbin_iptables = "/sbin/iptables"; | ||
739 | else if (0 == access ("/usr/sbin/iptables", X_OK)) | ||
740 | sbin_iptables = "/usr/sbin/iptables"; | ||
741 | else | ||
742 | { | ||
743 | fprintf (stderr, | ||
744 | "Executable iptables not found in approved directories: %s, skipping\n", | ||
745 | strerror (errno)); | ||
746 | return 77; | ||
747 | } | ||
748 | |||
749 | if (0 != fork_and_exec (sbin_iptables, iptables_args)) | ||
750 | { | ||
751 | fprintf (stderr, | ||
752 | "Failed to run `iptables -t mangle -L -v'. Skipping test.\n"); | ||
753 | return 77; | ||
754 | } | ||
755 | 800 | ||
801 | GNUNET_log_setup ("test-gns-vpn", | ||
802 | "WARNING", | ||
803 | NULL); | ||
756 | if (0 != ACCESS ("/dev/net/tun", R_OK)) | 804 | if (0 != ACCESS ("/dev/net/tun", R_OK)) |
757 | { | 805 | { |
758 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | 806 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, |
@@ -765,59 +813,26 @@ main (int argc, char *const *argv) | |||
765 | 813 | ||
766 | bin_vpn = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); | 814 | bin_vpn = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); |
767 | bin_exit = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit"); | 815 | bin_exit = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit"); |
768 | bin_dns = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-dns"); | ||
769 | srv_dns = GNUNET_OS_get_libexec_binary_path ("gnunet-service-dns"); | ||
770 | if ( (0 != geteuid ()) && | 816 | if ( (0 != geteuid ()) && |
771 | ( (GNUNET_YES != | 817 | ( (GNUNET_YES != |
772 | GNUNET_OS_check_helper_binary (bin_vpn, GNUNET_YES, "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) || //ipv4 only please! | 818 | GNUNET_OS_check_helper_binary (bin_vpn, |
819 | GNUNET_YES, | ||
820 | "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) || //ipv4 only please! | ||
773 | (GNUNET_YES != | 821 | (GNUNET_YES != |
774 | GNUNET_OS_check_helper_binary (bin_exit, GNUNET_YES, "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) || //no nat, ipv4 only | 822 | GNUNET_OS_check_helper_binary (bin_exit, |
775 | (GNUNET_YES != | 823 | GNUNET_YES, |
776 | GNUNET_OS_check_helper_binary (bin_dns, GNUNET_YES, NULL))) ) // TODO: once we have a windows-testcase, add test parameters here | 824 | "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) ) ) //no nat, ipv4 only |
777 | { | 825 | { |
778 | fprintf (stderr, | 826 | fprintf (stderr, |
779 | "WARNING: gnunet-helper-{exit,vpn,dns} binaries in $PATH are not SUID, refusing to run test (as it would have to fail).\n"); | 827 | "WARNING: gnunet-helper-{exit,vpn} binaries in $PATH are not SUID, refusing to run test (as it would have to fail).\n"); |
780 | fprintf (stderr, | 828 | fprintf (stderr, |
781 | "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n"); | 829 | "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n"); |
782 | GNUNET_free (bin_vpn); | 830 | GNUNET_free (bin_vpn); |
783 | GNUNET_free (bin_exit); | 831 | GNUNET_free (bin_exit); |
784 | GNUNET_free (bin_dns); | ||
785 | GNUNET_free (srv_dns); | ||
786 | return 77; | 832 | return 77; |
787 | } | 833 | } |
788 | GNUNET_free (bin_vpn); | 834 | GNUNET_free (bin_vpn); |
789 | GNUNET_free (bin_exit); | 835 | GNUNET_free (bin_exit); |
790 | my_gid = getgid (); | ||
791 | if ( (0 != stat (bin_dns, &s)) || | ||
792 | (my_gid == s.st_gid) || | ||
793 | ( (0 == (S_ISUID & s.st_mode)) && (0 != getuid()) ) ) | ||
794 | { | ||
795 | fprintf (stderr, | ||
796 | "WARNING: %s has wrong permissions (%d, %d, %d), refusing to run test (as it would have to fail).\n", | ||
797 | bin_dns, | ||
798 | (0 != stat (bin_dns, &s)), | ||
799 | (my_gid == s.st_gid), | ||
800 | (0 == (S_ISUID & s.st_mode)) || (0 != getuid()) ); | ||
801 | GNUNET_free (bin_dns); | ||
802 | GNUNET_free (srv_dns); | ||
803 | return 77; | ||
804 | } | ||
805 | if ( (0 != stat (srv_dns, &s)) || | ||
806 | (my_gid == s.st_gid) || | ||
807 | (0 == (S_ISGID & s.st_mode)) ) | ||
808 | { | ||
809 | fprintf (stderr, | ||
810 | "WARNING: %s has wrong permissions (%d, %d, %d), refusing to run test (as it would have to fail).\n", | ||
811 | srv_dns, | ||
812 | (0 != stat (bin_dns, &s)), | ||
813 | (my_gid == s.st_gid), | ||
814 | (0 == (S_ISGID & s.st_mode)) ); | ||
815 | GNUNET_free (bin_dns); | ||
816 | GNUNET_free (srv_dns); | ||
817 | return 77; | ||
818 | } | ||
819 | GNUNET_free (bin_dns); | ||
820 | GNUNET_free (srv_dns); | ||
821 | 836 | ||
822 | dest_ip = "169.254.86.1"; | 837 | dest_ip = "169.254.86.1"; |
823 | dest_af = AF_INET; | 838 | dest_af = AF_INET; |
@@ -842,9 +857,11 @@ main (int argc, char *const *argv) | |||
842 | } | 857 | } |
843 | 858 | ||
844 | 859 | ||
845 | if (0 != GNUNET_TESTING_peer_run ("test-gnunet-vpn", | 860 | if (0 != |
846 | "test_gns_vpn.conf", | 861 | GNUNET_TESTING_peer_run ("test_gns_vpn", |
847 | &run, NULL)) | 862 | "test_gns_vpn.conf", |
863 | &run, | ||
864 | NULL)) | ||
848 | return 1; | 865 | return 1; |
849 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-vpn"); | 866 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-vpn"); |
850 | return global_ret; | 867 | return global_ret; |
diff --git a/src/pt/test_gns_vpn.conf b/src/pt/test_gns_vpn.conf index ac9724c04..86642465f 100644 --- a/src/pt/test_gns_vpn.conf +++ b/src/pt/test_gns_vpn.conf | |||
@@ -35,6 +35,10 @@ FORCESTART = YES | |||
35 | AUTOSTART = NO | 35 | AUTOSTART = NO |
36 | FORCESTART = NO | 36 | FORCESTART = NO |
37 | 37 | ||
38 | [zonemaster] | ||
39 | AUTOSTART = YES | ||
40 | FORCESTART = YES | ||
41 | |||
38 | #[vpn] | 42 | #[vpn] |
39 | #PREFIX = valgrind | 43 | #PREFIX = valgrind |
40 | 44 | ||
diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c index 2965808fa..b5669d9ea 100644 --- a/src/revocation/gnunet-service-revocation.c +++ b/src/revocation/gnunet-service-revocation.c | |||
@@ -509,6 +509,7 @@ transmit_task_cb (void *cls) | |||
509 | &revocation_set_union_app_id, | 509 | &revocation_set_union_app_id, |
510 | NULL, | 510 | NULL, |
511 | GNUNET_SET_RESULT_ADDED, | 511 | GNUNET_SET_RESULT_ADDED, |
512 | (struct GNUNET_SET_Option[]) { 0 }, | ||
512 | &add_revocation, | 513 | &add_revocation, |
513 | peer_entry); | 514 | peer_entry); |
514 | if (GNUNET_OK != | 515 | if (GNUNET_OK != |
@@ -755,6 +756,7 @@ handle_revocation_union_request (void *cls, | |||
755 | } | 756 | } |
756 | peer_entry->so = GNUNET_SET_accept (request, | 757 | peer_entry->so = GNUNET_SET_accept (request, |
757 | GNUNET_SET_RESULT_ADDED, | 758 | GNUNET_SET_RESULT_ADDED, |
759 | (struct GNUNET_SET_Option[]) { 0 }, | ||
758 | &add_revocation, | 760 | &add_revocation, |
759 | peer_entry); | 761 | peer_entry); |
760 | if (GNUNET_OK != | 762 | if (GNUNET_OK != |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c index 9f8d98657..34149435c 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c | |||
@@ -788,6 +788,7 @@ cb_intersection_request_alice (void *cls, | |||
788 | s->intersection_op | 788 | s->intersection_op |
789 | = GNUNET_SET_accept (request, | 789 | = GNUNET_SET_accept (request, |
790 | GNUNET_SET_RESULT_REMOVED, | 790 | GNUNET_SET_RESULT_REMOVED, |
791 | (struct GNUNET_SET_Option[]) { 0 }, | ||
791 | &cb_intersection_element_removed, | 792 | &cb_intersection_element_removed, |
792 | s); | 793 | s); |
793 | if (NULL == s->intersection_op) | 794 | if (NULL == s->intersection_op) |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c index 7fd69a4ea..db8241bb7 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | |||
@@ -670,6 +670,7 @@ start_intersection (struct BobServiceSession *s) | |||
670 | &set_sid, | 670 | &set_sid, |
671 | NULL, | 671 | NULL, |
672 | GNUNET_SET_RESULT_REMOVED, | 672 | GNUNET_SET_RESULT_REMOVED, |
673 | (struct GNUNET_SET_Option[]) { 0 }, | ||
673 | &cb_intersection_element_removed, | 674 | &cb_intersection_element_removed, |
674 | s); | 675 | s); |
675 | if (GNUNET_OK != | 676 | if (GNUNET_OK != |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_alice.c b/src/scalarproduct/gnunet-service-scalarproduct_alice.c index 779d84b60..f99ff6168 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct_alice.c | |||
@@ -1022,6 +1022,7 @@ cb_intersection_request_alice (void *cls, | |||
1022 | s->intersection_op | 1022 | s->intersection_op |
1023 | = GNUNET_SET_accept (request, | 1023 | = GNUNET_SET_accept (request, |
1024 | GNUNET_SET_RESULT_REMOVED, | 1024 | GNUNET_SET_RESULT_REMOVED, |
1025 | (struct GNUNET_SET_Option[]) { 0 }, | ||
1025 | &cb_intersection_element_removed, | 1026 | &cb_intersection_element_removed, |
1026 | s); | 1027 | s); |
1027 | if (NULL == s->intersection_op) | 1028 | if (NULL == s->intersection_op) |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_bob.c b/src/scalarproduct/gnunet-service-scalarproduct_bob.c index a2bceba43..efc3bc8ea 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct_bob.c | |||
@@ -964,6 +964,7 @@ start_intersection (struct BobServiceSession *s) | |||
964 | &s->session_id, | 964 | &s->session_id, |
965 | NULL, | 965 | NULL, |
966 | GNUNET_SET_RESULT_REMOVED, | 966 | GNUNET_SET_RESULT_REMOVED, |
967 | (struct GNUNET_SET_Option[]) { 0 }, | ||
967 | &cb_intersection_element_removed, | 968 | &cb_intersection_element_removed, |
968 | s); | 969 | s); |
969 | if (GNUNET_OK != | 970 | if (GNUNET_OK != |
@@ -1172,11 +1173,11 @@ handle_bob_client_message (void *cls, | |||
1172 | GNUNET_MQ_hd_fixed_size (alices_computation_request, | 1173 | GNUNET_MQ_hd_fixed_size (alices_computation_request, |
1173 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, | 1174 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, |
1174 | struct ServiceRequestMessage, | 1175 | struct ServiceRequestMessage, |
1175 | s), | 1176 | NULL), |
1176 | GNUNET_MQ_hd_var_size (alices_cryptodata_message, | 1177 | GNUNET_MQ_hd_var_size (alices_cryptodata_message, |
1177 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, | 1178 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, |
1178 | struct AliceCryptodataMessage, | 1179 | struct AliceCryptodataMessage, |
1179 | s), | 1180 | NULL), |
1180 | GNUNET_MQ_handler_end () | 1181 | GNUNET_MQ_handler_end () |
1181 | }; | 1182 | }; |
1182 | uint32_t contained_count; | 1183 | uint32_t contained_count; |
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index a545e8a06..c48518f08 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -1371,6 +1371,14 @@ handle_client_listen (void *cls, | |||
1371 | struct GNUNET_MessageHeader, | 1371 | struct GNUNET_MessageHeader, |
1372 | NULL), | 1372 | NULL), |
1373 | GNUNET_MQ_hd_var_size (p2p_message, | 1373 | GNUNET_MQ_hd_var_size (p2p_message, |
1374 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, | ||
1375 | struct GNUNET_MessageHeader, | ||
1376 | NULL), | ||
1377 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1378 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, | ||
1379 | struct GNUNET_MessageHeader, | ||
1380 | NULL), | ||
1381 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1374 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, | 1382 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, |
1375 | struct GNUNET_MessageHeader, | 1383 | struct GNUNET_MessageHeader, |
1376 | NULL), | 1384 | NULL), |
@@ -1379,6 +1387,10 @@ handle_client_listen (void *cls, | |||
1379 | struct GNUNET_MessageHeader, | 1387 | struct GNUNET_MessageHeader, |
1380 | NULL), | 1388 | NULL), |
1381 | GNUNET_MQ_hd_var_size (p2p_message, | 1389 | GNUNET_MQ_hd_var_size (p2p_message, |
1390 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, | ||
1391 | struct GNUNET_MessageHeader, | ||
1392 | NULL), | ||
1393 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1382 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, | 1394 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, |
1383 | struct GNUNET_MessageHeader, | 1395 | struct GNUNET_MessageHeader, |
1384 | NULL), | 1396 | NULL), |
@@ -1393,7 +1405,6 @@ handle_client_listen (void *cls, | |||
1393 | GNUNET_MQ_handler_end () | 1405 | GNUNET_MQ_handler_end () |
1394 | }; | 1406 | }; |
1395 | struct Listener *listener; | 1407 | struct Listener *listener; |
1396 | struct Operation *op; | ||
1397 | 1408 | ||
1398 | if (NULL != listener_get (client)) | 1409 | if (NULL != listener_get (client)) |
1399 | { | 1410 | { |
@@ -1422,7 +1433,7 @@ handle_client_listen (void *cls, | |||
1422 | &channel_end_cb, | 1433 | &channel_end_cb, |
1423 | cadet_handlers); | 1434 | cadet_handlers); |
1424 | /* check for existing incoming requests the listener might be interested in */ | 1435 | /* check for existing incoming requests the listener might be interested in */ |
1425 | for (op = incoming_head; NULL != op; op = op->next) | 1436 | for (struct Operation *op = incoming_head; NULL != op; op = op->next) |
1426 | { | 1437 | { |
1427 | if (NULL == op->spec) | 1438 | if (NULL == op->spec) |
1428 | continue; /* no details available yet */ | 1439 | continue; /* no details available yet */ |
@@ -1634,6 +1645,18 @@ handle_client_evaluate (void *cls, | |||
1634 | struct GNUNET_MessageHeader, | 1645 | struct GNUNET_MessageHeader, |
1635 | op), | 1646 | op), |
1636 | GNUNET_MQ_hd_var_size (p2p_message, | 1647 | GNUNET_MQ_hd_var_size (p2p_message, |
1648 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, | ||
1649 | struct GNUNET_MessageHeader, | ||
1650 | op), | ||
1651 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1652 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, | ||
1653 | struct GNUNET_MessageHeader, | ||
1654 | op), | ||
1655 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1656 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, | ||
1657 | struct GNUNET_MessageHeader, | ||
1658 | op), | ||
1659 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1637 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, | 1660 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, |
1638 | struct GNUNET_MessageHeader, | 1661 | struct GNUNET_MessageHeader, |
1639 | op), | 1662 | op), |
@@ -1668,6 +1691,10 @@ handle_client_evaluate (void *cls, | |||
1668 | spec->set = set; | 1691 | spec->set = set; |
1669 | spec->result_mode = ntohl (msg->result_mode); | 1692 | spec->result_mode = ntohl (msg->result_mode); |
1670 | spec->client_request_id = ntohl (msg->request_id); | 1693 | spec->client_request_id = ntohl (msg->request_id); |
1694 | spec->byzantine = msg->byzantine; | ||
1695 | spec->byzantine_lower_bound = msg->byzantine_lower_bound; | ||
1696 | spec->force_full = msg->force_full; | ||
1697 | spec->force_delta = msg->force_delta; | ||
1671 | context = GNUNET_MQ_extract_nested_mh (msg); | 1698 | context = GNUNET_MQ_extract_nested_mh (msg); |
1672 | op->spec = spec; | 1699 | op->spec = spec; |
1673 | 1700 | ||
@@ -2004,6 +2031,10 @@ handle_client_accept (void *cls, | |||
2004 | op); | 2031 | op); |
2005 | op->spec->client_request_id = ntohl (msg->request_id); | 2032 | op->spec->client_request_id = ntohl (msg->request_id); |
2006 | op->spec->result_mode = ntohl (msg->result_mode); | 2033 | op->spec->result_mode = ntohl (msg->result_mode); |
2034 | op->spec->byzantine = msg->byzantine; | ||
2035 | op->spec->byzantine_lower_bound = msg->byzantine_lower_bound; | ||
2036 | op->spec->force_full = msg->force_full; | ||
2037 | op->spec->force_delta = msg->force_delta; | ||
2007 | 2038 | ||
2008 | // Advance generation values, so that | 2039 | // Advance generation values, so that |
2009 | // mutations won't interfer with the running operation. | 2040 | // mutations won't interfer with the running operation. |
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h index 1460707fa..68d8fe81f 100644 --- a/src/set/gnunet-service-set.h +++ b/src/set/gnunet-service-set.h | |||
@@ -119,6 +119,30 @@ struct OperationSpecification | |||
119 | * When are elements sent to the client, and which elements are sent? | 119 | * When are elements sent to the client, and which elements are sent? |
120 | */ | 120 | */ |
121 | enum GNUNET_SET_ResultMode result_mode; | 121 | enum GNUNET_SET_ResultMode result_mode; |
122 | |||
123 | /** | ||
124 | * Always use delta operation instead of sending full sets, | ||
125 | * even it it's less efficient. | ||
126 | */ | ||
127 | int force_delta; | ||
128 | |||
129 | /** | ||
130 | * Always send full sets, even if delta operations would | ||
131 | * be more efficient. | ||
132 | */ | ||
133 | int force_full; | ||
134 | |||
135 | /** | ||
136 | * #GNUNET_YES to fail operations where Byzantine faults | ||
137 | * are suspected | ||
138 | */ | ||
139 | int byzantine; | ||
140 | |||
141 | /** | ||
142 | * Lower bound for the set size, used only when | ||
143 | * byzantine mode is enabled. | ||
144 | */ | ||
145 | int byzantine_lower_bound; | ||
122 | }; | 146 | }; |
123 | 147 | ||
124 | 148 | ||
diff --git a/src/set/gnunet-service-set_protocol.h b/src/set/gnunet-service-set_protocol.h index 748da15fc..0138b21c7 100644 --- a/src/set/gnunet-service-set_protocol.h +++ b/src/set/gnunet-service-set_protocol.h | |||
@@ -208,6 +208,20 @@ struct IntersectionDoneMessage | |||
208 | struct GNUNET_HashCode element_xor_hash; | 208 | struct GNUNET_HashCode element_xor_hash; |
209 | }; | 209 | }; |
210 | 210 | ||
211 | |||
212 | /** | ||
213 | * Strata estimator together with the peer's overall set size. | ||
214 | */ | ||
215 | struct StrataEstimatorMessage | ||
216 | { | ||
217 | /** | ||
218 | * Type: #GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C) | ||
219 | */ | ||
220 | struct GNUNET_MessageHeader header; | ||
221 | |||
222 | uint64_t set_size; | ||
223 | }; | ||
224 | |||
211 | GNUNET_NETWORK_STRUCT_END | 225 | GNUNET_NETWORK_STRUCT_END |
212 | 226 | ||
213 | #endif | 227 | #endif |
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c index acaabd94a..ab39a2e8a 100644 --- a/src/set/gnunet-service-set_union.c +++ b/src/set/gnunet-service-set_union.c | |||
@@ -85,6 +85,7 @@ enum UnionOperationPhase | |||
85 | * upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS. | 85 | * upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS. |
86 | * | 86 | * |
87 | * XXX: could use better wording. | 87 | * XXX: could use better wording. |
88 | * XXX: repurposed to also expect a "request full set" message, should be renamed | ||
88 | * | 89 | * |
89 | * After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS | 90 | * After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS |
90 | */ | 91 | */ |
@@ -115,14 +116,22 @@ enum UnionOperationPhase | |||
115 | * In the penultimate phase, | 116 | * In the penultimate phase, |
116 | * we wait until all our demands | 117 | * we wait until all our demands |
117 | * are satisfied. Then we send a done | 118 | * are satisfied. Then we send a done |
118 | * message, and wait for another done message.*/ | 119 | * message, and wait for another done message. |
120 | */ | ||
119 | PHASE_FINISH_WAITING, | 121 | PHASE_FINISH_WAITING, |
120 | 122 | ||
121 | /** | 123 | /** |
122 | * In the ultimate phase, we wait until | 124 | * In the ultimate phase, we wait until |
123 | * our demands are satisfied and then | 125 | * our demands are satisfied and then |
124 | * quit (sending another DONE message). */ | 126 | * quit (sending another DONE message). |
125 | PHASE_DONE | 127 | */ |
128 | PHASE_DONE, | ||
129 | |||
130 | /** | ||
131 | * After sending the full set, wait for responses with the elements | ||
132 | * that the local peer is missing. | ||
133 | */ | ||
134 | PHASE_FULL_SENDING, | ||
126 | }; | 135 | }; |
127 | 136 | ||
128 | 137 | ||
@@ -148,7 +157,7 @@ struct OperationState | |||
148 | struct InvertibleBloomFilter *local_ibf; | 157 | struct InvertibleBloomFilter *local_ibf; |
149 | 158 | ||
150 | /** | 159 | /** |
151 | * Maps IBF-Keys (specific to the current salt) to elements. | 160 | * Maps unsalted IBF-Keys to elements. |
152 | * Used as a multihashmap, the keys being the lower 32bit of the IBF-Key. | 161 | * Used as a multihashmap, the keys being the lower 32bit of the IBF-Key. |
153 | * Colliding IBF-Keys are linked. | 162 | * Colliding IBF-Keys are linked. |
154 | */ | 163 | */ |
@@ -183,6 +192,23 @@ struct OperationState | |||
183 | * Salt for the IBF we've received and that we're currently decoding. | 192 | * Salt for the IBF we've received and that we're currently decoding. |
184 | */ | 193 | */ |
185 | uint32_t salt_receive; | 194 | uint32_t salt_receive; |
195 | |||
196 | /** | ||
197 | * Number of elements we received from the other peer | ||
198 | * that were not in the local set yet. | ||
199 | */ | ||
200 | uint32_t received_fresh; | ||
201 | |||
202 | /** | ||
203 | * Total number of elements received from the other peer. | ||
204 | */ | ||
205 | uint32_t received_total; | ||
206 | |||
207 | /** | ||
208 | * Initial size of our set, just before | ||
209 | * the operation started. | ||
210 | */ | ||
211 | uint64_t initial_size; | ||
186 | }; | 212 | }; |
187 | 213 | ||
188 | 214 | ||
@@ -203,6 +229,14 @@ struct KeyEntry | |||
203 | * is #GNUNET_YES. | 229 | * is #GNUNET_YES. |
204 | */ | 230 | */ |
205 | struct ElementEntry *element; | 231 | struct ElementEntry *element; |
232 | |||
233 | /** | ||
234 | * Did we receive this element? | ||
235 | * Even if element->is_foreign is false, we might | ||
236 | * have received the element, so this indicates that | ||
237 | * the other peer has it. | ||
238 | */ | ||
239 | int received; | ||
206 | }; | 240 | }; |
207 | 241 | ||
208 | 242 | ||
@@ -362,6 +396,16 @@ get_ibf_key (const struct GNUNET_HashCode *src) | |||
362 | 396 | ||
363 | 397 | ||
364 | /** | 398 | /** |
399 | * Context for #op_get_element_iterator | ||
400 | */ | ||
401 | struct GetElementContext | ||
402 | { | ||
403 | struct GNUNET_HashCode hash; | ||
404 | struct KeyEntry *k; | ||
405 | }; | ||
406 | |||
407 | |||
408 | /** | ||
365 | * Iterator over the mapping from IBF keys to element entries. Checks if we | 409 | * Iterator over the mapping from IBF keys to element entries. Checks if we |
366 | * have an element with a given GNUNET_HashCode. | 410 | * have an element with a given GNUNET_HashCode. |
367 | * | 411 | * |
@@ -372,17 +416,20 @@ get_ibf_key (const struct GNUNET_HashCode *src) | |||
372 | * #GNUNET_NO if we've found the element. | 416 | * #GNUNET_NO if we've found the element. |
373 | */ | 417 | */ |
374 | static int | 418 | static int |
375 | op_has_element_iterator (void *cls, | 419 | op_get_element_iterator (void *cls, |
376 | uint32_t key, | 420 | uint32_t key, |
377 | void *value) | 421 | void *value) |
378 | { | 422 | { |
379 | struct GNUNET_HashCode *element_hash = cls; | 423 | struct GetElementContext *ctx = cls; |
380 | struct KeyEntry *k = value; | 424 | struct KeyEntry *k = value; |
381 | 425 | ||
382 | GNUNET_assert (NULL != k); | 426 | GNUNET_assert (NULL != k); |
383 | if (0 == GNUNET_CRYPTO_hash_cmp (&k->element->element_hash, | 427 | if (0 == GNUNET_CRYPTO_hash_cmp (&k->element->element_hash, |
384 | element_hash)) | 428 | &ctx->hash)) |
429 | { | ||
430 | ctx->k = k; | ||
385 | return GNUNET_NO; | 431 | return GNUNET_NO; |
432 | } | ||
386 | return GNUNET_YES; | 433 | return GNUNET_YES; |
387 | } | 434 | } |
388 | 435 | ||
@@ -395,23 +442,29 @@ op_has_element_iterator (void *cls, | |||
395 | * @param element_hash hash of the element to look for | 442 | * @param element_hash hash of the element to look for |
396 | * @return #GNUNET_YES if the element has been found, #GNUNET_NO otherwise | 443 | * @return #GNUNET_YES if the element has been found, #GNUNET_NO otherwise |
397 | */ | 444 | */ |
398 | static int | 445 | static struct KeyEntry * |
399 | op_has_element (struct Operation *op, | 446 | op_get_element (struct Operation *op, |
400 | const struct GNUNET_HashCode *element_hash) | 447 | const struct GNUNET_HashCode *element_hash) |
401 | { | 448 | { |
402 | int ret; | 449 | int ret; |
403 | struct IBF_Key ibf_key; | 450 | struct IBF_Key ibf_key; |
451 | struct GetElementContext ctx = { 0 }; | ||
452 | |||
453 | ctx.hash = *element_hash; | ||
404 | 454 | ||
405 | ibf_key = get_ibf_key (element_hash); | 455 | ibf_key = get_ibf_key (element_hash); |
406 | ret = GNUNET_CONTAINER_multihashmap32_get_multiple (op->state->key_to_element, | 456 | ret = GNUNET_CONTAINER_multihashmap32_get_multiple (op->state->key_to_element, |
407 | (uint32_t) ibf_key.key_val, | 457 | (uint32_t) ibf_key.key_val, |
408 | op_has_element_iterator, | 458 | op_get_element_iterator, |
409 | (void *) element_hash); | 459 | &ctx); |
410 | 460 | ||
411 | /* was the iteration aborted because we found the element? */ | 461 | /* was the iteration aborted because we found the element? */ |
412 | if (GNUNET_SYSERR == ret) | 462 | if (GNUNET_SYSERR == ret) |
413 | return GNUNET_YES; | 463 | { |
414 | return GNUNET_NO; | 464 | GNUNET_assert (NULL != ctx.k); |
465 | return ctx.k; | ||
466 | } | ||
467 | return NULL; | ||
415 | } | 468 | } |
416 | 469 | ||
417 | 470 | ||
@@ -427,10 +480,12 @@ op_has_element (struct Operation *op, | |||
427 | * | 480 | * |
428 | * @param op the union operation | 481 | * @param op the union operation |
429 | * @param ee the element entry | 482 | * @param ee the element entry |
483 | * @parem received was this element received from the remote peer? | ||
430 | */ | 484 | */ |
431 | static void | 485 | static void |
432 | op_register_element (struct Operation *op, | 486 | op_register_element (struct Operation *op, |
433 | struct ElementEntry *ee) | 487 | struct ElementEntry *ee, |
488 | int received) | ||
434 | { | 489 | { |
435 | struct IBF_Key ibf_key; | 490 | struct IBF_Key ibf_key; |
436 | struct KeyEntry *k; | 491 | struct KeyEntry *k; |
@@ -439,6 +494,7 @@ op_register_element (struct Operation *op, | |||
439 | k = GNUNET_new (struct KeyEntry); | 494 | k = GNUNET_new (struct KeyEntry); |
440 | k->element = ee; | 495 | k->element = ee; |
441 | k->ibf_key = ibf_key; | 496 | k->ibf_key = ibf_key; |
497 | k->received = received; | ||
442 | GNUNET_assert (GNUNET_OK == | 498 | GNUNET_assert (GNUNET_OK == |
443 | GNUNET_CONTAINER_multihashmap32_put (op->state->key_to_element, | 499 | GNUNET_CONTAINER_multihashmap32_put (op->state->key_to_element, |
444 | (uint32_t) ibf_key.key_val, | 500 | (uint32_t) ibf_key.key_val, |
@@ -524,12 +580,30 @@ init_key_to_element_iterator (void *cls, | |||
524 | 580 | ||
525 | GNUNET_assert (GNUNET_NO == ee->remote); | 581 | GNUNET_assert (GNUNET_NO == ee->remote); |
526 | 582 | ||
527 | op_register_element (op, ee); | 583 | op_register_element (op, ee, GNUNET_NO); |
528 | return GNUNET_YES; | 584 | return GNUNET_YES; |
529 | } | 585 | } |
530 | 586 | ||
531 | 587 | ||
532 | /** | 588 | /** |
589 | * Initialize the IBF key to element mapping local to this set | ||
590 | * operation. | ||
591 | * | ||
592 | * @param op the set union operation | ||
593 | */ | ||
594 | static void | ||
595 | initialize_key_to_element (struct Operation *op) | ||
596 | { | ||
597 | unsigned int len; | ||
598 | |||
599 | GNUNET_assert (NULL == op->state->key_to_element); | ||
600 | len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
601 | op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1); | ||
602 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, init_key_to_element_iterator, op); | ||
603 | } | ||
604 | |||
605 | |||
606 | /** | ||
533 | * Create an ibf with the operation's elements | 607 | * Create an ibf with the operation's elements |
534 | * of the specified size | 608 | * of the specified size |
535 | * | 609 | * |
@@ -541,15 +615,8 @@ static int | |||
541 | prepare_ibf (struct Operation *op, | 615 | prepare_ibf (struct Operation *op, |
542 | uint32_t size) | 616 | uint32_t size) |
543 | { | 617 | { |
544 | if (NULL == op->state->key_to_element) | 618 | GNUNET_assert (NULL != op->state->key_to_element); |
545 | { | ||
546 | unsigned int len; | ||
547 | 619 | ||
548 | len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
549 | op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1); | ||
550 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, | ||
551 | init_key_to_element_iterator, op); | ||
552 | } | ||
553 | if (NULL != op->state->local_ibf) | 620 | if (NULL != op->state->local_ibf) |
554 | ibf_destroy (op->state->local_ibf); | 621 | ibf_destroy (op->state->local_ibf); |
555 | op->state->local_ibf = ibf_create (size, SE_IBF_HASH_NUM); | 622 | op->state->local_ibf = ibf_create (size, SE_IBF_HASH_NUM); |
@@ -648,7 +715,7 @@ send_strata_estimator (struct Operation *op) | |||
648 | { | 715 | { |
649 | const struct StrataEstimator *se = op->state->se; | 716 | const struct StrataEstimator *se = op->state->se; |
650 | struct GNUNET_MQ_Envelope *ev; | 717 | struct GNUNET_MQ_Envelope *ev; |
651 | struct GNUNET_MessageHeader *strata_msg; | 718 | struct StrataEstimatorMessage *strata_msg; |
652 | char *buf; | 719 | char *buf; |
653 | size_t len; | 720 | size_t len; |
654 | uint16_t type; | 721 | uint16_t type; |
@@ -660,13 +727,14 @@ send_strata_estimator (struct Operation *op) | |||
660 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC; | 727 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC; |
661 | else | 728 | else |
662 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE; | 729 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE; |
663 | ev = GNUNET_MQ_msg_header_extra (strata_msg, | 730 | ev = GNUNET_MQ_msg_extra (strata_msg, |
664 | len, | 731 | len, |
665 | type); | 732 | type); |
666 | GNUNET_memcpy (&strata_msg[1], | 733 | GNUNET_memcpy (&strata_msg[1], |
667 | buf, | 734 | buf, |
668 | len); | 735 | len); |
669 | GNUNET_free (buf); | 736 | GNUNET_free (buf); |
737 | strata_msg->set_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements)); | ||
670 | GNUNET_MQ_send (op->mq, | 738 | GNUNET_MQ_send (op->mq, |
671 | ev); | 739 | ev); |
672 | op->state->phase = PHASE_EXPECT_IBF; | 740 | op->state->phase = PHASE_EXPECT_IBF; |
@@ -698,6 +766,47 @@ get_order_from_difference (unsigned int diff) | |||
698 | 766 | ||
699 | 767 | ||
700 | /** | 768 | /** |
769 | * Send a set element. | ||
770 | * | ||
771 | * @param cls the union operation `struct Operation *` | ||
772 | * @param key unused | ||
773 | * @param value the `struct ElementEntry *` to insert | ||
774 | * into the key-to-element mapping | ||
775 | * @return #GNUNET_YES (to continue iterating) | ||
776 | */ | ||
777 | static int | ||
778 | send_element_iterator (void *cls, | ||
779 | const struct GNUNET_HashCode *key, | ||
780 | void *value) | ||
781 | { | ||
782 | struct Operation *op = cls; | ||
783 | struct GNUNET_SET_ElementMessage *emsg; | ||
784 | struct GNUNET_SET_Element *el = value; | ||
785 | struct GNUNET_MQ_Envelope *ev; | ||
786 | |||
787 | ev = GNUNET_MQ_msg_extra (emsg, el->size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT); | ||
788 | emsg->element_type = htonl (el->element_type); | ||
789 | GNUNET_memcpy (&emsg[1], el->data, el->size); | ||
790 | GNUNET_MQ_send (op->mq, ev); | ||
791 | return GNUNET_YES; | ||
792 | } | ||
793 | |||
794 | |||
795 | static void | ||
796 | send_full_set (struct Operation *op) | ||
797 | { | ||
798 | struct GNUNET_MQ_Envelope *ev; | ||
799 | |||
800 | op->state->phase = PHASE_FULL_SENDING; | ||
801 | |||
802 | (void) GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, | ||
803 | &send_element_iterator, op); | ||
804 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); | ||
805 | GNUNET_MQ_send (op->mq, ev); | ||
806 | } | ||
807 | |||
808 | |||
809 | /** | ||
701 | * Handle a strata estimator from a remote peer | 810 | * Handle a strata estimator from a remote peer |
702 | * | 811 | * |
703 | * @param cls the union operation | 812 | * @param cls the union operation |
@@ -713,7 +822,9 @@ handle_p2p_strata_estimator (void *cls, | |||
713 | { | 822 | { |
714 | struct Operation *op = cls; | 823 | struct Operation *op = cls; |
715 | struct StrataEstimator *remote_se; | 824 | struct StrataEstimator *remote_se; |
716 | int diff; | 825 | struct StrataEstimatorMessage *msg = (void *) mh; |
826 | unsigned int diff; | ||
827 | uint64_t other_size; | ||
717 | size_t len; | 828 | size_t len; |
718 | 829 | ||
719 | GNUNET_STATISTICS_update (_GSS_statistics, | 830 | GNUNET_STATISTICS_update (_GSS_statistics, |
@@ -723,11 +834,11 @@ handle_p2p_strata_estimator (void *cls, | |||
723 | 834 | ||
724 | if (op->state->phase != PHASE_EXPECT_SE) | 835 | if (op->state->phase != PHASE_EXPECT_SE) |
725 | { | 836 | { |
726 | fail_union_operation (op); | ||
727 | GNUNET_break (0); | 837 | GNUNET_break (0); |
838 | fail_union_operation (op); | ||
728 | return GNUNET_SYSERR; | 839 | return GNUNET_SYSERR; |
729 | } | 840 | } |
730 | len = ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader); | 841 | len = ntohs (mh->size) - sizeof (struct StrataEstimatorMessage); |
731 | if ( (GNUNET_NO == is_compressed) && | 842 | if ( (GNUNET_NO == is_compressed) && |
732 | (len != SE_STRATA_COUNT * SE_IBF_SIZE * IBF_BUCKET_SIZE) ) | 843 | (len != SE_STRATA_COUNT * SE_IBF_SIZE * IBF_BUCKET_SIZE) ) |
733 | { | 844 | { |
@@ -735,6 +846,7 @@ handle_p2p_strata_estimator (void *cls, | |||
735 | GNUNET_break (0); | 846 | GNUNET_break (0); |
736 | return GNUNET_SYSERR; | 847 | return GNUNET_SYSERR; |
737 | } | 848 | } |
849 | other_size = GNUNET_ntohll (msg->set_size); | ||
738 | remote_se = strata_estimator_create (SE_STRATA_COUNT, | 850 | remote_se = strata_estimator_create (SE_STRATA_COUNT, |
739 | SE_IBF_SIZE, | 851 | SE_IBF_SIZE, |
740 | SE_IBF_HASH_NUM); | 852 | SE_IBF_HASH_NUM); |
@@ -745,7 +857,7 @@ handle_p2p_strata_estimator (void *cls, | |||
745 | return GNUNET_SYSERR; | 857 | return GNUNET_SYSERR; |
746 | } | 858 | } |
747 | if (GNUNET_OK != | 859 | if (GNUNET_OK != |
748 | strata_estimator_read (&mh[1], | 860 | strata_estimator_read (&msg[1], |
749 | len, | 861 | len, |
750 | is_compressed, | 862 | is_compressed, |
751 | remote_se)) | 863 | remote_se)) |
@@ -765,16 +877,46 @@ handle_p2p_strata_estimator (void *cls, | |||
765 | "got se diff=%d, using ibf size %d\n", | 877 | "got se diff=%d, using ibf size %d\n", |
766 | diff, | 878 | diff, |
767 | 1<<get_order_from_difference (diff)); | 879 | 1<<get_order_from_difference (diff)); |
768 | if (GNUNET_OK != | 880 | |
769 | send_ibf (op, | 881 | if ((GNUNET_YES == op->spec->byzantine) && (other_size < op->spec->byzantine_lower_bound)) |
770 | get_order_from_difference (diff))) | ||
771 | { | 882 | { |
772 | /* Internal error, best we can do is shut the connection */ | 883 | GNUNET_break (0); |
773 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
774 | "Failed to send IBF, closing connection\n"); | ||
775 | fail_union_operation (op); | 884 | fail_union_operation (op); |
776 | return GNUNET_SYSERR; | 885 | return GNUNET_SYSERR; |
777 | } | 886 | } |
887 | |||
888 | |||
889 | if ( (GNUNET_YES == op->spec->force_full) || (diff > op->state->initial_size / 2)) | ||
890 | { | ||
891 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
892 | "Sending full set (diff=%d, own set=%u)\n", | ||
893 | diff, | ||
894 | op->state->initial_size); | ||
895 | if (op->state->initial_size <= other_size) | ||
896 | { | ||
897 | send_full_set (op); | ||
898 | } | ||
899 | else | ||
900 | { | ||
901 | struct GNUNET_MQ_Envelope *ev; | ||
902 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL); | ||
903 | GNUNET_MQ_send (op->mq, ev); | ||
904 | } | ||
905 | } | ||
906 | else | ||
907 | { | ||
908 | if (GNUNET_OK != | ||
909 | send_ibf (op, | ||
910 | get_order_from_difference (diff))) | ||
911 | { | ||
912 | /* Internal error, best we can do is shut the connection */ | ||
913 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
914 | "Failed to send IBF, closing connection\n"); | ||
915 | fail_union_operation (op); | ||
916 | return GNUNET_SYSERR; | ||
917 | } | ||
918 | } | ||
919 | |||
778 | return GNUNET_OK; | 920 | return GNUNET_OK; |
779 | } | 921 | } |
780 | 922 | ||
@@ -1210,6 +1352,8 @@ maybe_finish (struct Operation *op) | |||
1210 | 1352 | ||
1211 | /** | 1353 | /** |
1212 | * Handle an element message from a remote peer. | 1354 | * Handle an element message from a remote peer. |
1355 | * Sent by the other peer either because we decoded an IBF and placed a demand, | ||
1356 | * or because the other peer switched to full set transmission. | ||
1213 | * | 1357 | * |
1214 | * @param cls the union operation | 1358 | * @param cls the union operation |
1215 | * @param mh the message | 1359 | * @param mh the message |
@@ -1273,7 +1417,11 @@ handle_p2p_elements (void *cls, | |||
1273 | 1, | 1417 | 1, |
1274 | GNUNET_NO); | 1418 | GNUNET_NO); |
1275 | 1419 | ||
1276 | if (GNUNET_YES == op_has_element (op, &ee->element_hash)) | 1420 | op->state->received_total += 1; |
1421 | |||
1422 | struct KeyEntry *ke = op_get_element (op, &ee->element_hash); | ||
1423 | |||
1424 | if (NULL != ke) | ||
1277 | { | 1425 | { |
1278 | /* Got repeated element. Should not happen since | 1426 | /* Got repeated element. Should not happen since |
1279 | * we track demands. */ | 1427 | * we track demands. */ |
@@ -1281,13 +1429,15 @@ handle_p2p_elements (void *cls, | |||
1281 | "# repeated elements", | 1429 | "# repeated elements", |
1282 | 1, | 1430 | 1, |
1283 | GNUNET_NO); | 1431 | GNUNET_NO); |
1432 | ke->received = GNUNET_YES; | ||
1284 | GNUNET_free (ee); | 1433 | GNUNET_free (ee); |
1285 | } | 1434 | } |
1286 | else | 1435 | else |
1287 | { | 1436 | { |
1288 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1437 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1289 | "Registering new element from remote peer\n"); | 1438 | "Registering new element from remote peer\n"); |
1290 | op_register_element (op, ee); | 1439 | op->state->received_fresh += 1; |
1440 | op_register_element (op, ee, GNUNET_YES); | ||
1291 | /* only send results immediately if the client wants it */ | 1441 | /* only send results immediately if the client wants it */ |
1292 | switch (op->spec->result_mode) | 1442 | switch (op->spec->result_mode) |
1293 | { | 1443 | { |
@@ -1304,11 +1454,112 @@ handle_p2p_elements (void *cls, | |||
1304 | } | 1454 | } |
1305 | } | 1455 | } |
1306 | 1456 | ||
1457 | if (op->state->received_total > 8 && op->state->received_fresh < op->state->received_total / 3) | ||
1458 | { | ||
1459 | /* The other peer gave us lots of old elements, there's something wrong. */ | ||
1460 | GNUNET_break_op (0); | ||
1461 | fail_union_operation (op); | ||
1462 | return; | ||
1463 | } | ||
1464 | |||
1307 | maybe_finish (op); | 1465 | maybe_finish (op); |
1308 | } | 1466 | } |
1309 | 1467 | ||
1310 | 1468 | ||
1311 | /** | 1469 | /** |
1470 | * Handle an element message from a remote peer. | ||
1471 | * | ||
1472 | * @param cls the union operation | ||
1473 | * @param mh the message | ||
1474 | */ | ||
1475 | static void | ||
1476 | handle_p2p_full_element (void *cls, | ||
1477 | const struct GNUNET_MessageHeader *mh) | ||
1478 | { | ||
1479 | struct Operation *op = cls; | ||
1480 | struct ElementEntry *ee; | ||
1481 | const struct GNUNET_SET_ElementMessage *emsg; | ||
1482 | uint16_t element_size; | ||
1483 | |||
1484 | if (ntohs (mh->size) < sizeof (struct GNUNET_SET_ElementMessage)) | ||
1485 | { | ||
1486 | GNUNET_break_op (0); | ||
1487 | fail_union_operation (op); | ||
1488 | return; | ||
1489 | } | ||
1490 | |||
1491 | emsg = (const struct GNUNET_SET_ElementMessage *) mh; | ||
1492 | |||
1493 | element_size = ntohs (mh->size) - sizeof (struct GNUNET_SET_ElementMessage); | ||
1494 | ee = GNUNET_malloc (sizeof (struct ElementEntry) + element_size); | ||
1495 | GNUNET_memcpy (&ee[1], &emsg[1], element_size); | ||
1496 | ee->element.size = element_size; | ||
1497 | ee->element.data = &ee[1]; | ||
1498 | ee->element.element_type = ntohs (emsg->element_type); | ||
1499 | ee->remote = GNUNET_YES; | ||
1500 | GNUNET_SET_element_hash (&ee->element, &ee->element_hash); | ||
1501 | |||
1502 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1503 | "Got element (full diff, size %u, hash %s) from peer\n", | ||
1504 | (unsigned int) element_size, | ||
1505 | GNUNET_h2s (&ee->element_hash)); | ||
1506 | |||
1507 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1508 | "# received elements", | ||
1509 | 1, | ||
1510 | GNUNET_NO); | ||
1511 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1512 | "# exchanged elements", | ||
1513 | 1, | ||
1514 | GNUNET_NO); | ||
1515 | |||
1516 | op->state->received_total += 1; | ||
1517 | |||
1518 | struct KeyEntry *ke = op_get_element (op, &ee->element_hash); | ||
1519 | |||
1520 | if (NULL != ke) | ||
1521 | { | ||
1522 | /* Got repeated element. Should not happen since | ||
1523 | * we track demands. */ | ||
1524 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1525 | "# repeated elements", | ||
1526 | 1, | ||
1527 | GNUNET_NO); | ||
1528 | ke->received = GNUNET_YES; | ||
1529 | GNUNET_free (ee); | ||
1530 | } | ||
1531 | else | ||
1532 | { | ||
1533 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1534 | "Registering new element from remote peer\n"); | ||
1535 | op->state->received_fresh += 1; | ||
1536 | op_register_element (op, ee, GNUNET_YES); | ||
1537 | /* only send results immediately if the client wants it */ | ||
1538 | switch (op->spec->result_mode) | ||
1539 | { | ||
1540 | case GNUNET_SET_RESULT_ADDED: | ||
1541 | send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK); | ||
1542 | break; | ||
1543 | case GNUNET_SET_RESULT_SYMMETRIC: | ||
1544 | send_client_element (op, &ee->element, GNUNET_SET_STATUS_ADD_LOCAL); | ||
1545 | break; | ||
1546 | default: | ||
1547 | /* Result mode not supported, should have been caught earlier. */ | ||
1548 | GNUNET_break (0); | ||
1549 | break; | ||
1550 | } | ||
1551 | } | ||
1552 | |||
1553 | if (op->state->received_total > 8 && op->state->received_fresh < op->state->received_total / 3) | ||
1554 | { | ||
1555 | /* The other peer gave us lots of old elements, there's something wrong. */ | ||
1556 | GNUNET_break_op (0); | ||
1557 | fail_union_operation (op); | ||
1558 | return; | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | /** | ||
1312 | * Send offers (for GNUNET_Hash-es) in response | 1563 | * Send offers (for GNUNET_Hash-es) in response |
1313 | * to inquiries (for IBF_Key-s). | 1564 | * to inquiries (for IBF_Key-s). |
1314 | * | 1565 | * |
@@ -1355,7 +1606,116 @@ handle_p2p_inquiry (void *cls, | |||
1355 | 1606 | ||
1356 | 1607 | ||
1357 | /** | 1608 | /** |
1358 | * FIXME | 1609 | * Iterator over hash map entries, called to |
1610 | * destroy the linked list of colliding ibf key entries. | ||
1611 | * | ||
1612 | * @param cls closure | ||
1613 | * @param key current key code | ||
1614 | * @param value value in the hash map | ||
1615 | * @return #GNUNET_YES if we should continue to iterate, | ||
1616 | * #GNUNET_NO if not. | ||
1617 | */ | ||
1618 | static int | ||
1619 | send_missing_elements_iter (void *cls, | ||
1620 | uint32_t key, | ||
1621 | void *value) | ||
1622 | { | ||
1623 | struct Operation *op = cls; | ||
1624 | struct KeyEntry *ke = value; | ||
1625 | struct GNUNET_MQ_Envelope *ev; | ||
1626 | struct GNUNET_SET_ElementMessage *emsg; | ||
1627 | struct ElementEntry *ee = ke->element; | ||
1628 | |||
1629 | if (GNUNET_YES == ke->received) | ||
1630 | return GNUNET_YES; | ||
1631 | |||
1632 | ev = GNUNET_MQ_msg_extra (emsg, ee->element.size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT); | ||
1633 | GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size); | ||
1634 | emsg->reserved = htons (0); | ||
1635 | emsg->element_type = htons (ee->element.element_type); | ||
1636 | GNUNET_MQ_send (op->mq, ev); | ||
1637 | |||
1638 | return GNUNET_YES; | ||
1639 | } | ||
1640 | |||
1641 | |||
1642 | /** | ||
1643 | * Handle a | ||
1644 | * | ||
1645 | * @parem cls closure, a set union operation | ||
1646 | * @param mh the demand message | ||
1647 | */ | ||
1648 | static void | ||
1649 | handle_p2p_request_full (void *cls, | ||
1650 | const struct GNUNET_MessageHeader *mh) | ||
1651 | { | ||
1652 | struct Operation *op = cls; | ||
1653 | |||
1654 | if (PHASE_EXPECT_IBF != op->state->phase) | ||
1655 | { | ||
1656 | fail_union_operation (op); | ||
1657 | GNUNET_break_op (0); | ||
1658 | return; | ||
1659 | } | ||
1660 | |||
1661 | // FIXME: we need to check that our set is larger than the | ||
1662 | // byzantine_lower_bound by some threshold | ||
1663 | send_full_set (op); | ||
1664 | } | ||
1665 | |||
1666 | |||
1667 | /** | ||
1668 | * Handle a "full done" message. | ||
1669 | * | ||
1670 | * @parem cls closure, a set union operation | ||
1671 | * @param mh the demand message | ||
1672 | */ | ||
1673 | static void | ||
1674 | handle_p2p_full_done (void *cls, | ||
1675 | const struct GNUNET_MessageHeader *mh) | ||
1676 | { | ||
1677 | struct Operation *op = cls; | ||
1678 | |||
1679 | if (PHASE_EXPECT_IBF == op->state->phase) | ||
1680 | { | ||
1681 | struct GNUNET_MQ_Envelope *ev; | ||
1682 | |||
1683 | LOG (GNUNET_ERROR_TYPE_DEBUG, "got FULL DONE, sending elements that other peer is missing\n"); | ||
1684 | |||
1685 | /* send all the elements that did not come from the remote peer */ | ||
1686 | GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element, | ||
1687 | &send_missing_elements_iter, | ||
1688 | op); | ||
1689 | |||
1690 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); | ||
1691 | GNUNET_MQ_send (op->mq, ev); | ||
1692 | op->state->phase = PHASE_DONE; | ||
1693 | |||
1694 | /* we now wait until the other peer shuts the tunnel down*/ | ||
1695 | } | ||
1696 | else if (PHASE_FULL_SENDING == op->state->phase) | ||
1697 | { | ||
1698 | LOG (GNUNET_ERROR_TYPE_DEBUG, "got FULL DONE, finishing\n"); | ||
1699 | /* We sent the full set, and got the response for that. We're done. */ | ||
1700 | op->state->phase = PHASE_DONE; | ||
1701 | send_done_and_destroy (op); | ||
1702 | } | ||
1703 | else | ||
1704 | { | ||
1705 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handle full done phase is %u\n", (unsigned) op->state->phase); | ||
1706 | GNUNET_break_op (0); | ||
1707 | fail_union_operation (op); | ||
1708 | return; | ||
1709 | } | ||
1710 | } | ||
1711 | |||
1712 | |||
1713 | /** | ||
1714 | * Handle a demand by the other peer for elements based on a list | ||
1715 | * of GNUNET_HashCode-s. | ||
1716 | * | ||
1717 | * @parem cls closure, a set union operation | ||
1718 | * @param mh the demand message | ||
1359 | */ | 1719 | */ |
1360 | static void | 1720 | static void |
1361 | handle_p2p_demand (void *cls, | 1721 | handle_p2p_demand (void *cls, |
@@ -1607,6 +1967,9 @@ union_evaluate (struct Operation *op, | |||
1607 | else | 1967 | else |
1608 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1968 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1609 | "sent op request without context message\n"); | 1969 | "sent op request without context message\n"); |
1970 | |||
1971 | op->state->initial_size = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
1972 | initialize_key_to_element (op); | ||
1610 | } | 1973 | } |
1611 | 1974 | ||
1612 | 1975 | ||
@@ -1636,6 +1999,8 @@ union_accept (struct Operation *op) | |||
1636 | op->state->se = strata_estimator_dup (op->spec->set->state->se); | 1999 | op->state->se = strata_estimator_dup (op->spec->set->state->se); |
1637 | op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); | 2000 | op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); |
1638 | op->state->salt_receive = op->state->salt_send = 42; | 2001 | op->state->salt_receive = op->state->salt_send = 42; |
2002 | op->state->initial_size = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
2003 | initialize_key_to_element (op); | ||
1639 | /* kick off the operation */ | 2004 | /* kick off the operation */ |
1640 | send_strata_estimator (op); | 2005 | send_strata_estimator (op); |
1641 | } | 2006 | } |
@@ -1743,6 +2108,9 @@ union_handle_p2p_message (struct Operation *op, | |||
1743 | case GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS: | 2108 | case GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS: |
1744 | handle_p2p_elements (op, mh); | 2109 | handle_p2p_elements (op, mh); |
1745 | break; | 2110 | break; |
2111 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT: | ||
2112 | handle_p2p_full_element (op, mh); | ||
2113 | break; | ||
1746 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY: | 2114 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY: |
1747 | handle_p2p_inquiry (op, mh); | 2115 | handle_p2p_inquiry (op, mh); |
1748 | break; | 2116 | break; |
@@ -1755,6 +2123,12 @@ union_handle_p2p_message (struct Operation *op, | |||
1755 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND: | 2123 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND: |
1756 | handle_p2p_demand (op, mh); | 2124 | handle_p2p_demand (op, mh); |
1757 | break; | 2125 | break; |
2126 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE: | ||
2127 | handle_p2p_full_done (op, mh); | ||
2128 | break; | ||
2129 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL: | ||
2130 | handle_p2p_request_full (op, mh); | ||
2131 | break; | ||
1758 | default: | 2132 | default: |
1759 | /* Something wrong with cadet's message handlers? */ | 2133 | /* Something wrong with cadet's message handlers? */ |
1760 | GNUNET_assert (0); | 2134 | GNUNET_assert (0); |
diff --git a/src/set/gnunet-set-profiler.c b/src/set/gnunet-set-profiler.c index f89817ff5..971d9746a 100644 --- a/src/set/gnunet-set-profiler.c +++ b/src/set/gnunet-set-profiler.c | |||
@@ -58,6 +58,10 @@ static struct GNUNET_PeerIdentity local_peer; | |||
58 | 58 | ||
59 | static struct GNUNET_SET_ListenHandle *set_listener; | 59 | static struct GNUNET_SET_ListenHandle *set_listener; |
60 | 60 | ||
61 | static int byzantine; | ||
62 | static int force_delta; | ||
63 | static int force_full; | ||
64 | |||
61 | /** | 65 | /** |
62 | * Handle to the statistics service. | 66 | * Handle to the statistics service. |
63 | */ | 67 | */ |
@@ -215,6 +219,10 @@ set_listen_cb (void *cls, | |||
215 | const struct GNUNET_MessageHeader *context_msg, | 219 | const struct GNUNET_MessageHeader *context_msg, |
216 | struct GNUNET_SET_Request *request) | 220 | struct GNUNET_SET_Request *request) |
217 | { | 221 | { |
222 | /* max. 2 options plus terminator */ | ||
223 | struct GNUNET_SET_Option opts[3] = {0}; | ||
224 | unsigned int n_opts = 0; | ||
225 | |||
218 | if (NULL == request) | 226 | if (NULL == request) |
219 | { | 227 | { |
220 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 228 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -224,8 +232,24 @@ set_listen_cb (void *cls, | |||
224 | GNUNET_assert (NULL == info2.oh); | 232 | GNUNET_assert (NULL == info2.oh); |
225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 233 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
226 | "set listen cb called\n"); | 234 | "set listen cb called\n"); |
235 | if (byzantine) | ||
236 | { | ||
237 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_BYZANTINE }; | ||
238 | } | ||
239 | GNUNET_assert (!(force_full && force_delta)); | ||
240 | if (force_full) | ||
241 | { | ||
242 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_FULL }; | ||
243 | } | ||
244 | if (force_delta) | ||
245 | { | ||
246 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_DELTA }; | ||
247 | } | ||
248 | |||
249 | opts[n_opts].type = 0; | ||
227 | info2.oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_SYMMETRIC, | 250 | info2.oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_SYMMETRIC, |
228 | set_result_cb, &info2); | 251 | opts, |
252 | set_result_cb, &info2); | ||
229 | GNUNET_SET_commit (info2.oh, info2.set); | 253 | GNUNET_SET_commit (info2.oh, info2.set); |
230 | } | 254 | } |
231 | 255 | ||
@@ -291,6 +315,9 @@ run (void *cls, | |||
291 | { | 315 | { |
292 | unsigned int i; | 316 | unsigned int i; |
293 | struct GNUNET_HashCode hash; | 317 | struct GNUNET_HashCode hash; |
318 | /* max. 2 options plus terminator */ | ||
319 | struct GNUNET_SET_Option opts[3] = {0}; | ||
320 | unsigned int n_opts = 0; | ||
294 | 321 | ||
295 | config = cfg; | 322 | config = cfg; |
296 | 323 | ||
@@ -350,8 +377,26 @@ run (void *cls, | |||
350 | set_listener = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION, | 377 | set_listener = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION, |
351 | &app_id, set_listen_cb, NULL); | 378 | &app_id, set_listen_cb, NULL); |
352 | 379 | ||
380 | |||
381 | if (byzantine) | ||
382 | { | ||
383 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_BYZANTINE }; | ||
384 | } | ||
385 | GNUNET_assert (!(force_full && force_delta)); | ||
386 | if (force_full) | ||
387 | { | ||
388 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_FULL }; | ||
389 | } | ||
390 | if (force_delta) | ||
391 | { | ||
392 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_DELTA }; | ||
393 | } | ||
394 | |||
395 | opts[n_opts].type = 0; | ||
396 | |||
353 | info1.oh = GNUNET_SET_prepare (&local_peer, &app_id, NULL, | 397 | info1.oh = GNUNET_SET_prepare (&local_peer, &app_id, NULL, |
354 | GNUNET_SET_RESULT_SYMMETRIC, | 398 | GNUNET_SET_RESULT_SYMMETRIC, |
399 | opts, | ||
355 | set_result_cb, &info1); | 400 | set_result_cb, &info1); |
356 | GNUNET_SET_commit (info1.oh, info1.set); | 401 | GNUNET_SET_commit (info1.oh, info1.set); |
357 | GNUNET_SET_destroy (info1.set); | 402 | GNUNET_SET_destroy (info1.set); |
@@ -380,6 +425,15 @@ main (int argc, char **argv) | |||
380 | { 'B', "num-second", NULL, | 425 | { 'B', "num-second", NULL, |
381 | gettext_noop ("number of values"), | 426 | gettext_noop ("number of values"), |
382 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_b }, | 427 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_b }, |
428 | { 'b', "byzantine", NULL, | ||
429 | gettext_noop ("use byzantine mode"), | ||
430 | GNUNET_NO, &GNUNET_GETOPT_set_one, &byzantine }, | ||
431 | { 'f', "force-full", NULL, | ||
432 | gettext_noop ("force sending full set"), | ||
433 | GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_full }, | ||
434 | { 'd', "force-delta", NULL, | ||
435 | gettext_noop ("number delta operation"), | ||
436 | GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_delta }, | ||
383 | { 'C', "num-common", NULL, | 437 | { 'C', "num-common", NULL, |
384 | gettext_noop ("number of values"), | 438 | gettext_noop ("number of values"), |
385 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_c }, | 439 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_c }, |
diff --git a/src/set/set.h b/src/set/set.h index f31216cb8..207f098bc 100644 --- a/src/set/set.h +++ b/src/set/set.h | |||
@@ -102,6 +102,30 @@ struct GNUNET_SET_AcceptMessage | |||
102 | * See `enum GNUNET_SET_ResultMode`. | 102 | * See `enum GNUNET_SET_ResultMode`. |
103 | */ | 103 | */ |
104 | uint32_t result_mode GNUNET_PACKED; | 104 | uint32_t result_mode GNUNET_PACKED; |
105 | |||
106 | /** | ||
107 | * Always use delta operation instead of sending full sets, | ||
108 | * even it it's less efficient. | ||
109 | */ | ||
110 | uint8_t force_delta; | ||
111 | |||
112 | /** | ||
113 | * Always send full sets, even if delta operations would | ||
114 | * be more efficient. | ||
115 | */ | ||
116 | uint8_t force_full; | ||
117 | |||
118 | /** | ||
119 | * #GNUNET_YES to fail operations where Byzantine faults | ||
120 | * are suspected | ||
121 | */ | ||
122 | uint8_t byzantine; | ||
123 | |||
124 | /** | ||
125 | * Lower bound for the set size, used only when | ||
126 | * byzantine mode is enabled. | ||
127 | */ | ||
128 | uint8_t byzantine_lower_bound; | ||
105 | }; | 129 | }; |
106 | 130 | ||
107 | 131 | ||
@@ -184,6 +208,30 @@ struct GNUNET_SET_EvaluateMessage | |||
184 | */ | 208 | */ |
185 | uint32_t request_id GNUNET_PACKED; | 209 | uint32_t request_id GNUNET_PACKED; |
186 | 210 | ||
211 | /** | ||
212 | * Always use delta operation instead of sending full sets, | ||
213 | * even it it's less efficient. | ||
214 | */ | ||
215 | uint8_t force_delta; | ||
216 | |||
217 | /** | ||
218 | * Always send full sets, even if delta operations would | ||
219 | * be more efficient. | ||
220 | */ | ||
221 | uint8_t force_full; | ||
222 | |||
223 | /** | ||
224 | * #GNUNET_YES to fail operations where Byzantine faults | ||
225 | * are suspected | ||
226 | */ | ||
227 | uint8_t byzantine; | ||
228 | |||
229 | /** | ||
230 | * Lower bound for the set size, used only when | ||
231 | * byzantine mode is enabled. | ||
232 | */ | ||
233 | uint8_t byzantine_lower_bound; | ||
234 | |||
187 | /* rest: context message, that is, application-specific | 235 | /* rest: context message, that is, application-specific |
188 | message to convince listener to pick up */ | 236 | message to convince listener to pick up */ |
189 | }; | 237 | }; |
diff --git a/src/set/set_api.c b/src/set/set_api.c index baeee6da0..2b09725e8 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c | |||
@@ -766,12 +766,14 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
766 | const struct GNUNET_HashCode *app_id, | 766 | const struct GNUNET_HashCode *app_id, |
767 | const struct GNUNET_MessageHeader *context_msg, | 767 | const struct GNUNET_MessageHeader *context_msg, |
768 | enum GNUNET_SET_ResultMode result_mode, | 768 | enum GNUNET_SET_ResultMode result_mode, |
769 | struct GNUNET_SET_Option options[], | ||
769 | GNUNET_SET_ResultIterator result_cb, | 770 | GNUNET_SET_ResultIterator result_cb, |
770 | void *result_cls) | 771 | void *result_cls) |
771 | { | 772 | { |
772 | struct GNUNET_MQ_Envelope *mqm; | 773 | struct GNUNET_MQ_Envelope *mqm; |
773 | struct GNUNET_SET_OperationHandle *oh; | 774 | struct GNUNET_SET_OperationHandle *oh; |
774 | struct GNUNET_SET_EvaluateMessage *msg; | 775 | struct GNUNET_SET_EvaluateMessage *msg; |
776 | struct GNUNET_SET_Option *opt; | ||
775 | 777 | ||
776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 778 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
777 | "Client prepares set operation (%d)\n", | 779 | "Client prepares set operation (%d)\n", |
@@ -785,6 +787,25 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
785 | msg->app_id = *app_id; | 787 | msg->app_id = *app_id; |
786 | msg->result_mode = htonl (result_mode); | 788 | msg->result_mode = htonl (result_mode); |
787 | msg->target_peer = *other_peer; | 789 | msg->target_peer = *other_peer; |
790 | for (opt = options; opt->type != 0; opt++) | ||
791 | { | ||
792 | switch (opt->type) | ||
793 | { | ||
794 | case GNUNET_SET_OPTION_BYZANTINE: | ||
795 | msg->byzantine = GNUNET_YES; | ||
796 | msg->byzantine_lower_bound = opt->v.num; | ||
797 | break; | ||
798 | case GNUNET_SET_OPTION_FORCE_FULL: | ||
799 | msg->force_full = GNUNET_YES; | ||
800 | break; | ||
801 | case GNUNET_SET_OPTION_FORCE_DELTA: | ||
802 | msg->force_delta = GNUNET_YES; | ||
803 | break; | ||
804 | default: | ||
805 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
806 | "Option with type %d not recognized\n", (int) opt->type); | ||
807 | } | ||
808 | } | ||
788 | oh->conclude_mqm = mqm; | 809 | oh->conclude_mqm = mqm; |
789 | oh->request_id_addr = &msg->request_id; | 810 | oh->request_id_addr = &msg->request_id; |
790 | 811 | ||
@@ -1006,6 +1027,7 @@ GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh) | |||
1006 | struct GNUNET_SET_OperationHandle * | 1027 | struct GNUNET_SET_OperationHandle * |
1007 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, | 1028 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, |
1008 | enum GNUNET_SET_ResultMode result_mode, | 1029 | enum GNUNET_SET_ResultMode result_mode, |
1030 | struct GNUNET_SET_Option options[], | ||
1009 | GNUNET_SET_ResultIterator result_cb, | 1031 | GNUNET_SET_ResultIterator result_cb, |
1010 | void *result_cls) | 1032 | void *result_cls) |
1011 | { | 1033 | { |
diff --git a/src/set/test_set.conf b/src/set/test_set.conf index 69e7f5c52..30ccbde55 100644 --- a/src/set/test_set.conf +++ b/src/set/test_set.conf | |||
@@ -5,7 +5,7 @@ GNUNET_TEST_HOME = /tmp/test-gnunet-set/ | |||
5 | 5 | ||
6 | [set] | 6 | [set] |
7 | AUTOSTART = YES | 7 | AUTOSTART = YES |
8 | # PREFIX = valgrind | 8 | PREFIX = valgrind |
9 | #PREFIX = valgrind --leak-check=full | 9 | #PREFIX = valgrind --leak-check=full |
10 | #PREFIX = gdbserver :1234 | 10 | #PREFIX = gdbserver :1234 |
11 | OPTIONS = -L INFO | 11 | OPTIONS = -L INFO |
diff --git a/src/set/test_set_api.c b/src/set/test_set_api.c index 21af45f8a..4bc6bd1c3 100644 --- a/src/set/test_set_api.c +++ b/src/set/test_set_api.c | |||
@@ -149,6 +149,7 @@ listen_cb (void *cls, | |||
149 | listen_handle = NULL; | 149 | listen_handle = NULL; |
150 | oh2 = GNUNET_SET_accept (request, | 150 | oh2 = GNUNET_SET_accept (request, |
151 | GNUNET_SET_RESULT_ADDED, | 151 | GNUNET_SET_RESULT_ADDED, |
152 | (struct GNUNET_SET_Option[]) { 0 }, | ||
152 | &result_cb_set2, | 153 | &result_cb_set2, |
153 | NULL); | 154 | NULL); |
154 | GNUNET_SET_commit (oh2, | 155 | GNUNET_SET_commit (oh2, |
@@ -179,6 +180,7 @@ start (void *cls) | |||
179 | &app_id, | 180 | &app_id, |
180 | &context_msg, | 181 | &context_msg, |
181 | GNUNET_SET_RESULT_ADDED, | 182 | GNUNET_SET_RESULT_ADDED, |
183 | (struct GNUNET_SET_Option[]) { 0 }, | ||
182 | &result_cb_set1, | 184 | &result_cb_set1, |
183 | NULL); | 185 | NULL); |
184 | GNUNET_SET_commit (oh1, | 186 | GNUNET_SET_commit (oh1, |
@@ -378,6 +380,7 @@ run (void *cls, | |||
378 | &app_id, | 380 | &app_id, |
379 | NULL, | 381 | NULL, |
380 | GNUNET_SET_RESULT_ADDED, | 382 | GNUNET_SET_RESULT_ADDED, |
383 | (struct GNUNET_SET_Option[]) { 0 }, | ||
381 | NULL, | 384 | NULL, |
382 | NULL); | 385 | NULL); |
383 | 386 | ||
diff --git a/src/set/test_set_intersection_result_full.c b/src/set/test_set_intersection_result_full.c index b2d6ce8a9..cbe1ce149 100644 --- a/src/set/test_set_intersection_result_full.c +++ b/src/set/test_set_intersection_result_full.c | |||
@@ -133,6 +133,7 @@ listen_cb (void *cls, | |||
133 | listen_handle = NULL; | 133 | listen_handle = NULL; |
134 | oh2 = GNUNET_SET_accept (request, | 134 | oh2 = GNUNET_SET_accept (request, |
135 | GNUNET_SET_RESULT_FULL, | 135 | GNUNET_SET_RESULT_FULL, |
136 | (struct GNUNET_SET_Option[]) { 0 }, | ||
136 | &result_cb_set2, | 137 | &result_cb_set2, |
137 | NULL); | 138 | NULL); |
138 | GNUNET_SET_commit (oh2, | 139 | GNUNET_SET_commit (oh2, |
@@ -163,6 +164,7 @@ start (void *cls) | |||
163 | &app_id, | 164 | &app_id, |
164 | &context_msg, | 165 | &context_msg, |
165 | GNUNET_SET_RESULT_FULL, | 166 | GNUNET_SET_RESULT_FULL, |
167 | (struct GNUNET_SET_Option[]) { 0 }, | ||
166 | &result_cb_set1, | 168 | &result_cb_set1, |
167 | NULL); | 169 | NULL); |
168 | GNUNET_SET_commit (oh1, | 170 | GNUNET_SET_commit (oh1, |
diff --git a/src/set/test_set_union_result_symmetric.c b/src/set/test_set_union_result_symmetric.c index ab191a34a..8dff40ec0 100644 --- a/src/set/test_set_union_result_symmetric.c +++ b/src/set/test_set_union_result_symmetric.c | |||
@@ -184,6 +184,7 @@ listen_cb (void *cls, | |||
184 | listen_handle = NULL; | 184 | listen_handle = NULL; |
185 | oh2 = GNUNET_SET_accept (request, | 185 | oh2 = GNUNET_SET_accept (request, |
186 | GNUNET_SET_RESULT_SYMMETRIC, | 186 | GNUNET_SET_RESULT_SYMMETRIC, |
187 | (struct GNUNET_SET_Option[]) { 0 }, | ||
187 | &result_cb_set2, | 188 | &result_cb_set2, |
188 | NULL); | 189 | NULL); |
189 | GNUNET_SET_commit (oh2, | 190 | GNUNET_SET_commit (oh2, |
@@ -212,6 +213,7 @@ start (void *cls) | |||
212 | &app_id, | 213 | &app_id, |
213 | &context_msg, | 214 | &context_msg, |
214 | GNUNET_SET_RESULT_SYMMETRIC, | 215 | GNUNET_SET_RESULT_SYMMETRIC, |
216 | (struct GNUNET_SET_Option[]) { 0 }, | ||
215 | &result_cb_set1, NULL); | 217 | &result_cb_set1, NULL); |
216 | GNUNET_SET_commit (oh1, set1); | 218 | GNUNET_SET_commit (oh1, set1); |
217 | } | 219 | } |
diff --git a/src/testing/testing.c b/src/testing/testing.c index 043bdd7d2..bab7976ea 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c | |||
@@ -1633,7 +1633,9 @@ GNUNET_TESTING_service_run (const char *testdir, | |||
1633 | char *binary; | 1633 | char *binary; |
1634 | char *libexec_binary; | 1634 | char *libexec_binary; |
1635 | 1635 | ||
1636 | GNUNET_log_setup (testdir, "WARNING", NULL); | 1636 | GNUNET_log_setup (testdir, |
1637 | "WARNING", | ||
1638 | NULL); | ||
1637 | system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL, NULL); | 1639 | system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL, NULL); |
1638 | if (NULL == system) | 1640 | if (NULL == system) |
1639 | return 1; | 1641 | return 1; |
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 3952a728e..bbda715a2 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -1150,17 +1150,18 @@ set_incoming_quota (struct NeighbourMapEntry *n, | |||
1150 | sqm.header.size = htons (sizeof (struct GNUNET_ATS_SessionQuotaMessage)); | 1150 | sqm.header.size = htons (sizeof (struct GNUNET_ATS_SessionQuotaMessage)); |
1151 | sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA); | 1151 | sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA); |
1152 | sqm.quota = quota.value__; | 1152 | sqm.quota = quota.value__; |
1153 | (void) send_with_session (n, | 1153 | if (NULL != n->primary_address.session) |
1154 | &sqm, | 1154 | (void) send_with_session (n, |
1155 | sizeof (sqm), | 1155 | &sqm, |
1156 | UINT32_MAX - 1, | 1156 | sizeof (sqm), |
1157 | GNUNET_TIME_UNIT_FOREVER_REL, | 1157 | UINT32_MAX - 1, |
1158 | GNUNET_NO, | 1158 | GNUNET_TIME_UNIT_FOREVER_REL, |
1159 | NULL, NULL); | 1159 | GNUNET_NO, |
1160 | NULL, NULL); | ||
1160 | return; | 1161 | return; |
1161 | } | 1162 | } |
1162 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1163 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1163 | "Disconnecting peer `%4s' due to SET_QUOTA\n", | 1164 | "Disconnecting peer `%s' due to SET_QUOTA\n", |
1164 | GNUNET_i2s (&n->id)); | 1165 | GNUNET_i2s (&n->id)); |
1165 | if (GNUNET_YES == test_connected (n)) | 1166 | if (GNUNET_YES == test_connected (n)) |
1166 | GNUNET_STATISTICS_update (GST_stats, | 1167 | GNUNET_STATISTICS_update (GST_stats, |
diff --git a/src/util/mq.c b/src/util/mq.c index a8216d964..71619bda4 100644 --- a/src/util/mq.c +++ b/src/util/mq.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2012-2014 GNUnet e.V. | 3 | Copyright (C) 2012-2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -362,6 +362,7 @@ GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, | |||
362 | GNUNET_assert (NULL == ev->parent_queue); | 362 | GNUNET_assert (NULL == ev->parent_queue); |
363 | 363 | ||
364 | mq->queue_length++; | 364 | mq->queue_length++; |
365 | GNUNET_break (mq->queue_length < 10000); /* This would seem like a bug... */ | ||
365 | ev->parent_queue = mq; | 366 | ev->parent_queue = mq; |
366 | /* is the implementation busy? queue it! */ | 367 | /* is the implementation busy? queue it! */ |
367 | if ( (NULL != mq->current_envelope) || | 368 | if ( (NULL != mq->current_envelope) || |
diff --git a/src/util/os_installation.c b/src/util/os_installation.c index caceeea0c..1226c5966 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c | |||
@@ -823,9 +823,13 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
823 | #ifdef MINGW | 823 | #ifdef MINGW |
824 | char *binaryexe; | 824 | char *binaryexe; |
825 | 825 | ||
826 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); | 826 | GNUNET_asprintf (&binaryexe, |
827 | if ( (GNUNET_YES == GNUNET_STRINGS_path_is_absolute (binaryexe, GNUNET_NO, | 827 | "%s.exe", |
828 | NULL, NULL)) || | 828 | binary); |
829 | if ( (GNUNET_YES == | ||
830 | GNUNET_STRINGS_path_is_absolute (binaryexe, | ||
831 | GNUNET_NO, | ||
832 | NULL, NULL)) || | ||
829 | (0 == strncmp (binary, "./", 2)) ) | 833 | (0 == strncmp (binary, "./", 2)) ) |
830 | p = GNUNET_strdup (binaryexe); | 834 | p = GNUNET_strdup (binaryexe); |
831 | else | 835 | else |
@@ -840,16 +844,24 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
840 | } | 844 | } |
841 | GNUNET_free (binaryexe); | 845 | GNUNET_free (binaryexe); |
842 | #else | 846 | #else |
843 | if ( (GNUNET_YES == GNUNET_STRINGS_path_is_absolute (binary, GNUNET_NO, | 847 | if ( (GNUNET_YES == |
844 | NULL, NULL)) || | 848 | GNUNET_STRINGS_path_is_absolute (binary, |
849 | GNUNET_NO, | ||
850 | NULL, | ||
851 | NULL)) || | ||
845 | (0 == strncmp (binary, "./", 2)) ) | 852 | (0 == strncmp (binary, "./", 2)) ) |
853 | { | ||
846 | p = GNUNET_strdup (binary); | 854 | p = GNUNET_strdup (binary); |
855 | } | ||
847 | else | 856 | else |
848 | { | 857 | { |
849 | p = get_path_from_PATH (binary); | 858 | p = get_path_from_PATH (binary); |
850 | if (NULL != p) | 859 | if (NULL != p) |
851 | { | 860 | { |
852 | GNUNET_asprintf (&pf, "%s/%s", p, binary); | 861 | GNUNET_asprintf (&pf, |
862 | "%s/%s", | ||
863 | p, | ||
864 | binary); | ||
853 | GNUNET_free (p); | 865 | GNUNET_free (p); |
854 | p = pf; | 866 | p = pf; |
855 | } | 867 | } |
@@ -862,9 +874,12 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
862 | binary); | 874 | binary); |
863 | return GNUNET_SYSERR; | 875 | return GNUNET_SYSERR; |
864 | } | 876 | } |
865 | if (0 != ACCESS (p, X_OK)) | 877 | if (0 != ACCESS (p, |
878 | X_OK)) | ||
866 | { | 879 | { |
867 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", p); | 880 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, |
881 | "access", | ||
882 | p); | ||
868 | GNUNET_free (p); | 883 | GNUNET_free (p); |
869 | return GNUNET_SYSERR; | 884 | return GNUNET_SYSERR; |
870 | } | 885 | } |
@@ -873,22 +888,30 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
873 | { | 888 | { |
874 | /* as we run as root, we don't insist on SUID */ | 889 | /* as we run as root, we don't insist on SUID */ |
875 | GNUNET_free (p); | 890 | GNUNET_free (p); |
876 | return GNUNET_OK; | 891 | return GNUNET_YES; |
877 | } | 892 | } |
878 | #endif | 893 | #endif |
879 | if (0 != STAT (p, &statbuf)) | 894 | if (0 != STAT (p, |
895 | &statbuf)) | ||
880 | { | 896 | { |
881 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", p); | 897 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, |
898 | "stat", | ||
899 | p); | ||
882 | GNUNET_free (p); | 900 | GNUNET_free (p); |
883 | return GNUNET_SYSERR; | 901 | return GNUNET_SYSERR; |
884 | } | 902 | } |
885 | if (check_suid){ | 903 | if (check_suid) |
904 | { | ||
886 | #ifndef MINGW | 905 | #ifndef MINGW |
887 | if ((0 != (statbuf.st_mode & S_ISUID)) && (0 == statbuf.st_uid)) | 906 | if ( (0 != (statbuf.st_mode & S_ISUID)) && |
907 | (0 == statbuf.st_uid) ) | ||
888 | { | 908 | { |
889 | GNUNET_free (p); | 909 | GNUNET_free (p); |
890 | return GNUNET_YES; | 910 | return GNUNET_YES; |
891 | } | 911 | } |
912 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
913 | _("Binary `%s' exists, but is not SUID\n"), | ||
914 | p); | ||
892 | /* binary exists, but not SUID */ | 915 | /* binary exists, but not SUID */ |
893 | #else | 916 | #else |
894 | STARTUPINFO start; | 917 | STARTUPINFO start; |
diff --git a/src/util/service_new.c b/src/util/service_new.c index a832b070c..987fb1c3b 100644 --- a/src/util/service_new.c +++ b/src/util/service_new.c | |||
@@ -1996,8 +1996,9 @@ service_mq_send (struct GNUNET_MQ_Handle *mq, | |||
1996 | { | 1996 | { |
1997 | struct GNUNET_SERVICE_Client *client = impl_state; | 1997 | struct GNUNET_SERVICE_Client *client = impl_state; |
1998 | 1998 | ||
1999 | if (NULL != client->drop_task) | ||
2000 | return; /* we're going down right now, do not try to send */ | ||
1999 | GNUNET_assert (NULL == client->send_task); | 2001 | GNUNET_assert (NULL == client->send_task); |
2000 | GNUNET_assert (NULL == client->drop_task); | ||
2001 | client->msg = msg; | 2002 | client->msg = msg; |
2002 | client->msg_pos = 0; | 2003 | client->msg_pos = 0; |
2003 | client->send_task | 2004 | client->send_task |
@@ -2466,6 +2467,10 @@ finish_client_drop (void *cls) | |||
2466 | struct GNUNET_SERVICE_Client *c = cls; | 2467 | struct GNUNET_SERVICE_Client *c = cls; |
2467 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2468 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2468 | 2469 | ||
2470 | c->drop_task = NULL; | ||
2471 | GNUNET_assert (NULL == c->send_task); | ||
2472 | GNUNET_assert (NULL == c->recv_task); | ||
2473 | GNUNET_assert (NULL == c->warn_task); | ||
2469 | GNUNET_MST_destroy (c->mst); | 2474 | GNUNET_MST_destroy (c->mst); |
2470 | GNUNET_MQ_destroy (c->mq); | 2475 | GNUNET_MQ_destroy (c->mq); |
2471 | if (GNUNET_NO == c->persist) | 2476 | if (GNUNET_NO == c->persist) |