diff options
author | t3sserakt <t3ss@posteo.de> | 2023-01-27 13:07:48 +0100 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2023-01-27 13:07:48 +0100 |
commit | 1a95d92b448b1dc77332781507cb6155b46c45b0 (patch) | |
tree | 1325457b90077904c91e37c4eeef8314df1a8a53 | |
parent | a21cb18203056306fa08ecbcaf4100a6c94cc4d9 (diff) | |
download | gnunet-1a95d92b448b1dc77332781507cb6155b46c45b0.tar.gz gnunet-1a95d92b448b1dc77332781507cb6155b46c45b0.zip |
TNG: Added nat reversal code to tcp communicator. Prepared udp communicator.
-rw-r--r-- | src/transport/gnunet-communicator-tcp.c | 729 | ||||
-rw-r--r-- | src/transport/gnunet-communicator-udp.c | 9 |
2 files changed, 563 insertions, 175 deletions
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c index 84aa45b9a..86b98cee1 100644 --- a/src/transport/gnunet-communicator-tcp.c +++ b/src/transport/gnunet-communicator-tcp.c | |||
@@ -40,6 +40,13 @@ | |||
40 | #include "gnunet_transport_communication_service.h" | 40 | #include "gnunet_transport_communication_service.h" |
41 | #include "gnunet_resolver_service.h" | 41 | #include "gnunet_resolver_service.h" |
42 | 42 | ||
43 | |||
44 | /** | ||
45 | * How long until we give up on establishing an NAT connection? | ||
46 | * Must be > 4 RTT | ||
47 | */ | ||
48 | #define NAT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | ||
49 | |||
43 | /** | 50 | /** |
44 | * How long do we believe our addresses to remain up (before | 51 | * How long do we believe our addresses to remain up (before |
45 | * the other peer should revalidate). | 52 | * the other peer should revalidate). |
@@ -364,10 +371,47 @@ struct TCPFinish | |||
364 | struct GNUNET_ShortHashCode hmac; | 371 | struct GNUNET_ShortHashCode hmac; |
365 | }; | 372 | }; |
366 | 373 | ||
374 | /** | ||
375 | * Basically a WELCOME message, but with the purpose | ||
376 | * of giving the waiting peer a client handle to use | ||
377 | */ | ||
378 | struct TCPNATProbeMessage | ||
379 | { | ||
380 | /** | ||
381 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE. | ||
382 | */ | ||
383 | struct GNUNET_MessageHeader header; | ||
384 | |||
385 | /** | ||
386 | * Identity of the sender of the message. | ||
387 | */ | ||
388 | struct GNUNET_PeerIdentity clientIdentity; | ||
389 | }; | ||
367 | 390 | ||
368 | GNUNET_NETWORK_STRUCT_END | 391 | GNUNET_NETWORK_STRUCT_END |
369 | 392 | ||
370 | /** | 393 | /** |
394 | * Struct for pending nat reversals. | ||
395 | */ | ||
396 | struct PendingReversal | ||
397 | { | ||
398 | /* | ||
399 | * Timeout task. | ||
400 | */ | ||
401 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
402 | |||
403 | /** | ||
404 | * To whom are we like to talk to. | ||
405 | */ | ||
406 | struct GNUNET_PeerIdentity target; | ||
407 | |||
408 | /** | ||
409 | * Address the reversal was send to. | ||
410 | */ | ||
411 | struct sockaddr *in; | ||
412 | }; | ||
413 | |||
414 | /** | ||
371 | * Struct to use as closure. | 415 | * Struct to use as closure. |
372 | */ | 416 | */ |
373 | struct ListenTask | 417 | struct ListenTask |
@@ -653,6 +697,21 @@ struct ProtoQueue | |||
653 | struct GNUNET_NETWORK_Handle *sock; | 697 | struct GNUNET_NETWORK_Handle *sock; |
654 | 698 | ||
655 | /** | 699 | /** |
700 | * ID of write task for this connection. | ||
701 | */ | ||
702 | struct GNUNET_SCHEDULER_Task *write_task; | ||
703 | |||
704 | /** | ||
705 | * buffer for writing struct TCPNATProbeMessage to network. | ||
706 | */ | ||
707 | char write_buf[sizeof (struct TCPNATProbeMessage)]; | ||
708 | |||
709 | /** | ||
710 | * Offset of the buffer? | ||
711 | */ | ||
712 | size_t write_off; | ||
713 | |||
714 | /** | ||
656 | * ID of read task for this connection. | 715 | * ID of read task for this connection. |
657 | */ | 716 | */ |
658 | struct GNUNET_SCHEDULER_Task *read_task; | 717 | struct GNUNET_SCHEDULER_Task *read_task; |
@@ -856,6 +915,11 @@ int shutdown_running = GNUNET_NO; | |||
856 | unsigned int bind_port; | 915 | unsigned int bind_port; |
857 | 916 | ||
858 | /** | 917 | /** |
918 | * Map of pending reversals. | ||
919 | */ | ||
920 | struct GNUNET_CONTAINER_MultiHashMap *pending_reversals; | ||
921 | |||
922 | /** | ||
859 | * We have been notified that our listen socket has something to | 923 | * We have been notified that our listen socket has something to |
860 | * read. Do the read and reschedule this function to be called again | 924 | * read. Do the read and reschedule this function to be called again |
861 | * once more is available. | 925 | * once more is available. |
@@ -1568,6 +1632,134 @@ inject_rekey (struct Queue *queue) | |||
1568 | setup_out_cipher (queue); | 1632 | setup_out_cipher (queue); |
1569 | } | 1633 | } |
1570 | 1634 | ||
1635 | static int | ||
1636 | pending_reversals_delete_it (void *cls, | ||
1637 | const struct GNUNET_HashCode *key, | ||
1638 | void *value) | ||
1639 | { | ||
1640 | (void) cls; | ||
1641 | struct PendingReversal *pending_reversal = value; | ||
1642 | |||
1643 | if (NULL != pending_reversal->timeout_task) | ||
1644 | { | ||
1645 | GNUNET_SCHEDULER_cancel (pending_reversal->timeout_task); | ||
1646 | pending_reversal->timeout_task = NULL; | ||
1647 | } | ||
1648 | GNUNET_CONTAINER_multihashmap_remove (pending_reversals, | ||
1649 | key, | ||
1650 | pending_reversal); | ||
1651 | GNUNET_free (pending_reversal->in); | ||
1652 | GNUNET_free (pending_reversal); | ||
1653 | return GNUNET_OK; | ||
1654 | } | ||
1655 | |||
1656 | |||
1657 | static void | ||
1658 | check_and_remove_pending_reversal (struct sockaddr *in, sa_family_t sa_family, struct GNUNET_PeerIdentity *sender) | ||
1659 | { | ||
1660 | if (AF_INET == sa_family) | ||
1661 | { | ||
1662 | struct PendingReversal *pending_reversal; | ||
1663 | struct GNUNET_HashCode key; | ||
1664 | struct sockaddr_in *natted_address; | ||
1665 | |||
1666 | natted_address = GNUNET_memdup (in, sizeof (struct sockaddr)); | ||
1667 | natted_address->sin_port = 0; | ||
1668 | GNUNET_CRYPTO_hash (natted_address, | ||
1669 | sizeof(struct sockaddr), | ||
1670 | &key); | ||
1671 | |||
1672 | pending_reversal = GNUNET_CONTAINER_multihashmap_get (pending_reversals, | ||
1673 | &key); | ||
1674 | if (NULL != pending_reversal && (NULL == sender || | ||
1675 | 0 != memcmp (sender, &pending_reversal->target, sizeof(struct GNUNET_PeerIdentity)))) | ||
1676 | { | ||
1677 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1678 | "Removing invalid pending reversal for `%s'at `%s'\n", | ||
1679 | GNUNET_i2s (&pending_reversal->target), | ||
1680 | GNUNET_a2s (in, sizeof (in))); | ||
1681 | pending_reversals_delete_it (NULL, &key, pending_reversal); | ||
1682 | } | ||
1683 | GNUNET_free (natted_address); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | |||
1688 | /** | ||
1689 | * Closes socket and frees memory associated with @a pq. | ||
1690 | * | ||
1691 | * @param pq proto queue to free | ||
1692 | */ | ||
1693 | static void | ||
1694 | free_proto_queue (struct ProtoQueue *pq) | ||
1695 | { | ||
1696 | if (NULL != pq->listen_sock) | ||
1697 | { | ||
1698 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pq->listen_sock)); | ||
1699 | pq->listen_sock = NULL; | ||
1700 | } | ||
1701 | if (NULL != pq->read_task) | ||
1702 | { | ||
1703 | GNUNET_SCHEDULER_cancel (pq->read_task); | ||
1704 | pq->read_task = NULL; | ||
1705 | } | ||
1706 | if (NULL != pq->write_task) | ||
1707 | { | ||
1708 | GNUNET_SCHEDULER_cancel (pq->write_task); | ||
1709 | pq->write_task = NULL; | ||
1710 | } | ||
1711 | check_and_remove_pending_reversal (pq->address, pq->address->sa_family, NULL); | ||
1712 | GNUNET_NETWORK_socket_close (pq->sock); | ||
1713 | GNUNET_free (pq->address); | ||
1714 | GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq); | ||
1715 | GNUNET_free (pq); | ||
1716 | } | ||
1717 | |||
1718 | |||
1719 | /** | ||
1720 | * We have been notified that our socket is ready to write. | ||
1721 | * Then reschedule this function to be called again once more is available. | ||
1722 | * | ||
1723 | * @param cls a `struct ProtoQueue` | ||
1724 | */ | ||
1725 | static void | ||
1726 | proto_queue_write (void *cls) | ||
1727 | { | ||
1728 | struct ProtoQueue *pq = cls; | ||
1729 | ssize_t sent; | ||
1730 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In proto queue write\n"); | ||
1731 | pq->write_task = NULL; | ||
1732 | if (0 != pq->write_off) | ||
1733 | { | ||
1734 | sent = GNUNET_NETWORK_socket_send (pq->sock, | ||
1735 | pq->write_buf, | ||
1736 | pq->write_off); | ||
1737 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1738 | "Sent %lu bytes to TCP queue\n", sent); | ||
1739 | if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno)) | ||
1740 | { | ||
1741 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); | ||
1742 | free_proto_queue (pq); | ||
1743 | return; | ||
1744 | } | ||
1745 | if (sent > 0) | ||
1746 | { | ||
1747 | size_t usent = (size_t) sent; | ||
1748 | pq->write_off -= usent; | ||
1749 | memmove (pq->write_buf, | ||
1750 | &pq->write_buf[usent], | ||
1751 | pq->write_off); | ||
1752 | } | ||
1753 | } | ||
1754 | /* do we care to write more? */ | ||
1755 | if ((0 < pq->write_off)) | ||
1756 | pq->write_task = | ||
1757 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1758 | pq->sock, | ||
1759 | &proto_queue_write, | ||
1760 | pq); | ||
1761 | } | ||
1762 | |||
1571 | 1763 | ||
1572 | /** | 1764 | /** |
1573 | * We have been notified that our socket is ready to write. | 1765 | * We have been notified that our socket is ready to write. |
@@ -1779,6 +1971,10 @@ try_handle_plaintext (struct Queue *queue) | |||
1779 | &queue_write, | 1971 | &queue_write, |
1780 | queue); | 1972 | queue); |
1781 | } | 1973 | } |
1974 | else if (GNUNET_TRANSPORT_CS_OUTBOUND == queue->cs) | ||
1975 | { | ||
1976 | check_and_remove_pending_reversal (queue->address, queue->address->sa_family, NULL); | ||
1977 | } | ||
1782 | 1978 | ||
1783 | unverified_size = -1; | 1979 | unverified_size = -1; |
1784 | 1980 | ||
@@ -2659,22 +2855,99 @@ decrypt_and_check_tc (struct Queue *queue, | |||
2659 | 2855 | ||
2660 | 2856 | ||
2661 | /** | 2857 | /** |
2662 | * Closes socket and frees memory associated with @a pq. | 2858 | * Read from the socket of the queue until we have enough data |
2859 | * to initialize the decryption logic and can switch to regular | ||
2860 | * reading. | ||
2663 | * | 2861 | * |
2664 | * @param pq proto queue to free | 2862 | * @param cls a `struct Queue` |
2665 | */ | 2863 | */ |
2666 | static void | 2864 | static void |
2667 | free_proto_queue (struct ProtoQueue *pq) | 2865 | queue_read_kx (void *cls) |
2668 | { | 2866 | { |
2669 | if (NULL != pq->listen_sock) | 2867 | struct Queue *queue = cls; |
2868 | ssize_t rcvd; | ||
2869 | struct GNUNET_TIME_Relative left; | ||
2870 | struct TCPConfirmation tc; | ||
2871 | |||
2872 | queue->read_task = NULL; | ||
2873 | left = GNUNET_TIME_absolute_get_remaining (queue->timeout); | ||
2874 | if (0 == left.rel_value_us) | ||
2670 | { | 2875 | { |
2671 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pq->listen_sock)); | 2876 | queue_destroy (queue); |
2672 | pq->listen_sock = NULL; | 2877 | return; |
2673 | } | 2878 | } |
2674 | GNUNET_NETWORK_socket_close (pq->sock); | 2879 | rcvd = GNUNET_NETWORK_socket_recv (queue->sock, |
2675 | GNUNET_free (pq->address); | 2880 | &queue->cread_buf[queue->cread_off], |
2676 | GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq); | 2881 | BUF_SIZE - queue->cread_off); |
2677 | GNUNET_free (pq); | 2882 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2883 | "Received %lu bytes for KX\n", | ||
2884 | rcvd); | ||
2885 | GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG, | ||
2886 | "transport", | ||
2887 | "Received %lu bytes for KX\n", | ||
2888 | rcvd); | ||
2889 | if (-1 == rcvd) | ||
2890 | { | ||
2891 | if ((EAGAIN != errno) && (EINTR != errno)) | ||
2892 | { | ||
2893 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv"); | ||
2894 | queue_destroy (queue); | ||
2895 | return; | ||
2896 | } | ||
2897 | queue->read_task = | ||
2898 | GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue); | ||
2899 | return; | ||
2900 | } | ||
2901 | queue->cread_off += rcvd; | ||
2902 | if (queue->cread_off < INITIAL_KX_SIZE) | ||
2903 | { | ||
2904 | /* read more */ | ||
2905 | queue->read_task = | ||
2906 | GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue); | ||
2907 | return; | ||
2908 | } | ||
2909 | /* we got all the data, let's find out who we are talking to! */ | ||
2910 | setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) | ||
2911 | queue->cread_buf, | ||
2912 | queue); | ||
2913 | if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf)) | ||
2914 | { | ||
2915 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2916 | "Invalid TCP KX received from %s\n", | ||
2917 | GNUNET_a2s (queue->address, queue->address_len)); | ||
2918 | queue_destroy (queue); | ||
2919 | return; | ||
2920 | } | ||
2921 | if (0 != | ||
2922 | memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity))) | ||
2923 | { | ||
2924 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2925 | "Invalid sender in TCP KX received from %s\n", | ||
2926 | GNUNET_a2s (queue->address, queue->address_len)); | ||
2927 | queue_destroy (queue); | ||
2928 | return; | ||
2929 | } | ||
2930 | send_challenge (tc.challenge, queue); | ||
2931 | queue->write_task = | ||
2932 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
2933 | queue->sock, | ||
2934 | &queue_write, | ||
2935 | queue); | ||
2936 | |||
2937 | /* update queue timeout */ | ||
2938 | reschedule_queue_timeout (queue); | ||
2939 | /* prepare to continue with regular read task immediately */ | ||
2940 | memmove (queue->cread_buf, | ||
2941 | &queue->cread_buf[INITIAL_KX_SIZE], | ||
2942 | queue->cread_off - (INITIAL_KX_SIZE)); | ||
2943 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2944 | "cread_off is %lu bytes before adjusting\n", | ||
2945 | queue->cread_off); | ||
2946 | queue->cread_off -= INITIAL_KX_SIZE; | ||
2947 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2948 | "cread_off set to %lu bytes\n", | ||
2949 | queue->cread_off); | ||
2950 | queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue); | ||
2678 | } | 2951 | } |
2679 | 2952 | ||
2680 | 2953 | ||
@@ -2692,6 +2965,7 @@ proto_read_kx (void *cls) | |||
2692 | struct GNUNET_TIME_Relative left; | 2965 | struct GNUNET_TIME_Relative left; |
2693 | struct Queue *queue; | 2966 | struct Queue *queue; |
2694 | struct TCPConfirmation tc; | 2967 | struct TCPConfirmation tc; |
2968 | GNUNET_SCHEDULER_TaskCallback read_task; | ||
2695 | 2969 | ||
2696 | pq->read_task = NULL; | 2970 | pq->read_task = NULL; |
2697 | left = GNUNET_TIME_absolute_get_remaining (pq->timeout); | 2971 | left = GNUNET_TIME_absolute_get_remaining (pq->timeout); |
@@ -2704,10 +2978,10 @@ proto_read_kx (void *cls) | |||
2704 | &pq->ibuf[pq->ibuf_off], | 2978 | &pq->ibuf[pq->ibuf_off], |
2705 | sizeof(pq->ibuf) - pq->ibuf_off); | 2979 | sizeof(pq->ibuf) - pq->ibuf_off); |
2706 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2980 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2707 | "Received %lu bytes for KX\n", rcvd); | 2981 | "Proto received %lu bytes for KX\n", rcvd); |
2708 | GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG, | 2982 | GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG, |
2709 | "transport", | 2983 | "transport", |
2710 | "Received %lu bytes for KX\n", rcvd); | 2984 | "Proto received %lu bytes for KX\n", rcvd); |
2711 | if (-1 == rcvd) | 2985 | if (-1 == rcvd) |
2712 | { | 2986 | { |
2713 | if ((EAGAIN != errno) && (EINTR != errno)) | 2987 | if ((EAGAIN != errno) && (EINTR != errno)) |
@@ -2722,30 +2996,46 @@ proto_read_kx (void *cls) | |||
2722 | return; | 2996 | return; |
2723 | } | 2997 | } |
2724 | pq->ibuf_off += rcvd; | 2998 | pq->ibuf_off += rcvd; |
2725 | if (pq->ibuf_off > sizeof(pq->ibuf)) | 2999 | if (sizeof (struct TCPNATProbeMessage) == pq->ibuf_off) |
3000 | { | ||
3001 | struct TCPNATProbeMessage *pm = (struct TCPNATProbeMessage *) pq->ibuf; | ||
3002 | |||
3003 | check_and_remove_pending_reversal (pq->address, pq->address->sa_family, &pm->clientIdentity); | ||
3004 | |||
3005 | queue = GNUNET_new (struct Queue); | ||
3006 | queue->target = pm->clientIdentity; | ||
3007 | queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND; | ||
3008 | read_task = &queue_read_kx; | ||
3009 | } | ||
3010 | else if (pq->ibuf_off > sizeof(pq->ibuf)) | ||
2726 | { | 3011 | { |
2727 | /* read more */ | 3012 | /* read more */ |
2728 | pq->read_task = | 3013 | pq->read_task = |
2729 | GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq); | 3014 | GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq); |
2730 | return; | 3015 | return; |
2731 | } | 3016 | } |
2732 | /* we got all the data, let's find out who we are talking to! */ | 3017 | else |
2733 | queue = GNUNET_new (struct Queue); | ||
2734 | setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf, | ||
2735 | queue); | ||
2736 | if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf)) | ||
2737 | { | 3018 | { |
2738 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 3019 | /* we got all the data, let's find out who we are talking to! */ |
2739 | "Invalid TCP KX received from %s\n", | 3020 | queue = GNUNET_new (struct Queue); |
2740 | GNUNET_a2s (pq->address, pq->address_len)); | 3021 | setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf, |
2741 | gcry_cipher_close (queue->in_cipher); | 3022 | queue); |
2742 | GNUNET_free (queue); | 3023 | if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf)) |
2743 | free_proto_queue (pq); | 3024 | { |
2744 | return; | 3025 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
3026 | "Invalid TCP KX received from %s\n", | ||
3027 | GNUNET_a2s (pq->address, pq->address_len)); | ||
3028 | gcry_cipher_close (queue->in_cipher); | ||
3029 | GNUNET_free (queue); | ||
3030 | free_proto_queue (pq); | ||
3031 | return; | ||
3032 | } | ||
3033 | queue->target = tc.sender; | ||
3034 | queue->cs = GNUNET_TRANSPORT_CS_INBOUND; | ||
3035 | read_task = &queue_read; | ||
2745 | } | 3036 | } |
2746 | queue->address = pq->address; /* steals reference */ | 3037 | queue->address = pq->address; /* steals reference */ |
2747 | queue->address_len = pq->address_len; | 3038 | queue->address_len = pq->address_len; |
2748 | queue->target = tc.sender; | ||
2749 | queue->listen_sock = pq->listen_sock; | 3039 | queue->listen_sock = pq->listen_sock; |
2750 | queue->sock = pq->sock; | 3040 | queue->sock = pq->sock; |
2751 | 3041 | ||
@@ -2757,12 +3047,11 @@ proto_read_kx (void *cls) | |||
2757 | "start kx proto\n"); | 3047 | "start kx proto\n"); |
2758 | 3048 | ||
2759 | start_initial_kx_out (queue); | 3049 | start_initial_kx_out (queue); |
2760 | queue->cs = GNUNET_TRANSPORT_CS_INBOUND; | ||
2761 | boot_queue (queue); | 3050 | boot_queue (queue); |
2762 | queue->read_task = | 3051 | queue->read_task = |
2763 | GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | 3052 | GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, |
2764 | queue->sock, | 3053 | queue->sock, |
2765 | &queue_read, | 3054 | read_task, |
2766 | queue); | 3055 | queue); |
2767 | queue->write_task = | 3056 | queue->write_task = |
2768 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | 3057 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
@@ -2777,6 +3066,51 @@ proto_read_kx (void *cls) | |||
2777 | GNUNET_free (pq); | 3066 | GNUNET_free (pq); |
2778 | } | 3067 | } |
2779 | 3068 | ||
3069 | static struct ProtoQueue * | ||
3070 | create_proto_queue (struct GNUNET_NETWORK_Handle *sock, | ||
3071 | struct sockaddr *in, | ||
3072 | socklen_t addrlen) | ||
3073 | { | ||
3074 | struct ProtoQueue *pq = GNUNET_new (struct ProtoQueue); | ||
3075 | |||
3076 | if (NULL == sock) | ||
3077 | { | ||
3078 | //sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, addr, addrlen); | ||
3079 | sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, 0); | ||
3080 | if (NULL == sock) | ||
3081 | { | ||
3082 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3083 | "socket(%d) failed: %s", | ||
3084 | in->sa_family, | ||
3085 | strerror (errno)); | ||
3086 | GNUNET_free (in); | ||
3087 | return NULL; | ||
3088 | } | ||
3089 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, addrlen)) && | ||
3090 | (errno != EINPROGRESS)) | ||
3091 | { | ||
3092 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3093 | "connect to `%s' failed: %s", | ||
3094 | GNUNET_a2s (in, addrlen), | ||
3095 | strerror (errno)); | ||
3096 | GNUNET_NETWORK_socket_close (sock); | ||
3097 | GNUNET_free (in); | ||
3098 | return NULL; | ||
3099 | } | ||
3100 | } | ||
3101 | pq->address_len = addrlen; | ||
3102 | pq->address = in; | ||
3103 | pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT); | ||
3104 | pq->sock = sock; | ||
3105 | pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT, | ||
3106 | pq->sock, | ||
3107 | &proto_read_kx, | ||
3108 | pq); | ||
3109 | GNUNET_CONTAINER_DLL_insert (proto_head, proto_tail, pq); | ||
3110 | |||
3111 | return pq; | ||
3112 | } | ||
3113 | |||
2780 | 3114 | ||
2781 | /** | 3115 | /** |
2782 | * We have been notified that our listen socket has something to | 3116 | * We have been notified that our listen socket has something to |
@@ -2793,6 +3127,7 @@ listen_cb (void *cls) | |||
2793 | struct GNUNET_NETWORK_Handle *sock; | 3127 | struct GNUNET_NETWORK_Handle *sock; |
2794 | struct ProtoQueue *pq; | 3128 | struct ProtoQueue *pq; |
2795 | struct ListenTask *lt; | 3129 | struct ListenTask *lt; |
3130 | struct sockaddr *in_addr; | ||
2796 | 3131 | ||
2797 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3132 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2798 | "listen_cb\n"); | 3133 | "listen_cb\n"); |
@@ -2819,113 +3154,71 @@ listen_cb (void *cls) | |||
2819 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); | 3154 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); |
2820 | return; | 3155 | return; |
2821 | } | 3156 | } |
2822 | pq = GNUNET_new (struct ProtoQueue); | 3157 | in_addr = GNUNET_memdup (&in, addrlen); |
2823 | pq->address_len = addrlen; | 3158 | create_proto_queue (sock, in_addr, addrlen); |
2824 | pq->address = GNUNET_memdup (&in, addrlen); | ||
2825 | pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT); | ||
2826 | pq->sock = sock; | ||
2827 | pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT, | ||
2828 | pq->sock, | ||
2829 | &proto_read_kx, | ||
2830 | pq); | ||
2831 | GNUNET_CONTAINER_DLL_insert (proto_head, proto_tail, pq); | ||
2832 | } | 3159 | } |
2833 | 3160 | ||
2834 | 3161 | ||
2835 | /** | ||
2836 | * Read from the socket of the queue until we have enough data | ||
2837 | * to initialize the decryption logic and can switch to regular | ||
2838 | * reading. | ||
2839 | * | ||
2840 | * @param cls a `struct Queue` | ||
2841 | */ | ||
2842 | static void | 3162 | static void |
2843 | queue_read_kx (void *cls) | 3163 | try_connection_reversal (void *cls, |
3164 | const struct sockaddr *addr, | ||
3165 | socklen_t addrlen) | ||
2844 | { | 3166 | { |
2845 | struct Queue *queue = cls; | 3167 | (void) cls; |
2846 | ssize_t rcvd; | 3168 | struct TCPNATProbeMessage pm; |
2847 | struct GNUNET_TIME_Relative left; | 3169 | struct ProtoQueue *pq; |
2848 | struct TCPConfirmation tc; | 3170 | struct sockaddr *in_addr; |
2849 | 3171 | ||
2850 | queue->read_task = NULL; | ||
2851 | left = GNUNET_TIME_absolute_get_remaining (queue->timeout); | ||
2852 | if (0 == left.rel_value_us) | ||
2853 | { | ||
2854 | queue_destroy (queue); | ||
2855 | return; | ||
2856 | } | ||
2857 | rcvd = GNUNET_NETWORK_socket_recv (queue->sock, | ||
2858 | &queue->cread_buf[queue->cread_off], | ||
2859 | BUF_SIZE - queue->cread_off); | ||
2860 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2861 | "Received %lu bytes for KX\n", | 3173 | "addr->sa_family %d\n", |
2862 | rcvd); | 3174 | addr->sa_family); |
2863 | GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG, | 3175 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2864 | "transport", | 3176 | "Try to connect back\n"); |
2865 | "Received %lu bytes for KX\n", | 3177 | in_addr = GNUNET_memdup (addr, addrlen); |
2866 | rcvd); | 3178 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2867 | if (-1 == rcvd) | 3179 | "in_addr->sa_family %d\n", |
2868 | { | 3180 | in_addr->sa_family); |
2869 | if ((EAGAIN != errno) && (EINTR != errno)) | 3181 | pq = create_proto_queue (NULL, in_addr, addrlen); |
2870 | { | 3182 | if (NULL != pq) |
2871 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv"); | 3183 | { |
2872 | queue_destroy (queue); | 3184 | pm.header.size = htons (sizeof(struct TCPNATProbeMessage)); |
2873 | return; | 3185 | pm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE); |
2874 | } | 3186 | pm.clientIdentity = my_identity; |
2875 | queue->read_task = | 3187 | memcpy (pq->write_buf, &pm, sizeof(struct TCPNATProbeMessage)); |
2876 | GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue); | 3188 | pq->write_off = sizeof(struct TCPNATProbeMessage); |
2877 | return; | 3189 | pq->write_task = GNUNET_SCHEDULER_add_write_net (PROTO_QUEUE_TIMEOUT, |
2878 | } | 3190 | pq->sock, |
2879 | queue->cread_off += rcvd; | 3191 | &proto_queue_write, |
2880 | if (queue->cread_off < INITIAL_KX_SIZE) | 3192 | pq); |
2881 | { | ||
2882 | /* read more */ | ||
2883 | queue->read_task = | ||
2884 | GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue); | ||
2885 | return; | ||
2886 | } | ||
2887 | /* we got all the data, let's find out who we are talking to! */ | ||
2888 | setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) | ||
2889 | queue->cread_buf, | ||
2890 | queue); | ||
2891 | if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf)) | ||
2892 | { | ||
2893 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2894 | "Invalid TCP KX received from %s\n", | ||
2895 | GNUNET_a2s (queue->address, queue->address_len)); | ||
2896 | queue_destroy (queue); | ||
2897 | return; | ||
2898 | } | 3193 | } |
2899 | if (0 != | 3194 | else |
2900 | memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity))) | ||
2901 | { | 3195 | { |
2902 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 3196 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2903 | "Invalid sender in TCP KX received from %s\n", | 3197 | "Couldn't create ProtoQueue for sending TCPNATProbeMessage\n"); |
2904 | GNUNET_a2s (queue->address, queue->address_len)); | ||
2905 | queue_destroy (queue); | ||
2906 | return; | ||
2907 | } | 3198 | } |
2908 | send_challenge (tc.challenge, queue); | 3199 | } |
2909 | queue->write_task = | ||
2910 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
2911 | queue->sock, | ||
2912 | &queue_write, | ||
2913 | queue); | ||
2914 | 3200 | ||
2915 | /* update queue timeout */ | 3201 | |
2916 | reschedule_queue_timeout (queue); | 3202 | static void |
2917 | /* prepare to continue with regular read task immediately */ | 3203 | pending_reversal_timeout (void *cls) |
2918 | memmove (queue->cread_buf, | 3204 | { |
2919 | &queue->cread_buf[INITIAL_KX_SIZE], | 3205 | struct sockaddr *in = cls; |
2920 | queue->cread_off - (INITIAL_KX_SIZE)); | 3206 | struct PendingReversal *pending_reversal; |
2921 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3207 | struct GNUNET_HashCode key; |
2922 | "cread_off is %lu bytes before adjusting\n", | 3208 | |
2923 | queue->cread_off); | 3209 | GNUNET_CRYPTO_hash (in, |
2924 | queue->cread_off -= INITIAL_KX_SIZE; | 3210 | sizeof(struct sockaddr), |
2925 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3211 | &key); |
2926 | "cread_off set to %lu bytes\n", | 3212 | pending_reversal = GNUNET_CONTAINER_multihashmap_get (pending_reversals, |
2927 | queue->cread_off); | 3213 | &key); |
2928 | queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue); | 3214 | |
3215 | GNUNET_assert (NULL != pending_reversal); | ||
3216 | |||
3217 | GNUNET_CONTAINER_multihashmap_remove (pending_reversals, | ||
3218 | &key, | ||
3219 | pending_reversal); | ||
3220 | GNUNET_free (pending_reversal->in); | ||
3221 | GNUNET_free (pending_reversal); | ||
2929 | } | 3222 | } |
2930 | 3223 | ||
2931 | 3224 | ||
@@ -2950,17 +3243,18 @@ queue_read_kx (void *cls) | |||
2950 | static int | 3243 | static int |
2951 | mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) | 3244 | mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) |
2952 | { | 3245 | { |
2953 | struct Queue *queue; | ||
2954 | const char *path; | ||
2955 | struct sockaddr *in; | 3246 | struct sockaddr *in; |
2956 | socklen_t in_len = 0; | 3247 | socklen_t in_len = 0; |
2957 | struct GNUNET_NETWORK_Handle *sock; | 3248 | const char *path; |
3249 | struct sockaddr_in *v4; | ||
3250 | struct sockaddr_in6 *v6; | ||
3251 | unsigned int is_natd = GNUNET_NO; | ||
3252 | struct GNUNET_HashCode key; | ||
2958 | 3253 | ||
2959 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3254 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2960 | "Connecting to %s\n", address); | 3255 | "Connecting to %s at %s\n", |
2961 | GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG, | 3256 | GNUNET_i2s (peer), |
2962 | "transport", | 3257 | address); |
2963 | "Connecting to %s\n", address); | ||
2964 | if (0 != strncmp (address, | 3258 | if (0 != strncmp (address, |
2965 | COMMUNICATOR_ADDRESS_PREFIX "-", | 3259 | COMMUNICATOR_ADDRESS_PREFIX "-", |
2966 | strlen (COMMUNICATOR_ADDRESS_PREFIX "-"))) | 3260 | strlen (COMMUNICATOR_ADDRESS_PREFIX "-"))) |
@@ -2982,55 +3276,135 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) | |||
2982 | "in %s\n", | 3276 | "in %s\n", |
2983 | GNUNET_a2s (in, in_len)); | 3277 | GNUNET_a2s (in, in_len)); |
2984 | 3278 | ||
2985 | sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP); | 3279 | switch (in->sa_family) |
2986 | if (NULL == sock) | 3280 | { |
3281 | case AF_INET: | ||
3282 | v4 = (struct sockaddr_in *) in; | ||
3283 | if (0 == v4->sin_port){ | ||
3284 | is_natd = GNUNET_YES; | ||
3285 | GNUNET_CRYPTO_hash (in, | ||
3286 | sizeof(struct sockaddr), | ||
3287 | &key); | ||
3288 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (pending_reversals, | ||
3289 | &key)) | ||
3290 | { | ||
3291 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3292 | "There is already a request reversal for `%s'at `%s'\n", | ||
3293 | GNUNET_i2s (peer), | ||
3294 | address); | ||
3295 | GNUNET_free (in); | ||
3296 | return GNUNET_SYSERR; | ||
3297 | } | ||
3298 | } | ||
3299 | break; | ||
3300 | |||
3301 | case AF_INET6: | ||
3302 | v6 = (struct sockaddr_in6 *) in; | ||
3303 | if (0 == v6->sin6_port) | ||
3304 | { | ||
3305 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3306 | "Request reversal for `%s' at `%s' not possible for an IPv6 address\n", | ||
3307 | GNUNET_i2s (peer), | ||
3308 | address); | ||
3309 | GNUNET_free (in); | ||
3310 | return GNUNET_SYSERR; | ||
3311 | } | ||
3312 | break; | ||
3313 | |||
3314 | default: | ||
3315 | GNUNET_assert (0); | ||
3316 | } | ||
3317 | |||
3318 | if (GNUNET_YES == is_natd) | ||
2987 | { | 3319 | { |
2988 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 3320 | struct sockaddr_in local_sa; |
2989 | "socket(%d) failed: %s", | 3321 | struct PendingReversal *pending_reversal; |
2990 | in->sa_family, | 3322 | |
2991 | strerror (errno)); | 3323 | memset (&local_sa, 0, sizeof(local_sa)); |
2992 | GNUNET_free (in); | 3324 | local_sa.sin_family = AF_INET; |
2993 | return GNUNET_SYSERR; | 3325 | local_sa.sin_port = htons (bind_port); |
3326 | /* We leave sin_address at 0, let the kernel figure it out, | ||
3327 | even if our bind() is more specific. (May want to reconsider | ||
3328 | later.) */ | ||
3329 | if (GNUNET_OK != GNUNET_NAT_request_reversal (nat, &local_sa, v4)) | ||
3330 | { | ||
3331 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3332 | "request reversal for `%s' at `%s' failed\n", | ||
3333 | GNUNET_i2s (peer), | ||
3334 | address); | ||
3335 | GNUNET_free (in); | ||
3336 | return GNUNET_SYSERR; | ||
3337 | } | ||
3338 | pending_reversal = GNUNET_new (struct PendingReversal); | ||
3339 | pending_reversal->in = in; | ||
3340 | GNUNET_assert (GNUNET_OK == | ||
3341 | GNUNET_CONTAINER_multihashmap_put (pending_reversals, | ||
3342 | &key, | ||
3343 | pending_reversal, | ||
3344 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
3345 | pending_reversal->target = *peer; | ||
3346 | pending_reversal->timeout_task = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT, &pending_reversal_timeout, in); | ||
3347 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3348 | "Created NAT WAIT connection to `%s' at `%s'\n", | ||
3349 | GNUNET_i2s (peer), | ||
3350 | GNUNET_a2s (in, sizeof (struct sockaddr))); | ||
2994 | } | 3351 | } |
2995 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) && | 3352 | else |
2996 | (errno != EINPROGRESS)) | ||
2997 | { | 3353 | { |
2998 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 3354 | struct GNUNET_NETWORK_Handle *sock; |
2999 | "connect to `%s' failed: %s", | 3355 | struct Queue *queue; |
3000 | address, | ||
3001 | strerror (errno)); | ||
3002 | GNUNET_NETWORK_socket_close (sock); | ||
3003 | GNUNET_free (in); | ||
3004 | return GNUNET_SYSERR; | ||
3005 | } | ||
3006 | 3356 | ||
3007 | queue = GNUNET_new (struct Queue); | 3357 | sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP); |
3008 | queue->target = *peer; | 3358 | if (NULL == sock) |
3009 | queue->address = in; | 3359 | { |
3010 | queue->address_len = in_len; | 3360 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
3011 | queue->sock = sock; | 3361 | "socket(%d) failed: %s", |
3012 | queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND; | 3362 | in->sa_family, |
3013 | boot_queue (queue); | 3363 | strerror (errno)); |
3014 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3364 | GNUNET_free (in); |
3015 | "booted queue with target %s\n", | 3365 | return GNUNET_SYSERR; |
3016 | GNUNET_i2s (&queue->target)); | 3366 | } |
3017 | // queue->mq_awaits_continue = GNUNET_YES; | 3367 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) && |
3018 | queue->read_task = | 3368 | (errno != EINPROGRESS)) |
3019 | GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | 3369 | { |
3020 | queue->sock, | 3370 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
3021 | &queue_read_kx, | 3371 | "connect to `%s' failed: %s", |
3022 | queue); | 3372 | address, |
3373 | strerror (errno)); | ||
3374 | GNUNET_NETWORK_socket_close (sock); | ||
3375 | GNUNET_free (in); | ||
3376 | return GNUNET_SYSERR; | ||
3377 | } | ||
3023 | 3378 | ||
3379 | queue = GNUNET_new (struct Queue); | ||
3380 | queue->target = *peer; | ||
3381 | queue->address = in; | ||
3382 | queue->address_len = in_len; | ||
3383 | queue->sock = sock; | ||
3384 | queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND; | ||
3385 | boot_queue (queue); | ||
3386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3387 | "booted queue with target %s\n", | ||
3388 | GNUNET_i2s (&queue->target)); | ||
3389 | // queue->mq_awaits_continue = GNUNET_YES; | ||
3390 | queue->read_task = | ||
3391 | GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
3392 | queue->sock, | ||
3393 | &queue_read_kx, | ||
3394 | queue); | ||
3024 | 3395 | ||
3025 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3026 | "start kx mq_init\n"); | ||
3027 | 3396 | ||
3028 | start_initial_kx_out (queue); | 3397 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3029 | queue->write_task = | 3398 | "start kx mq_init\n"); |
3030 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | 3399 | |
3031 | queue->sock, | 3400 | start_initial_kx_out (queue); |
3032 | &queue_write, | 3401 | queue->write_task = |
3033 | queue); | 3402 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
3403 | queue->sock, | ||
3404 | &queue_write, | ||
3405 | queue); | ||
3406 | } | ||
3407 | |||
3034 | return GNUNET_OK; | 3408 | return GNUNET_OK; |
3035 | } | 3409 | } |
3036 | 3410 | ||
@@ -3062,6 +3436,7 @@ get_lt_delete_it (void *cls, | |||
3062 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lt->listen_sock)); | 3436 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lt->listen_sock)); |
3063 | lt->listen_sock = NULL; | 3437 | lt->listen_sock = NULL; |
3064 | } | 3438 | } |
3439 | GNUNET_free (lt); | ||
3065 | return GNUNET_OK; | 3440 | return GNUNET_OK; |
3066 | } | 3441 | } |
3067 | 3442 | ||
@@ -3112,7 +3487,10 @@ do_shutdown (void *cls) | |||
3112 | GNUNET_NAT_unregister (nat); | 3487 | GNUNET_NAT_unregister (nat); |
3113 | nat = NULL; | 3488 | nat = NULL; |
3114 | } | 3489 | } |
3490 | GNUNET_CONTAINER_multihashmap_iterate (pending_reversals, &pending_reversals_delete_it, NULL); | ||
3491 | GNUNET_CONTAINER_multihashmap_destroy (pending_reversals); | ||
3115 | GNUNET_CONTAINER_multihashmap_iterate (lt_map, &get_lt_delete_it, NULL); | 3492 | GNUNET_CONTAINER_multihashmap_iterate (lt_map, &get_lt_delete_it, NULL); |
3493 | GNUNET_CONTAINER_multihashmap_destroy (lt_map); | ||
3116 | GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL); | 3494 | GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL); |
3117 | GNUNET_CONTAINER_multipeermap_destroy (queue_map); | 3495 | GNUNET_CONTAINER_multipeermap_destroy (queue_map); |
3118 | if (NULL != ch) | 3496 | if (NULL != ch) |
@@ -3454,7 +3832,7 @@ nat_register () | |||
3454 | (const struct sockaddr **) saddrs, | 3832 | (const struct sockaddr **) saddrs, |
3455 | saddr_lens, | 3833 | saddr_lens, |
3456 | &nat_address_cb, | 3834 | &nat_address_cb, |
3457 | NULL /* FIXME: support reversal: #5529 */, | 3835 | try_connection_reversal, |
3458 | NULL /* closure */); | 3836 | NULL /* closure */); |
3459 | for (i = addrs_lens - 1; i >= 0; i--) | 3837 | for (i = addrs_lens - 1; i >= 0; i--) |
3460 | GNUNET_free (saddrs[i]); | 3838 | GNUNET_free (saddrs[i]); |
@@ -3554,6 +3932,8 @@ run (void *cls, | |||
3554 | socklen_t addr_len_ipv6; | 3932 | socklen_t addr_len_ipv6; |
3555 | 3933 | ||
3556 | (void) cls; | 3934 | (void) cls; |
3935 | |||
3936 | pending_reversals = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO); | ||
3557 | memset (&v4,0,sizeof(struct sockaddr_in)); | 3937 | memset (&v4,0,sizeof(struct sockaddr_in)); |
3558 | memset (&v6,0,sizeof(struct sockaddr_in6)); | 3938 | memset (&v6,0,sizeof(struct sockaddr_in6)); |
3559 | cfg = c; | 3939 | cfg = c; |
@@ -3647,6 +4027,7 @@ run (void *cls, | |||
3647 | GNUNET_TIME_UNIT_MINUTES, | 4027 | GNUNET_TIME_UNIT_MINUTES, |
3648 | &init_socket_resolv, | 4028 | &init_socket_resolv, |
3649 | &port); | 4029 | &port); |
4030 | |||
3650 | GNUNET_free (bindto); | 4031 | GNUNET_free (bindto); |
3651 | GNUNET_free (start); | 4032 | GNUNET_free (start); |
3652 | } | 4033 | } |
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index 282902f1c..6b2985b59 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c | |||
@@ -3735,6 +3735,13 @@ do_broadcast (void *cls) | |||
3735 | NULL); | 3735 | NULL); |
3736 | } | 3736 | } |
3737 | 3737 | ||
3738 | static void | ||
3739 | try_connection_reversal (void *cls, | ||
3740 | const struct sockaddr *addr, | ||
3741 | socklen_t addrlen) | ||
3742 | { | ||
3743 | /* FIXME: support reversal: #5529 */ | ||
3744 | } | ||
3738 | 3745 | ||
3739 | /** | 3746 | /** |
3740 | * Setup communicator and launch network interactions. | 3747 | * Setup communicator and launch network interactions. |
@@ -3915,7 +3922,7 @@ run (void *cls, | |||
3915 | (const struct sockaddr **) &in, | 3922 | (const struct sockaddr **) &in, |
3916 | &in_len, | 3923 | &in_len, |
3917 | &nat_address_cb, | 3924 | &nat_address_cb, |
3918 | NULL /* FIXME: support reversal: #5529 */, | 3925 | try_connection_reversal, |
3919 | NULL /* closure */); | 3926 | NULL /* closure */); |
3920 | } | 3927 | } |
3921 | 3928 | ||