diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-02-23 14:08:07 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-02-23 14:08:07 +0100 |
commit | 450f962ef7349f2f08fbda705e92acb87884af71 (patch) | |
tree | e9e934560bc343df83149188d41c718497561d12 /src/exit | |
parent | 1108ec482bba414f016b35a45e5d43ff99994b7b (diff) | |
download | gnunet-450f962ef7349f2f08fbda705e92acb87884af71.tar.gz gnunet-450f962ef7349f2f08fbda705e92acb87884af71.zip |
convert EXIT to new CADET MQ API
Diffstat (limited to 'src/exit')
-rw-r--r-- | src/exit/Makefile.am | 8 | ||||
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 3013 |
2 files changed, 1482 insertions, 1539 deletions
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, |