diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-01-25 15:22:18 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-01-25 15:22:18 +0000 |
commit | 43d558efd13a3245e65efd0acdc9c4ba59cd2bee (patch) | |
tree | 469de47f10a4aba6742b360b8622708d60587659 /src/exit | |
parent | 07ab625068b62afc532a78534018f6579697a307 (diff) | |
download | gnunet-43d558efd13a3245e65efd0acdc9c4ba59cd2bee.tar.gz gnunet-43d558efd13a3245e65efd0acdc9c4ba59cd2bee.zip |
add DNS exit for mesh to gnunet-daemon-exit
Diffstat (limited to 'src/exit')
-rw-r--r-- | src/exit/Makefile.am | 1 | ||||
-rw-r--r-- | src/exit/exit.conf | 12 | ||||
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 704 |
3 files changed, 538 insertions, 179 deletions
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am index 2da59f14a..be3a66a34 100644 --- a/src/exit/Makefile.am +++ b/src/exit/Makefile.am | |||
@@ -36,6 +36,7 @@ gnunet_helper_exit_SOURCES = \ | |||
36 | gnunet_daemon_exit_SOURCES = \ | 36 | gnunet_daemon_exit_SOURCES = \ |
37 | gnunet-daemon-exit.c exit.h | 37 | gnunet-daemon-exit.c exit.h |
38 | gnunet_daemon_exit_LDADD = \ | 38 | gnunet_daemon_exit_LDADD = \ |
39 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ | ||
39 | $(top_builddir)/src/core/libgnunetcore.la \ | 40 | $(top_builddir)/src/core/libgnunetcore.la \ |
40 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 41 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
41 | $(top_builddir)/src/tun/libgnunettun.la \ | 42 | $(top_builddir)/src/tun/libgnunettun.la \ |
diff --git a/src/exit/exit.conf b/src/exit/exit.conf index f8f0764f7..aadcee47f 100644 --- a/src/exit/exit.conf +++ b/src/exit/exit.conf | |||
@@ -43,6 +43,18 @@ EXIT_IPV4 = NO | |||
43 | # Set this to YES to allow exiting this system via IPv6 to the Internet | 43 | # Set this to YES to allow exiting this system via IPv6 to the Internet |
44 | EXIT_IPV6 = NO | 44 | EXIT_IPV6 = NO |
45 | 45 | ||
46 | # This option should be set to YES to allow the DNS service to | ||
47 | # perform lookups against the locally configured DNS resolver. | ||
48 | # (set to "NO" if no normal ISP is locally available and thus | ||
49 | # requests for normal ".com"/".org"/etc. must be routed via | ||
50 | # the GNUnet VPN (the GNUNET PT daemon then needs to be configured | ||
51 | # to intercept and route DNS queries via mesh). | ||
52 | # Set this to YES to allow using this system for DNS queries. | ||
53 | EXIT_DNS = NO | ||
54 | |||
55 | # Set this to an IPv4 or IPv6 address of a DNS resolver to use for DNS queries | ||
56 | DNS_RESOLVER = 8.8.8.8 | ||
57 | |||
46 | # For IPv4-services offered by this peer, we need to at least enable IPv4 | 58 | # For IPv4-services offered by this peer, we need to at least enable IPv4 |
47 | ENABLE_IPV4 = YES | 59 | ENABLE_IPV4 = YES |
48 | 60 | ||
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 5f60ea4cd..92f38665b 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include "gnunet_protocols.h" | 39 | #include "gnunet_protocols.h" |
40 | #include "gnunet_applications.h" | 40 | #include "gnunet_applications.h" |
41 | #include "gnunet_mesh_service.h" | 41 | #include "gnunet_mesh_service.h" |
42 | #include "gnunet_dnsparser_lib.h" | ||
43 | #include "gnunet_dnsstub_lib.h" | ||
42 | #include "gnunet_statistics_service.h" | 44 | #include "gnunet_statistics_service.h" |
43 | #include "gnunet_constants.h" | 45 | #include "gnunet_constants.h" |
44 | #include "gnunet_tun_lib.h" | 46 | #include "gnunet_tun_lib.h" |
@@ -59,6 +61,14 @@ | |||
59 | 61 | ||
60 | 62 | ||
61 | /** | 63 | /** |
64 | * Generic logging shorthand | ||
65 | */ | ||
66 | #define LOG(kind, ...) \ | ||
67 | GNUNET_log_from (kind, "exit", __VA_ARGS__); | ||
68 | |||
69 | |||
70 | |||
71 | /** | ||
62 | * Information about an address. | 72 | * Information about an address. |
63 | */ | 73 | */ |
64 | struct SocketAddress | 74 | struct SocketAddress |
@@ -196,39 +206,85 @@ struct TunnelState | |||
196 | struct GNUNET_MESH_Tunnel *tunnel; | 206 | struct GNUNET_MESH_Tunnel *tunnel; |
197 | 207 | ||
198 | /** | 208 | /** |
199 | * Heap node for this state in the connections_heap. | 209 | * Active tunnel transmission request (or NULL). |
200 | */ | 210 | */ |
201 | struct GNUNET_CONTAINER_HeapNode *heap_node; | 211 | struct GNUNET_MESH_TransmitHandle *th; |
202 | 212 | ||
203 | /** | 213 | /** |
204 | * Key this state has in the connections_map. | 214 | * GNUNET_NO if this is a tunnel for TCP/UDP, |
215 | * GNUNET_YES if this is a tunnel for DNS, | ||
216 | * GNUNET_SYSERR if the tunnel is not yet initialized. | ||
205 | */ | 217 | */ |
206 | struct GNUNET_HashCode state_key; | 218 | int is_dns; |
207 | 219 | ||
208 | /** | 220 | union |
209 | * Associated service record, or NULL for no service. | 221 | { |
210 | */ | 222 | struct |
211 | struct LocalService *serv; | 223 | { |
212 | 224 | ||
213 | /** | 225 | /** |
214 | * Head of DLL of messages for this tunnel. | 226 | * Heap node for this state in the connections_heap. |
215 | */ | 227 | */ |
216 | struct TunnelMessageQueue *head; | 228 | struct GNUNET_CONTAINER_HeapNode *heap_node; |
229 | |||
230 | /** | ||
231 | * Key this state has in the connections_map. | ||
232 | */ | ||
233 | struct GNUNET_HashCode state_key; | ||
234 | |||
235 | /** | ||
236 | * Associated service record, or NULL for no service. | ||
237 | */ | ||
238 | struct LocalService *serv; | ||
239 | |||
240 | /** | ||
241 | * Head of DLL of messages for this tunnel. | ||
242 | */ | ||
243 | struct TunnelMessageQueue *head; | ||
244 | |||
245 | /** | ||
246 | * Tail of DLL of messages for this tunnel. | ||
247 | */ | ||
248 | struct TunnelMessageQueue *tail; | ||
249 | |||
250 | /** | ||
251 | * Primary redirection information for this connection. | ||
252 | */ | ||
253 | struct RedirectInformation ri; | ||
254 | } tcp_udp; | ||
217 | 255 | ||
218 | /** | 256 | struct |
219 | * Tail of DLL of messages for this tunnel. | 257 | { |
220 | */ | ||
221 | struct TunnelMessageQueue *tail; | ||
222 | 258 | ||
223 | /** | 259 | /** |
224 | * Active tunnel transmission request (or NULL). | 260 | * DNS reply ready for transmission. |
225 | */ | 261 | */ |
226 | struct GNUNET_MESH_TransmitHandle *th; | 262 | char *reply; |
263 | |||
264 | /** | ||
265 | * Socket we are using to transmit this request (must match if we receive | ||
266 | * a response). | ||
267 | */ | ||
268 | struct GNUNET_DNSSTUB_RequestSocket *rs; | ||
269 | |||
270 | /** | ||
271 | * Number of bytes in 'reply'. | ||
272 | */ | ||
273 | size_t reply_length; | ||
274 | |||
275 | /** | ||
276 | * Original DNS request ID as used by the client. | ||
277 | */ | ||
278 | uint16_t original_id; | ||
279 | |||
280 | /** | ||
281 | * DNS request ID that we used for forwarding. | ||
282 | */ | ||
283 | uint16_t my_id; | ||
284 | |||
285 | } dns; | ||
227 | 286 | ||
228 | /** | 287 | } specifics; |
229 | * Primary redirection information for this connection. | ||
230 | */ | ||
231 | struct RedirectInformation ri; | ||
232 | 288 | ||
233 | }; | 289 | }; |
234 | 290 | ||
@@ -273,7 +329,6 @@ static struct in_addr exit_ipv4addr; | |||
273 | */ | 329 | */ |
274 | static struct in_addr exit_ipv4mask; | 330 | static struct in_addr exit_ipv4mask; |
275 | 331 | ||
276 | |||
277 | /** | 332 | /** |
278 | * Statistics. | 333 | * Statistics. |
279 | */ | 334 | */ |
@@ -311,6 +366,16 @@ static struct GNUNET_CONTAINER_MultiHashMap *udp_services; | |||
311 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_services; | 366 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_services; |
312 | 367 | ||
313 | /** | 368 | /** |
369 | * Array of all open DNS requests from tunnels. | ||
370 | */ | ||
371 | static struct TunnelState *tunnels[UINT16_MAX + 1]; | ||
372 | |||
373 | /** | ||
374 | * Handle to the DNS Stub resolver. | ||
375 | */ | ||
376 | static struct GNUNET_DNSSTUB_Context *dnsstub; | ||
377 | |||
378 | /** | ||
314 | * Are we an IPv4-exit? | 379 | * Are we an IPv4-exit? |
315 | */ | 380 | */ |
316 | static int ipv4_exit; | 381 | static int ipv4_exit; |
@@ -332,6 +397,160 @@ static int ipv6_enabled; | |||
332 | 397 | ||
333 | 398 | ||
334 | /** | 399 | /** |
400 | * We got a reply from DNS for a request of a MESH tunnel. Send it | ||
401 | * via the tunnel (after changing the request ID back). | ||
402 | * | ||
403 | * @param cls the 'struct TunnelState' | ||
404 | * @param size number of bytes available in buf | ||
405 | * @param buf where to copy the reply | ||
406 | * @return number of bytes written to buf | ||
407 | */ | ||
408 | static size_t | ||
409 | transmit_reply_to_mesh (void *cls, | ||
410 | size_t size, | ||
411 | void *buf) | ||
412 | { | ||
413 | struct TunnelState *ts = cls; | ||
414 | size_t off; | ||
415 | size_t ret; | ||
416 | char *cbuf = buf; | ||
417 | struct GNUNET_MessageHeader hdr; | ||
418 | struct GNUNET_TUN_DnsHeader dns; | ||
419 | |||
420 | GNUNET_assert (GNUNET_YES == ts->is_dns); | ||
421 | ts->th = NULL; | ||
422 | GNUNET_assert (ts->specifics.dns.reply != NULL); | ||
423 | if (size == 0) | ||
424 | return 0; | ||
425 | ret = sizeof (struct GNUNET_MessageHeader) + ts->specifics.dns.reply_length; | ||
426 | GNUNET_assert (ret <= size); | ||
427 | hdr.size = htons (ret); | ||
428 | hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET); | ||
429 | memcpy (&dns, ts->specifics.dns.reply, sizeof (dns)); | ||
430 | dns.id = ts->specifics.dns.original_id; | ||
431 | off = 0; | ||
432 | memcpy (&cbuf[off], &hdr, sizeof (hdr)); | ||
433 | off += sizeof (hdr); | ||
434 | memcpy (&cbuf[off], &dns, sizeof (dns)); | ||
435 | off += sizeof (dns); | ||
436 | memcpy (&cbuf[off], &ts->specifics.dns.reply[sizeof (dns)], ts->specifics.dns.reply_length - sizeof (dns)); | ||
437 | off += ts->specifics.dns.reply_length - sizeof (dns); | ||
438 | GNUNET_free (ts->specifics.dns.reply); | ||
439 | ts->specifics.dns.reply = NULL; | ||
440 | ts->specifics.dns.reply_length = 0; | ||
441 | GNUNET_assert (ret == off); | ||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * Callback called from DNSSTUB resolver when a resolution | ||
448 | * succeeded. | ||
449 | * | ||
450 | * @param cls NULL | ||
451 | * @param rs the socket that received the response | ||
452 | * @param dns the response itself | ||
453 | * @param r number of bytes in dns | ||
454 | */ | ||
455 | static void | ||
456 | process_dns_result (void *cls, | ||
457 | struct GNUNET_DNSSTUB_RequestSocket *rs, | ||
458 | const struct GNUNET_TUN_DnsHeader *dns, | ||
459 | size_t r) | ||
460 | { | ||
461 | struct TunnelState *ts; | ||
462 | |||
463 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
464 | "Processing DNS result from stub resolver\n"); | ||
465 | GNUNET_assert (NULL == cls); | ||
466 | /* Handle case that this is a reply to a request from a MESH DNS tunnel */ | ||
467 | ts = tunnels[dns->id]; | ||
468 | if ( (NULL == ts) || | ||
469 | (ts->specifics.dns.rs != rs) ) | ||
470 | return; | ||
471 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
472 | "Got a response from the stub resolver for DNS request received via MESH!\n"); | ||
473 | tunnels[dns->id] = NULL; | ||
474 | GNUNET_free_non_null (ts->specifics.dns.reply); | ||
475 | ts->specifics.dns.reply = GNUNET_malloc (r); | ||
476 | ts->specifics.dns.reply_length = r; | ||
477 | memcpy (ts->specifics.dns.reply, dns, r); | ||
478 | if (NULL != ts->th) | ||
479 | GNUNET_MESH_notify_transmit_ready_cancel (ts->th); | ||
480 | ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, | ||
481 | GNUNET_NO, | ||
482 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
483 | NULL, | ||
484 | sizeof (struct GNUNET_MessageHeader) + r, | ||
485 | &transmit_reply_to_mesh, | ||
486 | ts); | ||
487 | } | ||
488 | |||
489 | |||
490 | /** | ||
491 | * Process a request via mesh to perform a DNS query. | ||
492 | * | ||
493 | * @param cls closure, NULL | ||
494 | * @param tunnel connection to the other end | ||
495 | * @param tunnel_ctx pointer to our 'struct TunnelState *' | ||
496 | * @param sender who sent the message | ||
497 | * @param message the actual message | ||
498 | * @param atsi performance data for the connection | ||
499 | * @return GNUNET_OK to keep the connection open, | ||
500 | * GNUNET_SYSERR to close it (signal serious error) | ||
501 | */ | ||
502 | static int | ||
503 | receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
504 | void **tunnel_ctx, | ||
505 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
506 | const struct GNUNET_MessageHeader *message, | ||
507 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
508 | { | ||
509 | struct TunnelState *ts = *tunnel_ctx; | ||
510 | const struct GNUNET_TUN_DnsHeader *dns; | ||
511 | size_t mlen = ntohs (message->size); | ||
512 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); | ||
513 | char buf[dlen] GNUNET_ALIGN; | ||
514 | struct GNUNET_TUN_DnsHeader *dout; | ||
515 | |||
516 | if (NULL == dnsstub) | ||
517 | return GNUNET_SYSERR; | ||
518 | if (GNUNET_NO == ts->is_dns) | ||
519 | { | ||
520 | GNUNET_break_op (0); | ||
521 | return GNUNET_SYSERR; | ||
522 | } | ||
523 | if (GNUNET_SYSERR == ts->is_dns) | ||
524 | { | ||
525 | /* tunnel is DNS from now on */ | ||
526 | ts->is_dns = GNUNET_YES; | ||
527 | } | ||
528 | if (dlen < sizeof (struct GNUNET_TUN_DnsHeader)) | ||
529 | { | ||
530 | GNUNET_break_op (0); | ||
531 | return GNUNET_SYSERR; | ||
532 | } | ||
533 | dns = (const struct GNUNET_TUN_DnsHeader *) &message[1]; | ||
534 | ts->specifics.dns.original_id = dns->id; | ||
535 | if (tunnels[ts->specifics.dns.my_id] == ts) | ||
536 | tunnels[ts->specifics.dns.my_id] = NULL; | ||
537 | ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
538 | UINT16_MAX + 1); | ||
539 | tunnels[ts->specifics.dns.my_id] = ts; | ||
540 | memcpy (buf, dns, dlen); | ||
541 | dout = (struct GNUNET_TUN_DnsHeader *) buf; | ||
542 | dout->id = ts->specifics.dns.my_id; | ||
543 | ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve2 (dnsstub, | ||
544 | buf, dlen, | ||
545 | &process_dns_result, | ||
546 | NULL); | ||
547 | if (NULL == ts->specifics.dns.rs) | ||
548 | return GNUNET_SYSERR; | ||
549 | return GNUNET_OK; | ||
550 | } | ||
551 | |||
552 | |||
553 | /** | ||
335 | * Given IP information about a connection, calculate the respective | 554 | * Given IP information about a connection, calculate the respective |
336 | * hash we would use for the 'connections_map'. | 555 | * hash we would use for the 'connections_map'. |
337 | * | 556 | * |
@@ -439,7 +658,7 @@ get_redirect_state (int af, | |||
439 | /* Mark this connection as freshly used */ | 658 | /* Mark this connection as freshly used */ |
440 | if (NULL == state_key) | 659 | if (NULL == state_key) |
441 | GNUNET_CONTAINER_heap_update_cost (connections_heap, | 660 | GNUNET_CONTAINER_heap_update_cost (connections_heap, |
442 | state->heap_node, | 661 | state->specifics.tcp_udp.heap_node, |
443 | GNUNET_TIME_absolute_get ().abs_value); | 662 | GNUNET_TIME_absolute_get ().abs_value); |
444 | return state; | 663 | return state; |
445 | } | 664 | } |
@@ -542,7 +761,7 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf) | |||
542 | struct TunnelMessageQueue *tnq; | 761 | struct TunnelMessageQueue *tnq; |
543 | 762 | ||
544 | s->th = NULL; | 763 | s->th = NULL; |
545 | tnq = s->head; | 764 | tnq = s->specifics.tcp_udp.head; |
546 | if (NULL == tnq) | 765 | if (NULL == tnq) |
547 | return 0; | 766 | return 0; |
548 | if (0 == size) | 767 | if (0 == size) |
@@ -559,11 +778,11 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf) | |||
559 | GNUNET_assert (size >= tnq->len); | 778 | GNUNET_assert (size >= tnq->len); |
560 | memcpy (buf, tnq->payload, tnq->len); | 779 | memcpy (buf, tnq->payload, tnq->len); |
561 | size = tnq->len; | 780 | size = tnq->len; |
562 | GNUNET_CONTAINER_DLL_remove (s->head, | 781 | GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head, |
563 | s->tail, | 782 | s->specifics.tcp_udp.tail, |
564 | tnq); | 783 | tnq); |
565 | GNUNET_free (tnq); | 784 | GNUNET_free (tnq); |
566 | if (NULL != (tnq = s->head)) | 785 | if (NULL != (tnq = s->specifics.tcp_udp.head)) |
567 | s->th = GNUNET_MESH_notify_transmit_ready (tunnel, | 786 | s->th = GNUNET_MESH_notify_transmit_ready (tunnel, |
568 | GNUNET_NO /* corking */, | 787 | GNUNET_NO /* corking */, |
569 | GNUNET_TIME_UNIT_FOREVER_REL, | 788 | GNUNET_TIME_UNIT_FOREVER_REL, |
@@ -592,7 +811,7 @@ send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel, | |||
592 | 811 | ||
593 | s = GNUNET_MESH_tunnel_get_data (mesh_tunnel); | 812 | s = GNUNET_MESH_tunnel_get_data (mesh_tunnel); |
594 | GNUNET_assert (NULL != s); | 813 | GNUNET_assert (NULL != s); |
595 | GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq); | 814 | GNUNET_CONTAINER_DLL_insert_tail (s->specifics.tcp_udp.head, s->specifics.tcp_udp.tail, tnq); |
596 | if (NULL == s->th) | 815 | if (NULL == s->th) |
597 | s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel, | 816 | s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel, |
598 | GNUNET_NO /* cork */, | 817 | GNUNET_NO /* cork */, |
@@ -1220,7 +1439,7 @@ setup_fresh_address (int af, | |||
1220 | * cleaning up 'old' states. | 1439 | * cleaning up 'old' states. |
1221 | * | 1440 | * |
1222 | * @param state skeleton state to setup a record for; should | 1441 | * @param state skeleton state to setup a record for; should |
1223 | * 'state->ri.remote_address' filled in so that | 1442 | * 'state->specifics.tcp_udp.ri.remote_address' filled in so that |
1224 | * this code can determine which AF/protocol is | 1443 | * this code can determine which AF/protocol is |
1225 | * going to be used (the 'tunnel' should also | 1444 | * going to be used (the 'tunnel' should also |
1226 | * already be set); after calling this function, | 1445 | * already be set); after calling this function, |
@@ -1237,47 +1456,47 @@ setup_state_record (struct TunnelState *state) | |||
1237 | /* generate fresh, unique address */ | 1456 | /* generate fresh, unique address */ |
1238 | do | 1457 | do |
1239 | { | 1458 | { |
1240 | if (NULL == state->serv) | 1459 | if (NULL == state->specifics.tcp_udp.serv) |
1241 | setup_fresh_address (state->ri.remote_address.af, | 1460 | setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af, |
1242 | state->ri.remote_address.proto, | 1461 | state->specifics.tcp_udp.ri.remote_address.proto, |
1243 | &state->ri.local_address); | 1462 | &state->specifics.tcp_udp.ri.local_address); |
1244 | else | 1463 | else |
1245 | setup_fresh_address (state->serv->address.af, | 1464 | setup_fresh_address (state->specifics.tcp_udp.serv->address.af, |
1246 | state->serv->address.proto, | 1465 | state->specifics.tcp_udp.serv->address.proto, |
1247 | &state->ri.local_address); | 1466 | &state->specifics.tcp_udp.ri.local_address); |
1248 | } while (NULL != get_redirect_state (state->ri.remote_address.af, | 1467 | } while (NULL != get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af, |
1249 | state->ri.remote_address.proto, | 1468 | state->specifics.tcp_udp.ri.remote_address.proto, |
1250 | &state->ri.remote_address.address, | 1469 | &state->specifics.tcp_udp.ri.remote_address.address, |
1251 | state->ri.remote_address.port, | 1470 | state->specifics.tcp_udp.ri.remote_address.port, |
1252 | &state->ri.local_address.address, | 1471 | &state->specifics.tcp_udp.ri.local_address.address, |
1253 | state->ri.local_address.port, | 1472 | state->specifics.tcp_udp.ri.local_address.port, |
1254 | &key)); | 1473 | &key)); |
1255 | { | 1474 | { |
1256 | char buf[INET6_ADDRSTRLEN]; | 1475 | char buf[INET6_ADDRSTRLEN]; |
1257 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1476 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1258 | "Picked local address %s:%u for new connection\n", | 1477 | "Picked local address %s:%u for new connection\n", |
1259 | inet_ntop (state->ri.local_address.af, | 1478 | inet_ntop (state->specifics.tcp_udp.ri.local_address.af, |
1260 | &state->ri.local_address.address, | 1479 | &state->specifics.tcp_udp.ri.local_address.address, |
1261 | buf, sizeof (buf)), | 1480 | buf, sizeof (buf)), |
1262 | (unsigned int) state->ri.local_address.port); | 1481 | (unsigned int) state->specifics.tcp_udp.ri.local_address.port); |
1263 | } | 1482 | } |
1264 | state->state_key = key; | 1483 | state->specifics.tcp_udp.state_key = key; |
1265 | GNUNET_assert (GNUNET_OK == | 1484 | GNUNET_assert (GNUNET_OK == |
1266 | GNUNET_CONTAINER_multihashmap_put (connections_map, | 1485 | GNUNET_CONTAINER_multihashmap_put (connections_map, |
1267 | &key, state, | 1486 | &key, state, |
1268 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 1487 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
1269 | state->heap_node = GNUNET_CONTAINER_heap_insert (connections_heap, | 1488 | state->specifics.tcp_udp.heap_node = GNUNET_CONTAINER_heap_insert (connections_heap, |
1270 | state, | 1489 | state, |
1271 | GNUNET_TIME_absolute_get ().abs_value); | 1490 | GNUNET_TIME_absolute_get ().abs_value); |
1272 | while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections) | 1491 | while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections) |
1273 | { | 1492 | { |
1274 | s = GNUNET_CONTAINER_heap_remove_root (connections_heap); | 1493 | s = GNUNET_CONTAINER_heap_remove_root (connections_heap); |
1275 | GNUNET_assert (state != s); | 1494 | GNUNET_assert (state != s); |
1276 | s->heap_node = NULL; | 1495 | s->specifics.tcp_udp.heap_node = NULL; |
1277 | GNUNET_MESH_tunnel_destroy (s->tunnel); | 1496 | GNUNET_MESH_tunnel_destroy (s->tunnel); |
1278 | GNUNET_assert (GNUNET_OK == | 1497 | GNUNET_assert (GNUNET_OK == |
1279 | GNUNET_CONTAINER_multihashmap_remove (connections_map, | 1498 | GNUNET_CONTAINER_multihashmap_remove (connections_map, |
1280 | &s->state_key, | 1499 | &s->specifics.tcp_udp.state_key, |
1281 | s)); | 1500 | s)); |
1282 | GNUNET_free (s); | 1501 | GNUNET_free (s); |
1283 | } | 1502 | } |
@@ -1548,10 +1767,11 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1548 | GNUNET_assert (0); | 1767 | GNUNET_assert (0); |
1549 | break; | 1768 | break; |
1550 | } | 1769 | } |
1551 | (void) GNUNET_HELPER_send (helper_handle, | 1770 | if (NULL != helper_handle) |
1552 | (const struct GNUNET_MessageHeader*) buf, | 1771 | (void) GNUNET_HELPER_send (helper_handle, |
1553 | GNUNET_YES, | 1772 | (const struct GNUNET_MessageHeader*) buf, |
1554 | NULL, NULL); | 1773 | GNUNET_YES, |
1774 | NULL, NULL); | ||
1555 | } | 1775 | } |
1556 | } | 1776 | } |
1557 | 1777 | ||
@@ -1580,6 +1800,16 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1580 | const struct GNUNET_EXIT_TcpServiceStartMessage *start; | 1800 | const struct GNUNET_EXIT_TcpServiceStartMessage *start; |
1581 | uint16_t pkt_len = ntohs (message->size); | 1801 | uint16_t pkt_len = ntohs (message->size); |
1582 | 1802 | ||
1803 | if (GNUNET_YES == state->is_dns) | ||
1804 | { | ||
1805 | GNUNET_break_op (0); | ||
1806 | return GNUNET_SYSERR; | ||
1807 | } | ||
1808 | if (GNUNET_SYSERR == state->is_dns) | ||
1809 | { | ||
1810 | /* tunnel is UDP/TCP from now on */ | ||
1811 | state->is_dns = GNUNET_NO; | ||
1812 | } | ||
1583 | GNUNET_STATISTICS_update (stats, | 1813 | GNUNET_STATISTICS_update (stats, |
1584 | gettext_noop ("# TCP service creation requests received via mesh"), | 1814 | gettext_noop ("# TCP service creation requests received via mesh"), |
1585 | 1, GNUNET_NO); | 1815 | 1, GNUNET_NO); |
@@ -1595,8 +1825,8 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1595 | start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message; | 1825 | start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message; |
1596 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage); | 1826 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage); |
1597 | if ( (NULL == state) || | 1827 | if ( (NULL == state) || |
1598 | (NULL != state->serv) || | 1828 | (NULL != state->specifics.tcp_udp.serv) || |
1599 | (NULL != state->heap_node) ) | 1829 | (NULL != state->specifics.tcp_udp.heap_node) ) |
1600 | { | 1830 | { |
1601 | GNUNET_break_op (0); | 1831 | GNUNET_break_op (0); |
1602 | return GNUNET_SYSERR; | 1832 | return GNUNET_SYSERR; |
@@ -1613,8 +1843,8 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1613 | GNUNET_i2s (sender), | 1843 | GNUNET_i2s (sender), |
1614 | GNUNET_h2s (&start->service_descriptor), | 1844 | GNUNET_h2s (&start->service_descriptor), |
1615 | (unsigned int) ntohs (start->tcp_header.destination_port)); | 1845 | (unsigned int) ntohs (start->tcp_header.destination_port)); |
1616 | if (NULL == (state->serv = find_service (tcp_services, &start->service_descriptor, | 1846 | if (NULL == (state->specifics.tcp_udp.serv = find_service (tcp_services, &start->service_descriptor, |
1617 | ntohs (start->tcp_header.destination_port)))) | 1847 | ntohs (start->tcp_header.destination_port)))) |
1618 | { | 1848 | { |
1619 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1849 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1620 | _("No service found for %s on port %d!\n"), | 1850 | _("No service found for %s on port %d!\n"), |
@@ -1625,10 +1855,10 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1625 | 1, GNUNET_NO); | 1855 | 1, GNUNET_NO); |
1626 | return GNUNET_SYSERR; | 1856 | return GNUNET_SYSERR; |
1627 | } | 1857 | } |
1628 | state->ri.remote_address = state->serv->address; | 1858 | state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address; |
1629 | setup_state_record (state); | 1859 | setup_state_record (state); |
1630 | send_tcp_packet_via_tun (&state->ri.remote_address, | 1860 | send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
1631 | &state->ri.local_address, | 1861 | &state->specifics.tcp_udp.ri.local_address, |
1632 | &start->tcp_header, | 1862 | &start->tcp_header, |
1633 | &start[1], pkt_len); | 1863 | &start[1], pkt_len); |
1634 | return GNUNET_YES; | 1864 | return GNUNET_YES; |
@@ -1662,6 +1892,16 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1662 | const void *payload; | 1892 | const void *payload; |
1663 | int af; | 1893 | int af; |
1664 | 1894 | ||
1895 | if (GNUNET_YES == state->is_dns) | ||
1896 | { | ||
1897 | GNUNET_break_op (0); | ||
1898 | return GNUNET_SYSERR; | ||
1899 | } | ||
1900 | if (GNUNET_SYSERR == state->is_dns) | ||
1901 | { | ||
1902 | /* tunnel is UDP/TCP from now on */ | ||
1903 | state->is_dns = GNUNET_NO; | ||
1904 | } | ||
1665 | GNUNET_STATISTICS_update (stats, | 1905 | GNUNET_STATISTICS_update (stats, |
1666 | gettext_noop ("# Bytes received from MESH"), | 1906 | gettext_noop ("# Bytes received from MESH"), |
1667 | pkt_len, GNUNET_NO); | 1907 | pkt_len, GNUNET_NO); |
@@ -1676,8 +1916,8 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1676 | start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message; | 1916 | start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message; |
1677 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage); | 1917 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage); |
1678 | if ( (NULL == state) || | 1918 | if ( (NULL == state) || |
1679 | (NULL != state->serv) || | 1919 | (NULL != state->specifics.tcp_udp.serv) || |
1680 | (NULL != state->heap_node) ) | 1920 | (NULL != state->specifics.tcp_udp.heap_node) ) |
1681 | { | 1921 | { |
1682 | GNUNET_break_op (0); | 1922 | GNUNET_break_op (0); |
1683 | return GNUNET_SYSERR; | 1923 | return GNUNET_SYSERR; |
@@ -1688,7 +1928,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1688 | return GNUNET_SYSERR; | 1928 | return GNUNET_SYSERR; |
1689 | } | 1929 | } |
1690 | af = (int) ntohl (start->af); | 1930 | af = (int) ntohl (start->af); |
1691 | state->ri.remote_address.af = af; | 1931 | state->specifics.tcp_udp.ri.remote_address.af = af; |
1692 | switch (af) | 1932 | switch (af) |
1693 | { | 1933 | { |
1694 | case AF_INET: | 1934 | case AF_INET: |
@@ -1705,7 +1945,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1705 | v4 = (const struct in_addr*) &start[1]; | 1945 | v4 = (const struct in_addr*) &start[1]; |
1706 | payload = &v4[1]; | 1946 | payload = &v4[1]; |
1707 | pkt_len -= sizeof (struct in_addr); | 1947 | pkt_len -= sizeof (struct in_addr); |
1708 | state->ri.remote_address.address.ipv4 = *v4; | 1948 | state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4; |
1709 | break; | 1949 | break; |
1710 | case AF_INET6: | 1950 | case AF_INET6: |
1711 | if (pkt_len < sizeof (struct in6_addr)) | 1951 | if (pkt_len < sizeof (struct in6_addr)) |
@@ -1721,7 +1961,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1721 | v6 = (const struct in6_addr*) &start[1]; | 1961 | v6 = (const struct in6_addr*) &start[1]; |
1722 | payload = &v6[1]; | 1962 | payload = &v6[1]; |
1723 | pkt_len -= sizeof (struct in6_addr); | 1963 | pkt_len -= sizeof (struct in6_addr); |
1724 | state->ri.remote_address.address.ipv6 = *v6; | 1964 | state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6; |
1725 | break; | 1965 | break; |
1726 | default: | 1966 | default: |
1727 | GNUNET_break_op (0); | 1967 | GNUNET_break_op (0); |
@@ -1733,15 +1973,15 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1733 | "Received data from %s for starting TCP stream to %s:%u\n", | 1973 | "Received data from %s for starting TCP stream to %s:%u\n", |
1734 | GNUNET_i2s (sender), | 1974 | GNUNET_i2s (sender), |
1735 | inet_ntop (af, | 1975 | inet_ntop (af, |
1736 | &state->ri.remote_address.address, | 1976 | &state->specifics.tcp_udp.ri.remote_address.address, |
1737 | buf, sizeof (buf)), | 1977 | buf, sizeof (buf)), |
1738 | (unsigned int) ntohs (start->tcp_header.destination_port)); | 1978 | (unsigned int) ntohs (start->tcp_header.destination_port)); |
1739 | } | 1979 | } |
1740 | state->ri.remote_address.proto = IPPROTO_TCP; | 1980 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP; |
1741 | state->ri.remote_address.port = ntohs (start->tcp_header.destination_port); | 1981 | state->specifics.tcp_udp.ri.remote_address.port = ntohs (start->tcp_header.destination_port); |
1742 | setup_state_record (state); | 1982 | setup_state_record (state); |
1743 | send_tcp_packet_via_tun (&state->ri.remote_address, | 1983 | send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
1744 | &state->ri.local_address, | 1984 | &state->specifics.tcp_udp.ri.local_address, |
1745 | &start->tcp_header, | 1985 | &start->tcp_header, |
1746 | payload, pkt_len); | 1986 | payload, pkt_len); |
1747 | return GNUNET_YES; | 1987 | return GNUNET_YES; |
@@ -1772,6 +2012,16 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1772 | const struct GNUNET_EXIT_TcpDataMessage *data; | 2012 | const struct GNUNET_EXIT_TcpDataMessage *data; |
1773 | uint16_t pkt_len = ntohs (message->size); | 2013 | uint16_t pkt_len = ntohs (message->size); |
1774 | 2014 | ||
2015 | if (GNUNET_YES == state->is_dns) | ||
2016 | { | ||
2017 | GNUNET_break_op (0); | ||
2018 | return GNUNET_SYSERR; | ||
2019 | } | ||
2020 | if (GNUNET_SYSERR == state->is_dns) | ||
2021 | { | ||
2022 | /* tunnel is UDP/TCP from now on */ | ||
2023 | state->is_dns = GNUNET_NO; | ||
2024 | } | ||
1775 | GNUNET_STATISTICS_update (stats, | 2025 | GNUNET_STATISTICS_update (stats, |
1776 | gettext_noop ("# Bytes received from MESH"), | 2026 | gettext_noop ("# Bytes received from MESH"), |
1777 | pkt_len, GNUNET_NO); | 2027 | pkt_len, GNUNET_NO); |
@@ -1786,7 +2036,7 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1786 | data = (const struct GNUNET_EXIT_TcpDataMessage*) message; | 2036 | data = (const struct GNUNET_EXIT_TcpDataMessage*) message; |
1787 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage); | 2037 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage); |
1788 | if ( (NULL == state) || | 2038 | if ( (NULL == state) || |
1789 | (NULL == state->heap_node) ) | 2039 | (NULL == state->specifics.tcp_udp.heap_node) ) |
1790 | { | 2040 | { |
1791 | /* connection should have been up! */ | 2041 | /* connection should have been up! */ |
1792 | GNUNET_STATISTICS_update (stats, | 2042 | GNUNET_STATISTICS_update (stats, |
@@ -1807,14 +2057,14 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1807 | "Received additional %u bytes of data from %s for TCP stream to %s:%u\n", | 2057 | "Received additional %u bytes of data from %s for TCP stream to %s:%u\n", |
1808 | pkt_len, | 2058 | pkt_len, |
1809 | GNUNET_i2s (sender), | 2059 | GNUNET_i2s (sender), |
1810 | inet_ntop (state->ri.remote_address.af, | 2060 | inet_ntop (state->specifics.tcp_udp.ri.remote_address.af, |
1811 | &state->ri.remote_address.address, | 2061 | &state->specifics.tcp_udp.ri.remote_address.address, |
1812 | buf, sizeof (buf)), | 2062 | buf, sizeof (buf)), |
1813 | (unsigned int) state->ri.remote_address.port); | 2063 | (unsigned int) state->specifics.tcp_udp.ri.remote_address.port); |
1814 | } | 2064 | } |
1815 | 2065 | ||
1816 | send_tcp_packet_via_tun (&state->ri.remote_address, | 2066 | send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
1817 | &state->ri.local_address, | 2067 | &state->specifics.tcp_udp.ri.local_address, |
1818 | &data->tcp_header, | 2068 | &data->tcp_header, |
1819 | &data[1], pkt_len); | 2069 | &data[1], pkt_len); |
1820 | return GNUNET_YES; | 2070 | return GNUNET_YES; |
@@ -1914,10 +2164,11 @@ send_icmp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1914 | GNUNET_TUN_calculate_icmp_checksum (icmp, | 2164 | GNUNET_TUN_calculate_icmp_checksum (icmp, |
1915 | payload, | 2165 | payload, |
1916 | payload_length); | 2166 | payload_length); |
1917 | (void) GNUNET_HELPER_send (helper_handle, | 2167 | if (NULL != helper_handle) |
1918 | (const struct GNUNET_MessageHeader*) buf, | 2168 | (void) GNUNET_HELPER_send (helper_handle, |
1919 | GNUNET_YES, | 2169 | (const struct GNUNET_MessageHeader*) buf, |
1920 | NULL, NULL); | 2170 | GNUNET_YES, |
2171 | NULL, NULL); | ||
1921 | } | 2172 | } |
1922 | } | 2173 | } |
1923 | 2174 | ||
@@ -1937,12 +2188,12 @@ make_up_icmpv4_payload (struct TunnelState *state, | |||
1937 | struct GNUNET_TUN_UdpHeader *udp) | 2188 | struct GNUNET_TUN_UdpHeader *udp) |
1938 | { | 2189 | { |
1939 | GNUNET_TUN_initialize_ipv4_header (ipp, | 2190 | GNUNET_TUN_initialize_ipv4_header (ipp, |
1940 | state->ri.remote_address.proto, | 2191 | state->specifics.tcp_udp.ri.remote_address.proto, |
1941 | sizeof (struct GNUNET_TUN_TcpHeader), | 2192 | sizeof (struct GNUNET_TUN_TcpHeader), |
1942 | &state->ri.remote_address.address.ipv4, | 2193 | &state->specifics.tcp_udp.ri.remote_address.address.ipv4, |
1943 | &state->ri.local_address.address.ipv4); | 2194 | &state->specifics.tcp_udp.ri.local_address.address.ipv4); |
1944 | udp->source_port = htons (state->ri.remote_address.port); | 2195 | udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port); |
1945 | udp->destination_port = htons (state->ri.local_address.port); | 2196 | udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port); |
1946 | udp->len = htons (0); | 2197 | udp->len = htons (0); |
1947 | udp->crc = htons (0); | 2198 | udp->crc = htons (0); |
1948 | } | 2199 | } |
@@ -1963,12 +2214,12 @@ make_up_icmpv6_payload (struct TunnelState *state, | |||
1963 | struct GNUNET_TUN_UdpHeader *udp) | 2214 | struct GNUNET_TUN_UdpHeader *udp) |
1964 | { | 2215 | { |
1965 | GNUNET_TUN_initialize_ipv6_header (ipp, | 2216 | GNUNET_TUN_initialize_ipv6_header (ipp, |
1966 | state->ri.remote_address.proto, | 2217 | state->specifics.tcp_udp.ri.remote_address.proto, |
1967 | sizeof (struct GNUNET_TUN_TcpHeader), | 2218 | sizeof (struct GNUNET_TUN_TcpHeader), |
1968 | &state->ri.remote_address.address.ipv6, | 2219 | &state->specifics.tcp_udp.ri.remote_address.address.ipv6, |
1969 | &state->ri.local_address.address.ipv6); | 2220 | &state->specifics.tcp_udp.ri.local_address.address.ipv6); |
1970 | udp->source_port = htons (state->ri.remote_address.port); | 2221 | udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port); |
1971 | udp->destination_port = htons (state->ri.local_address.port); | 2222 | udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port); |
1972 | udp->len = htons (0); | 2223 | udp->len = htons (0); |
1973 | udp->crc = htons (0); | 2224 | udp->crc = htons (0); |
1974 | } | 2225 | } |
@@ -2002,6 +2253,16 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2002 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | 2253 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; |
2003 | int af; | 2254 | int af; |
2004 | 2255 | ||
2256 | if (GNUNET_YES == state->is_dns) | ||
2257 | { | ||
2258 | GNUNET_break_op (0); | ||
2259 | return GNUNET_SYSERR; | ||
2260 | } | ||
2261 | if (GNUNET_SYSERR == state->is_dns) | ||
2262 | { | ||
2263 | /* tunnel is UDP/TCP from now on */ | ||
2264 | state->is_dns = GNUNET_NO; | ||
2265 | } | ||
2005 | GNUNET_STATISTICS_update (stats, | 2266 | GNUNET_STATISTICS_update (stats, |
2006 | gettext_noop ("# Bytes received from MESH"), | 2267 | gettext_noop ("# Bytes received from MESH"), |
2007 | pkt_len, GNUNET_NO); | 2268 | pkt_len, GNUNET_NO); |
@@ -2017,8 +2278,8 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2017 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage); | 2278 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage); |
2018 | 2279 | ||
2019 | af = (int) ntohl (msg->af); | 2280 | af = (int) ntohl (msg->af); |
2020 | if ( (NULL != state->heap_node) && | 2281 | if ( (NULL != state->specifics.tcp_udp.heap_node) && |
2021 | (af != state->ri.remote_address.af) ) | 2282 | (af != state->specifics.tcp_udp.ri.remote_address.af) ) |
2022 | { | 2283 | { |
2023 | /* other peer switched AF on this tunnel; not allowed */ | 2284 | /* other peer switched AF on this tunnel; not allowed */ |
2024 | GNUNET_break_op (0); | 2285 | GNUNET_break_op (0); |
@@ -2041,11 +2302,11 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2041 | v4 = (const struct in_addr*) &msg[1]; | 2302 | v4 = (const struct in_addr*) &msg[1]; |
2042 | payload = &v4[1]; | 2303 | payload = &v4[1]; |
2043 | pkt_len -= sizeof (struct in_addr); | 2304 | pkt_len -= sizeof (struct in_addr); |
2044 | state->ri.remote_address.address.ipv4 = *v4; | 2305 | state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4; |
2045 | if (NULL == state->heap_node) | 2306 | if (NULL == state->specifics.tcp_udp.heap_node) |
2046 | { | 2307 | { |
2047 | state->ri.remote_address.af = af; | 2308 | state->specifics.tcp_udp.ri.remote_address.af = af; |
2048 | state->ri.remote_address.proto = IPPROTO_ICMP; | 2309 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP; |
2049 | setup_state_record (state); | 2310 | setup_state_record (state); |
2050 | } | 2311 | } |
2051 | /* check that ICMP type is something we want to support | 2312 | /* check that ICMP type is something we want to support |
@@ -2099,11 +2360,11 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2099 | v6 = (const struct in6_addr*) &msg[1]; | 2360 | v6 = (const struct in6_addr*) &msg[1]; |
2100 | payload = &v6[1]; | 2361 | payload = &v6[1]; |
2101 | pkt_len -= sizeof (struct in6_addr); | 2362 | pkt_len -= sizeof (struct in6_addr); |
2102 | state->ri.remote_address.address.ipv6 = *v6; | 2363 | state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6; |
2103 | if (NULL == state->heap_node) | 2364 | if (NULL == state->specifics.tcp_udp.heap_node) |
2104 | { | 2365 | { |
2105 | state->ri.remote_address.af = af; | 2366 | state->specifics.tcp_udp.ri.remote_address.af = af; |
2106 | state->ri.remote_address.proto = IPPROTO_ICMPV6; | 2367 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6; |
2107 | setup_state_record (state); | 2368 | setup_state_record (state); |
2108 | } | 2369 | } |
2109 | /* check that ICMP type is something we want to support | 2370 | /* check that ICMP type is something we want to support |
@@ -2156,11 +2417,11 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2156 | "Received ICMP data from %s for forwarding to %s\n", | 2417 | "Received ICMP data from %s for forwarding to %s\n", |
2157 | GNUNET_i2s (sender), | 2418 | GNUNET_i2s (sender), |
2158 | inet_ntop (af, | 2419 | inet_ntop (af, |
2159 | &state->ri.remote_address.address, | 2420 | &state->specifics.tcp_udp.ri.remote_address.address, |
2160 | buf, sizeof (buf))); | 2421 | buf, sizeof (buf))); |
2161 | } | 2422 | } |
2162 | send_icmp_packet_via_tun (&state->ri.remote_address, | 2423 | send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2163 | &state->ri.local_address, | 2424 | &state->specifics.tcp_udp.ri.local_address, |
2164 | &msg->icmp_header, | 2425 | &msg->icmp_header, |
2165 | payload, pkt_len); | 2426 | payload, pkt_len); |
2166 | return GNUNET_YES; | 2427 | return GNUNET_YES; |
@@ -2180,7 +2441,7 @@ static uint16_t | |||
2180 | make_up_icmp_service_payload (struct TunnelState *state, | 2441 | make_up_icmp_service_payload (struct TunnelState *state, |
2181 | char *buf) | 2442 | char *buf) |
2182 | { | 2443 | { |
2183 | switch (state->serv->address.af) | 2444 | switch (state->specifics.tcp_udp.serv->address.af) |
2184 | { | 2445 | { |
2185 | case AF_INET: | 2446 | case AF_INET: |
2186 | { | 2447 | { |
@@ -2244,6 +2505,16 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2244 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | 2505 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; |
2245 | const void *payload; | 2506 | const void *payload; |
2246 | 2507 | ||
2508 | if (GNUNET_YES == state->is_dns) | ||
2509 | { | ||
2510 | GNUNET_break_op (0); | ||
2511 | return GNUNET_SYSERR; | ||
2512 | } | ||
2513 | if (GNUNET_SYSERR == state->is_dns) | ||
2514 | { | ||
2515 | /* tunnel is UDP/TCP from now on */ | ||
2516 | state->is_dns = GNUNET_NO; | ||
2517 | } | ||
2247 | GNUNET_STATISTICS_update (stats, | 2518 | GNUNET_STATISTICS_update (stats, |
2248 | gettext_noop ("# Bytes received from MESH"), | 2519 | gettext_noop ("# Bytes received from MESH"), |
2249 | pkt_len, GNUNET_NO); | 2520 | pkt_len, GNUNET_NO); |
@@ -2262,7 +2533,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2262 | "Received data from %s for forwarding to ICMP service %s\n", | 2533 | "Received data from %s for forwarding to ICMP service %s\n", |
2263 | GNUNET_i2s (sender), | 2534 | GNUNET_i2s (sender), |
2264 | GNUNET_h2s (&msg->service_descriptor)); | 2535 | GNUNET_h2s (&msg->service_descriptor)); |
2265 | if (NULL == state->serv) | 2536 | if (NULL == state->specifics.tcp_udp.serv) |
2266 | { | 2537 | { |
2267 | /* first packet to service must not be ICMP (cannot determine service!) */ | 2538 | /* first packet to service must not be ICMP (cannot determine service!) */ |
2268 | GNUNET_break_op (0); | 2539 | GNUNET_break_op (0); |
@@ -2270,7 +2541,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2270 | } | 2541 | } |
2271 | icmp = msg->icmp_header; | 2542 | icmp = msg->icmp_header; |
2272 | payload = &msg[1]; | 2543 | payload = &msg[1]; |
2273 | state->ri.remote_address = state->serv->address; | 2544 | state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address; |
2274 | setup_state_record (state); | 2545 | setup_state_record (state); |
2275 | 2546 | ||
2276 | /* check that ICMP type is something we want to support, | 2547 | /* check that ICMP type is something we want to support, |
@@ -2281,15 +2552,15 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2281 | switch (msg->icmp_header.type) | 2552 | switch (msg->icmp_header.type) |
2282 | { | 2553 | { |
2283 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | 2554 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: |
2284 | if (state->serv->address.af == AF_INET6) | 2555 | if (state->specifics.tcp_udp.serv->address.af == AF_INET6) |
2285 | icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | 2556 | icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; |
2286 | break; | 2557 | break; |
2287 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | 2558 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: |
2288 | if (state->serv->address.af == AF_INET6) | 2559 | if (state->specifics.tcp_udp.serv->address.af == AF_INET6) |
2289 | icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | 2560 | icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; |
2290 | break; | 2561 | break; |
2291 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | 2562 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: |
2292 | if (state->serv->address.af == AF_INET6) | 2563 | if (state->specifics.tcp_udp.serv->address.af == AF_INET6) |
2293 | icmp.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | 2564 | icmp.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; |
2294 | if (0 != pkt_len) | 2565 | if (0 != pkt_len) |
2295 | { | 2566 | { |
@@ -2300,7 +2571,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2300 | pkt_len = make_up_icmp_service_payload (state, buf); | 2571 | pkt_len = make_up_icmp_service_payload (state, buf); |
2301 | break; | 2572 | break; |
2302 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | 2573 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: |
2303 | if (state->serv->address.af == AF_INET6) | 2574 | if (state->specifics.tcp_udp.serv->address.af == AF_INET6) |
2304 | icmp.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | 2575 | icmp.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; |
2305 | if (0 != pkt_len) | 2576 | if (0 != pkt_len) |
2306 | { | 2577 | { |
@@ -2311,7 +2582,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2311 | pkt_len = make_up_icmp_service_payload (state, buf); | 2582 | pkt_len = make_up_icmp_service_payload (state, buf); |
2312 | break; | 2583 | break; |
2313 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | 2584 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: |
2314 | if (state->serv->address.af == AF_INET6) | 2585 | if (state->specifics.tcp_udp.serv->address.af == AF_INET6) |
2315 | { | 2586 | { |
2316 | GNUNET_STATISTICS_update (stats, | 2587 | GNUNET_STATISTICS_update (stats, |
2317 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | 2588 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), |
@@ -2339,15 +2610,15 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2339 | switch (msg->icmp_header.type) | 2610 | switch (msg->icmp_header.type) |
2340 | { | 2611 | { |
2341 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | 2612 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: |
2342 | if (state->serv->address.af == AF_INET) | 2613 | if (state->specifics.tcp_udp.serv->address.af == AF_INET) |
2343 | icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | 2614 | icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; |
2344 | break; | 2615 | break; |
2345 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | 2616 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: |
2346 | if (state->serv->address.af == AF_INET) | 2617 | if (state->specifics.tcp_udp.serv->address.af == AF_INET) |
2347 | icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | 2618 | icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; |
2348 | break; | 2619 | break; |
2349 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | 2620 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: |
2350 | if (state->serv->address.af == AF_INET) | 2621 | if (state->specifics.tcp_udp.serv->address.af == AF_INET) |
2351 | icmp.type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; | 2622 | icmp.type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; |
2352 | if (0 != pkt_len) | 2623 | if (0 != pkt_len) |
2353 | { | 2624 | { |
@@ -2358,7 +2629,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2358 | pkt_len = make_up_icmp_service_payload (state, buf); | 2629 | pkt_len = make_up_icmp_service_payload (state, buf); |
2359 | break; | 2630 | break; |
2360 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | 2631 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: |
2361 | if (state->serv->address.af == AF_INET) | 2632 | if (state->specifics.tcp_udp.serv->address.af == AF_INET) |
2362 | icmp.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | 2633 | icmp.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; |
2363 | if (0 != pkt_len) | 2634 | if (0 != pkt_len) |
2364 | { | 2635 | { |
@@ -2370,7 +2641,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2370 | break; | 2641 | break; |
2371 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | 2642 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: |
2372 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | 2643 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: |
2373 | if (state->serv->address.af == AF_INET) | 2644 | if (state->specifics.tcp_udp.serv->address.af == AF_INET) |
2374 | { | 2645 | { |
2375 | GNUNET_STATISTICS_update (stats, | 2646 | GNUNET_STATISTICS_update (stats, |
2376 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | 2647 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), |
@@ -2399,8 +2670,8 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2399 | return GNUNET_SYSERR; | 2670 | return GNUNET_SYSERR; |
2400 | } | 2671 | } |
2401 | 2672 | ||
2402 | send_icmp_packet_via_tun (&state->ri.remote_address, | 2673 | send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2403 | &state->ri.local_address, | 2674 | &state->specifics.tcp_udp.ri.local_address, |
2404 | &icmp, | 2675 | &icmp, |
2405 | payload, pkt_len); | 2676 | payload, pkt_len); |
2406 | return GNUNET_YES; | 2677 | return GNUNET_YES; |
@@ -2490,10 +2761,11 @@ send_udp_packet_via_tun (const struct SocketAddress *destination_address, | |||
2490 | GNUNET_assert (0); | 2761 | GNUNET_assert (0); |
2491 | break; | 2762 | break; |
2492 | } | 2763 | } |
2493 | (void) GNUNET_HELPER_send (helper_handle, | 2764 | if (NULL != helper_handle) |
2494 | (const struct GNUNET_MessageHeader*) buf, | 2765 | (void) GNUNET_HELPER_send (helper_handle, |
2495 | GNUNET_YES, | 2766 | (const struct GNUNET_MessageHeader*) buf, |
2496 | NULL, NULL); | 2767 | GNUNET_YES, |
2768 | NULL, NULL); | ||
2497 | } | 2769 | } |
2498 | } | 2770 | } |
2499 | 2771 | ||
@@ -2525,6 +2797,16 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2525 | const void *payload; | 2797 | const void *payload; |
2526 | int af; | 2798 | int af; |
2527 | 2799 | ||
2800 | if (GNUNET_YES == state->is_dns) | ||
2801 | { | ||
2802 | GNUNET_break_op (0); | ||
2803 | return GNUNET_SYSERR; | ||
2804 | } | ||
2805 | if (GNUNET_SYSERR == state->is_dns) | ||
2806 | { | ||
2807 | /* tunnel is UDP/TCP from now on */ | ||
2808 | state->is_dns = GNUNET_NO; | ||
2809 | } | ||
2528 | GNUNET_STATISTICS_update (stats, | 2810 | GNUNET_STATISTICS_update (stats, |
2529 | gettext_noop ("# Bytes received from MESH"), | 2811 | gettext_noop ("# Bytes received from MESH"), |
2530 | pkt_len, GNUNET_NO); | 2812 | pkt_len, GNUNET_NO); |
@@ -2539,7 +2821,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2539 | msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message; | 2821 | msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message; |
2540 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage); | 2822 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage); |
2541 | af = (int) ntohl (msg->af); | 2823 | af = (int) ntohl (msg->af); |
2542 | state->ri.remote_address.af = af; | 2824 | state->specifics.tcp_udp.ri.remote_address.af = af; |
2543 | switch (af) | 2825 | switch (af) |
2544 | { | 2826 | { |
2545 | case AF_INET: | 2827 | case AF_INET: |
@@ -2556,7 +2838,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2556 | v4 = (const struct in_addr*) &msg[1]; | 2838 | v4 = (const struct in_addr*) &msg[1]; |
2557 | payload = &v4[1]; | 2839 | payload = &v4[1]; |
2558 | pkt_len -= sizeof (struct in_addr); | 2840 | pkt_len -= sizeof (struct in_addr); |
2559 | state->ri.remote_address.address.ipv4 = *v4; | 2841 | state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4; |
2560 | break; | 2842 | break; |
2561 | case AF_INET6: | 2843 | case AF_INET6: |
2562 | if (pkt_len < sizeof (struct in6_addr)) | 2844 | if (pkt_len < sizeof (struct in6_addr)) |
@@ -2572,7 +2854,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2572 | v6 = (const struct in6_addr*) &msg[1]; | 2854 | v6 = (const struct in6_addr*) &msg[1]; |
2573 | payload = &v6[1]; | 2855 | payload = &v6[1]; |
2574 | pkt_len -= sizeof (struct in6_addr); | 2856 | pkt_len -= sizeof (struct in6_addr); |
2575 | state->ri.remote_address.address.ipv6 = *v6; | 2857 | state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6; |
2576 | break; | 2858 | break; |
2577 | default: | 2859 | default: |
2578 | GNUNET_break_op (0); | 2860 | GNUNET_break_op (0); |
@@ -2584,18 +2866,18 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2584 | "Received data from %s for forwarding to UDP %s:%u\n", | 2866 | "Received data from %s for forwarding to UDP %s:%u\n", |
2585 | GNUNET_i2s (sender), | 2867 | GNUNET_i2s (sender), |
2586 | inet_ntop (af, | 2868 | inet_ntop (af, |
2587 | &state->ri.remote_address.address, | 2869 | &state->specifics.tcp_udp.ri.remote_address.address, |
2588 | buf, sizeof (buf)), | 2870 | buf, sizeof (buf)), |
2589 | (unsigned int) ntohs (msg->destination_port)); | 2871 | (unsigned int) ntohs (msg->destination_port)); |
2590 | } | 2872 | } |
2591 | state->ri.remote_address.proto = IPPROTO_UDP; | 2873 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP; |
2592 | state->ri.remote_address.port = msg->destination_port; | 2874 | state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port; |
2593 | if (NULL == state->heap_node) | 2875 | if (NULL == state->specifics.tcp_udp.heap_node) |
2594 | setup_state_record (state); | 2876 | setup_state_record (state); |
2595 | if (0 != ntohs (msg->source_port)) | 2877 | if (0 != ntohs (msg->source_port)) |
2596 | state->ri.local_address.port = msg->source_port; | 2878 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; |
2597 | send_udp_packet_via_tun (&state->ri.remote_address, | 2879 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2598 | &state->ri.local_address, | 2880 | &state->specifics.tcp_udp.ri.local_address, |
2599 | payload, pkt_len); | 2881 | payload, pkt_len); |
2600 | return GNUNET_YES; | 2882 | return GNUNET_YES; |
2601 | } | 2883 | } |
@@ -2625,6 +2907,16 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2625 | const struct GNUNET_EXIT_UdpServiceMessage *msg; | 2907 | const struct GNUNET_EXIT_UdpServiceMessage *msg; |
2626 | uint16_t pkt_len = ntohs (message->size); | 2908 | uint16_t pkt_len = ntohs (message->size); |
2627 | 2909 | ||
2910 | if (GNUNET_YES == state->is_dns) | ||
2911 | { | ||
2912 | GNUNET_break_op (0); | ||
2913 | return GNUNET_SYSERR; | ||
2914 | } | ||
2915 | if (GNUNET_SYSERR == state->is_dns) | ||
2916 | { | ||
2917 | /* tunnel is UDP/TCP from now on */ | ||
2918 | state->is_dns = GNUNET_NO; | ||
2919 | } | ||
2628 | GNUNET_STATISTICS_update (stats, | 2920 | GNUNET_STATISTICS_update (stats, |
2629 | gettext_noop ("# Bytes received from MESH"), | 2921 | gettext_noop ("# Bytes received from MESH"), |
2630 | pkt_len, GNUNET_NO); | 2922 | pkt_len, GNUNET_NO); |
@@ -2639,13 +2931,13 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2639 | } | 2931 | } |
2640 | msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message; | 2932 | msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message; |
2641 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage); | 2933 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage); |
2642 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2934 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2643 | "Received data from %s for forwarding to UDP service %s on port %u\n", | 2935 | "Received data from %s for forwarding to UDP service %s on port %u\n", |
2644 | GNUNET_i2s (sender), | 2936 | GNUNET_i2s (sender), |
2645 | GNUNET_h2s (&msg->service_descriptor), | 2937 | GNUNET_h2s (&msg->service_descriptor), |
2646 | (unsigned int) ntohs (msg->destination_port)); | 2938 | (unsigned int) ntohs (msg->destination_port)); |
2647 | if (NULL == (state->serv = find_service (udp_services, &msg->service_descriptor, | 2939 | if (NULL == (state->specifics.tcp_udp.serv = find_service (udp_services, &msg->service_descriptor, |
2648 | ntohs (msg->destination_port)))) | 2940 | ntohs (msg->destination_port)))) |
2649 | { | 2941 | { |
2650 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 2942 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
2651 | _("No service found for %s on port %d!\n"), | 2943 | _("No service found for %s on port %d!\n"), |
@@ -2656,12 +2948,12 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2656 | 1, GNUNET_NO); | 2948 | 1, GNUNET_NO); |
2657 | return GNUNET_SYSERR; | 2949 | return GNUNET_SYSERR; |
2658 | } | 2950 | } |
2659 | state->ri.remote_address = state->serv->address; | 2951 | state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address; |
2660 | setup_state_record (state); | 2952 | setup_state_record (state); |
2661 | if (0 != ntohs (msg->source_port)) | 2953 | if (0 != ntohs (msg->source_port)) |
2662 | state->ri.local_address.port = msg->source_port; | 2954 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; |
2663 | send_udp_packet_via_tun (&state->ri.remote_address, | 2955 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2664 | &state->ri.local_address, | 2956 | &state->specifics.tcp_udp.ri.local_address, |
2665 | &msg[1], pkt_len); | 2957 | &msg[1], pkt_len); |
2666 | return GNUNET_YES; | 2958 | return GNUNET_YES; |
2667 | } | 2959 | } |
@@ -2683,6 +2975,7 @@ new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2683 | { | 2975 | { |
2684 | struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState)); | 2976 | struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState)); |
2685 | 2977 | ||
2978 | s->is_dns = GNUNET_SYSERR; | ||
2686 | GNUNET_STATISTICS_update (stats, | 2979 | GNUNET_STATISTICS_update (stats, |
2687 | gettext_noop ("# Inbound MESH tunnels created"), | 2980 | gettext_noop ("# Inbound MESH tunnels created"), |
2688 | 1, GNUNET_NO); | 2981 | 1, GNUNET_NO); |
@@ -2710,23 +3003,37 @@ clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel, | |||
2710 | struct TunnelState *s = tunnel_ctx; | 3003 | struct TunnelState *s = tunnel_ctx; |
2711 | struct TunnelMessageQueue *tnq; | 3004 | struct TunnelMessageQueue *tnq; |
2712 | 3005 | ||
2713 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3006 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2714 | "Tunnel destroyed\n"); | 3007 | "Tunnel destroyed\n"); |
2715 | while (NULL != (tnq = s->head)) | 3008 | if (GNUNET_SYSERR == s->is_dns) |
2716 | { | 3009 | { |
2717 | GNUNET_CONTAINER_DLL_remove (s->head, | 3010 | GNUNET_free (s); |
2718 | s->tail, | 3011 | return; |
2719 | tnq); | ||
2720 | GNUNET_free (tnq); | ||
2721 | } | 3012 | } |
2722 | if (s->heap_node != NULL) | 3013 | if (GNUNET_YES == s->is_dns) |
2723 | { | 3014 | { |
2724 | GNUNET_assert (GNUNET_YES == | 3015 | if (tunnels[s->specifics.dns.my_id] == s) |
2725 | GNUNET_CONTAINER_multihashmap_remove (connections_map, | 3016 | tunnels[s->specifics.dns.my_id] = NULL; |
2726 | &s->state_key, | 3017 | GNUNET_free_non_null (s->specifics.dns.reply); |
2727 | s)); | 3018 | } |
2728 | GNUNET_CONTAINER_heap_remove_node (s->heap_node); | 3019 | else |
2729 | s->heap_node = NULL; | 3020 | { |
3021 | while (NULL != (tnq = s->specifics.tcp_udp.head)) | ||
3022 | { | ||
3023 | GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head, | ||
3024 | s->specifics.tcp_udp.tail, | ||
3025 | tnq); | ||
3026 | GNUNET_free (tnq); | ||
3027 | } | ||
3028 | if (NULL != s->specifics.tcp_udp.heap_node) | ||
3029 | { | ||
3030 | GNUNET_assert (GNUNET_YES == | ||
3031 | GNUNET_CONTAINER_multihashmap_remove (connections_map, | ||
3032 | &s->specifics.tcp_udp.state_key, | ||
3033 | s)); | ||
3034 | GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node); | ||
3035 | s->specifics.tcp_udp.heap_node = NULL; | ||
3036 | } | ||
2730 | } | 3037 | } |
2731 | if (NULL != s->th) | 3038 | if (NULL != s->th) |
2732 | { | 3039 | { |
@@ -2764,6 +3071,7 @@ cleanup (void *cls GNUNET_UNUSED, | |||
2764 | 3071 | ||
2765 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3072 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2766 | "Exit service is shutting down now\n"); | 3073 | "Exit service is shutting down now\n"); |
3074 | |||
2767 | if (helper_handle != NULL) | 3075 | if (helper_handle != NULL) |
2768 | { | 3076 | { |
2769 | GNUNET_HELPER_stop (helper_handle); | 3077 | GNUNET_HELPER_stop (helper_handle); |
@@ -2797,6 +3105,11 @@ cleanup (void *cls GNUNET_UNUSED, | |||
2797 | GNUNET_CONTAINER_multihashmap_destroy (udp_services); | 3105 | GNUNET_CONTAINER_multihashmap_destroy (udp_services); |
2798 | udp_services = NULL; | 3106 | udp_services = NULL; |
2799 | } | 3107 | } |
3108 | if (NULL != dnsstub) | ||
3109 | { | ||
3110 | GNUNET_DNSSTUB_stop (dnsstub); | ||
3111 | dnsstub = NULL; | ||
3112 | } | ||
2800 | if (stats != NULL) | 3113 | if (stats != NULL) |
2801 | { | 3114 | { |
2802 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 3115 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); |
@@ -2998,12 +3311,14 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
2998 | {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0}, | 3311 | {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0}, |
2999 | {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0}, | 3312 | {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0}, |
3000 | {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0}, | 3313 | {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0}, |
3314 | {&receive_dns_request, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, 0}, | ||
3001 | {NULL, 0, 0} | 3315 | {NULL, 0, 0} |
3002 | }; | 3316 | }; |
3003 | 3317 | ||
3004 | static GNUNET_MESH_ApplicationType apptypes[] = { | 3318 | static GNUNET_MESH_ApplicationType apptypes[] = { |
3005 | GNUNET_APPLICATION_TYPE_END, | 3319 | GNUNET_APPLICATION_TYPE_END, |
3006 | GNUNET_APPLICATION_TYPE_END, | 3320 | GNUNET_APPLICATION_TYPE_END, |
3321 | GNUNET_APPLICATION_TYPE_END, | ||
3007 | GNUNET_APPLICATION_TYPE_END | 3322 | GNUNET_APPLICATION_TYPE_END |
3008 | }; | 3323 | }; |
3009 | unsigned int app_idx; | 3324 | unsigned int app_idx; |
@@ -3016,25 +3331,31 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
3016 | char *binary; | 3331 | char *binary; |
3017 | char *regex; | 3332 | char *regex; |
3018 | char *prefixed_regex; | 3333 | char *prefixed_regex; |
3334 | struct in_addr dns_exit4; | ||
3335 | struct in6_addr dns_exit6; | ||
3336 | char *dns_exit; | ||
3019 | 3337 | ||
3020 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit"); | ||
3021 | if (GNUNET_YES != | ||
3022 | GNUNET_OS_check_helper_binary (binary)) | ||
3023 | { | ||
3024 | GNUNET_free (binary); | ||
3025 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
3026 | _("`%s' must be installed SUID, refusing to run\n"), | ||
3027 | "gnunet-helper-exit"); | ||
3028 | global_ret = 1; | ||
3029 | return; | ||
3030 | } | ||
3031 | GNUNET_free (binary); | ||
3032 | cfg = cfg_; | 3338 | cfg = cfg_; |
3033 | stats = GNUNET_STATISTICS_create ("exit", cfg); | ||
3034 | ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4"); | 3339 | ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4"); |
3035 | ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6"); | 3340 | ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6"); |
3036 | ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4"); | 3341 | ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4"); |
3037 | ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6"); | 3342 | ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6"); |
3343 | if ( (ipv4_exit) || (ipv6_exit) ) | ||
3344 | { | ||
3345 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit"); | ||
3346 | if (GNUNET_YES != | ||
3347 | GNUNET_OS_check_helper_binary (binary)) | ||
3348 | { | ||
3349 | GNUNET_free (binary); | ||
3350 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
3351 | _("`%s' must be installed SUID, refusing to run\n"), | ||
3352 | "gnunet-helper-exit"); | ||
3353 | global_ret = 1; | ||
3354 | return; | ||
3355 | } | ||
3356 | GNUNET_free (binary); | ||
3357 | } | ||
3358 | stats = GNUNET_STATISTICS_create ("exit", cfg); | ||
3038 | 3359 | ||
3039 | if ( (ipv4_exit || ipv4_enabled) && | 3360 | if ( (ipv4_exit || ipv4_enabled) && |
3040 | GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) | 3361 | GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) |
@@ -3071,6 +3392,26 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
3071 | GNUNET_SCHEDULER_shutdown (); | 3392 | GNUNET_SCHEDULER_shutdown (); |
3072 | return; | 3393 | return; |
3073 | } | 3394 | } |
3395 | |||
3396 | dns_exit = NULL; | ||
3397 | if ( (GNUNET_YES == | ||
3398 | GNUNET_CONFIGURATION_get_value_yesno (cfg_, "exit", "ENABLE_DNS")) && | ||
3399 | ( (GNUNET_OK != | ||
3400 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", | ||
3401 | "DNS_RESOLVER", | ||
3402 | &dns_exit)) || | ||
3403 | ( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) && | ||
3404 | (1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) ) | ||
3405 | { | ||
3406 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "dns", "DNS_RESOLVER", | ||
3407 | _("need a valid IPv4 or IPv6 address\n")); | ||
3408 | GNUNET_free_non_null (dns_exit); | ||
3409 | dns_exit = NULL; | ||
3410 | } | ||
3411 | if (NULL != dns_exit) | ||
3412 | dnsstub = GNUNET_DNSSTUB_start (dns_exit); | ||
3413 | |||
3414 | |||
3074 | app_idx = 0; | 3415 | app_idx = 0; |
3075 | if (GNUNET_YES == ipv4_exit) | 3416 | if (GNUNET_YES == ipv4_exit) |
3076 | { | 3417 | { |
@@ -3082,6 +3423,11 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
3082 | apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; | 3423 | apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; |
3083 | app_idx++; | 3424 | app_idx++; |
3084 | } | 3425 | } |
3426 | if (NULL != dns_exit) | ||
3427 | { | ||
3428 | apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER; | ||
3429 | app_idx++; | ||
3430 | } | ||
3085 | 3431 | ||
3086 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); | 3432 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); |
3087 | 3433 | ||
@@ -3242,12 +3588,12 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
3242 | GNUNET_free (regex); | 3588 | GNUNET_free (regex); |
3243 | GNUNET_free (prefixed_regex); | 3589 | GNUNET_free (prefixed_regex); |
3244 | } | 3590 | } |
3245 | 3591 | if ((ipv4_exit) || (ipv6_exit)) | |
3246 | helper_handle = GNUNET_HELPER_start (GNUNET_NO, | 3592 | helper_handle = GNUNET_HELPER_start (GNUNET_NO, |
3247 | "gnunet-helper-exit", | 3593 | "gnunet-helper-exit", |
3248 | exit_argv, | 3594 | exit_argv, |
3249 | &message_token, | 3595 | &message_token, |
3250 | NULL, NULL); | 3596 | NULL, NULL); |
3251 | } | 3597 | } |
3252 | 3598 | ||
3253 | 3599 | ||