aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/Makefile.am1
-rw-r--r--src/transport/gnunet-communicator-tcp.c498
2 files changed, 438 insertions, 61 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 0df3e4e27..ead9beeec 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -256,6 +256,7 @@ gnunet_communicator_tcp_SOURCES = \
256 gnunet-communicator-tcp.c 256 gnunet-communicator-tcp.c
257gnunet_communicator_tcp_LDADD = \ 257gnunet_communicator_tcp_LDADD = \
258 libgnunettransportcommunicator.la \ 258 libgnunettransportcommunicator.la \
259 $(top_builddir)/src/nat/libgnunetnatnew.la \
259 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 260 $(top_builddir)/src/statistics/libgnunetstatistics.la \
260 $(top_builddir)/src/util/libgnunetutil.la \ 261 $(top_builddir)/src/util/libgnunetutil.la \
261 $(LIBGCRYPT_LIBS) 262 $(LIBGCRYPT_LIBS)
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
index a94559bd2..050a5f225 100644
--- a/src/transport/gnunet-communicator-tcp.c
+++ b/src/transport/gnunet-communicator-tcp.c
@@ -24,14 +24,8 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * TODO: 26 * TODO:
27 * - lots of basic adaptations (see FIXMEs), need NAT service 27 * - NAT service API change to handle address stops!
28 * to determine our own listen IPs! Parsing of bindto spec! 28 * - handling of rekeys!
29 * - actual decryption and handling of boxes and rekeys!
30 * - message queue management: flow control towards CORE!
31 * (stop reading from socket until MQ send to core is done;
32 * will need a counter as ONE read from socket may generate
33 * multiple messages en route to CORE; tricky bit: queue
34 * may die before we get MQ sent-done callbacks!)
35 */ 29 */
36#include "platform.h" 30#include "platform.h"
37#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
@@ -39,6 +33,7 @@
39#include "gnunet_signatures.h" 33#include "gnunet_signatures.h"
40#include "gnunet_constants.h" 34#include "gnunet_constants.h"
41#include "gnunet_nt_lib.h" 35#include "gnunet_nt_lib.h"
36#include "gnunet_nat_service.h"
42#include "gnunet_statistics_service.h" 37#include "gnunet_statistics_service.h"
43#include "gnunet_transport_communication_service.h" 38#include "gnunet_transport_communication_service.h"
44 39
@@ -391,10 +386,19 @@ struct Queue
391 struct GNUNET_TIME_Absolute timeout; 386 struct GNUNET_TIME_Absolute timeout;
392 387
393 /** 388 /**
389 * How may messages did we pass from this queue to CORE for which we
390 * have yet to receive an acknoweldgement that CORE is done with
391 * them? If "large" (or even just non-zero), we should throttle
392 * reading to provide flow control. See also #DEFAULT_MAX_QUEUE_LENGTH
393 * and #max_queue_length.
394 */
395 unsigned int backpressure;
396
397 /**
394 * Which network type does this queue use? 398 * Which network type does this queue use?
395 */ 399 */
396 enum GNUNET_NetworkType nt; 400 enum GNUNET_NetworkType nt;
397 401
398 /** 402 /**
399 * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call? 403 * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call?
400 */ 404 */
@@ -406,6 +410,14 @@ struct Queue
406 int finishing; 410 int finishing;
407 411
408 /** 412 /**
413 * Did we technically destroy this queue, but kept the allocation
414 * around because of @e backpressure not being zero yet? Used
415 * simply to delay the final #GNUNET_free() operation until
416 * #core_read_finished_cb() has been called.
417 */
418 int destroyed;
419
420 /**
409 * #GNUNET_YES after #inject_key() placed the rekey message into the 421 * #GNUNET_YES after #inject_key() placed the rekey message into the
410 * plaintext buffer. Once the plaintext buffer is drained, this 422 * plaintext buffer. Once the plaintext buffer is drained, this
411 * means we must switch to the new key material. 423 * means we must switch to the new key material.
@@ -475,11 +487,6 @@ struct ProtoQueue
475static struct GNUNET_SCHEDULER_Task *listen_task; 487static struct GNUNET_SCHEDULER_Task *listen_task;
476 488
477/** 489/**
478 * Number of messages we currently have in our queues towards the transport service.
479 */
480static unsigned long long delivering_messages;
481
482/**
483 * Maximum queue length before we stop reading towards the transport service. 490 * Maximum queue length before we stop reading towards the transport service.
484 */ 491 */
485static unsigned long long max_queue_length; 492static unsigned long long max_queue_length;
@@ -505,11 +512,6 @@ static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
505static struct GNUNET_NETWORK_Handle *listen_sock; 512static struct GNUNET_NETWORK_Handle *listen_sock;
506 513
507/** 514/**
508 * Handle to the operation that publishes our address.
509 */
510static struct GNUNET_TRANSPORT_AddressIdentifier *ai;
511
512/**
513 * Our public key. 515 * Our public key.
514 */ 516 */
515static struct GNUNET_PeerIdentity my_identity; 517static struct GNUNET_PeerIdentity my_identity;
@@ -525,6 +527,11 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
525static const struct GNUNET_CONFIGURATION_Handle *cfg; 527static const struct GNUNET_CONFIGURATION_Handle *cfg;
526 528
527/** 529/**
530 * Connection to NAT service.
531 */
532static struct GNUNET_NAT_Handle *nat;
533
534/**
528 * Protoqueues DLL head. 535 * Protoqueues DLL head.
529 */ 536 */
530static struct ProtoQueue *proto_head; 537static struct ProtoQueue *proto_head;
@@ -588,7 +595,10 @@ queue_destroy (struct Queue *queue)
588 gcry_cipher_close (queue->in_cipher); 595 gcry_cipher_close (queue->in_cipher);
589 gcry_cipher_close (queue->out_cipher); 596 gcry_cipher_close (queue->out_cipher);
590 GNUNET_free (queue->address); 597 GNUNET_free (queue->address);
591 GNUNET_free (queue); 598 if (0 != queue->backpressure)
599 queue->destroyed = GNUNET_YES;
600 else
601 GNUNET_free (queue);
592 if (NULL == listen_task) 602 if (NULL == listen_task)
593 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 603 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
594 listen_sock, 604 listen_sock,
@@ -685,6 +695,213 @@ reschedule_queue_timeout (struct Queue *queue)
685 * @param cls the `struct Queue *` to disconnect 695 * @param cls the `struct Queue *` to disconnect
686 */ 696 */
687static void 697static void
698queue_read (void *cls);
699
700
701/**
702 * Core tells us it is done processing a message that transport
703 * received on a queue with status @a success.
704 *
705 * @param cls a `struct Queue *` where the message originally came from
706 * @param success #GNUNET_OK on success
707 */
708static void
709core_read_finished_cb (void *cls,
710 int success)
711{
712 struct Queue *queue = cls;
713
714 if (GNUNET_OK != success)
715 GNUNET_STATISTICS_update (stats,
716 "# messages lost in communicator API towards CORE",
717 1,
718 GNUNET_NO);
719 queue->backpressure--;
720 /* handle deferred queue destruction */
721 if ( (queue->destroyed) &&
722 (0 == queue->backpressure) )
723 {
724 GNUNET_free (queue);
725 return;
726 }
727 reschedule_queue_timeout (queue);
728 /* possibly unchoke reading, now that CORE made progress */
729 if (NULL == queue->read_task)
730 queue->read_task
731 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (queue->timeout),
732 queue->sock,
733 &queue_read,
734 queue);
735}
736
737
738/**
739 * We received @a plaintext_len bytes of @a plaintext on @a queue.
740 * Pass it on to CORE. If transmission is actually happening,
741 * increase backpressure counter.
742 *
743 * @param queue the queue that received the plaintext
744 * @param plaintext the plaintext that was received
745 * @param plaintext_len number of bytes of plaintext received
746 */
747static void
748pass_plaintext_to_core (struct Queue *queue,
749 const void *plaintext,
750 size_t plaintext_len)
751{
752 const struct GNUNET_MessageHeader *hdr = plaintext;
753 int ret;
754
755 if (ntohs (hdr->size) != plaintext_len)
756 {
757 /* NOTE: If we ever allow multiple CORE messages in one
758 BOX, this will have to change! */
759 GNUNET_break (0);
760 return;
761 }
762 ret = GNUNET_TRANSPORT_communicator_receive (ch,
763 &queue->target,
764 hdr,
765 &core_read_finished_cb,
766 queue);
767 if (GNUNET_OK == ret)
768 queue->backpressure++;
769 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
770 if (GNUNET_SYSERR == ret)
771 GNUNET_STATISTICS_update (stats,
772 "# bytes lost due to CORE not running",
773 plaintext_len,
774 GNUNET_NO);
775}
776
777
778/**
779 * Test if we have received a full message in plaintext.
780 * If so, handle it.
781 *
782 * @param queue queue to process inbound plaintext for
783 */
784static void
785try_handle_plaintext (struct Queue *queue)
786{
787 const struct GNUNET_MessageHeader *hdr
788 = (const struct GNUNET_MessageHeader *) queue->pread_buf;
789 const struct TCPBox *box
790 = (const struct TCPBox *) queue->pread_buf;
791 const struct TCPRekey *rekey
792 = (const struct TCPRekey *) queue->pread_buf;
793 const struct TCPFinish *fin
794 = (const struct TCPFinish *) queue->pread_buf;
795 struct TCPRekey rekeyz;
796 struct TCPFinish finz;
797 struct GNUNET_ShortHashCode tmac;
798 uint16_t type;
799 size_t size = 0; /* make compiler happy */
800
801 if (sizeof (*hdr) > queue->pread_off)
802 return; /* not even a header */
803 type = ntohs (hdr->type);
804 switch (type)
805 {
806 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
807 /* Special case: header size excludes box itself! */
808 if (ntohs (hdr->size) + sizeof (struct TCPBox) > queue->pread_off)
809 return;
810 hmac (&queue->in_hmac,
811 &box[1],
812 ntohs (hdr->size),
813 &tmac);
814 if (0 != memcmp (&tmac,
815 &box->hmac,
816 sizeof (tmac)))
817 {
818 GNUNET_break_op (0);
819 queue_finish (queue);
820 return;
821 }
822 pass_plaintext_to_core (queue,
823 (const void *) &box[1],
824 ntohs (hdr->size));
825 size = ntohs (hdr->size) + sizeof (*box);
826 break;
827 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
828 if (sizeof (*rekey) > queue->pread_off)
829 return;
830 if (ntohs (hdr->size) != sizeof (*rekey))
831 {
832 GNUNET_break_op (0);
833 queue_finish (queue);
834 return;
835 }
836 rekeyz = *rekey;
837 memset (&rekeyz.hmac,
838 0,
839 sizeof (rekeyz.hmac));
840 hmac (&queue->in_hmac,
841 &rekeyz,
842 sizeof (rekeyz),
843 &tmac);
844 if (0 != memcmp (&tmac,
845 &box->hmac,
846 sizeof (tmac)))
847 {
848 GNUNET_break_op (0);
849 queue_finish (queue);
850 return;
851 }
852 // FIXME: handle rekey!
853
854 size = ntohs (hdr->size);
855 break;
856 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
857 if (sizeof (*fin) > queue->pread_off)
858 return;
859 if (ntohs (hdr->size) != sizeof (*fin))
860 {
861 GNUNET_break_op (0);
862 queue_finish (queue);
863 return;
864 }
865 finz = *fin;
866 memset (&finz.hmac,
867 0,
868 sizeof (finz.hmac));
869 hmac (&queue->in_hmac,
870 &rekeyz,
871 sizeof (rekeyz),
872 &tmac);
873 if (0 != memcmp (&tmac,
874 &fin->hmac,
875 sizeof (tmac)))
876 {
877 GNUNET_break_op (0);
878 queue_finish (queue);
879 return;
880 }
881 /* handle FINISH by destroying queue */
882 queue_destroy (queue);
883 break;
884 default:
885 GNUNET_break_op (0);
886 queue_finish (queue);
887 return;
888 }
889 GNUNET_assert (0 != size);
890 /* 'size' bytes of plaintext were used, shift buffer */
891 GNUNET_assert (size <= queue->pread_off);
892 memmove (queue->pread_buf,
893 &queue->pread_buf[size],
894 queue->pread_off - size);
895 queue->pread_off -= size;
896}
897
898
899/**
900 * Queue read task. If we hit the timeout, disconnect it
901 *
902 * @param cls the `struct Queue *` to disconnect
903 */
904static void
688queue_read (void *cls) 905queue_read (void *cls)
689{ 906{
690 struct Queue *queue = cls; 907 struct Queue *queue = cls;
@@ -718,10 +935,20 @@ queue_read (void *cls)
718 queue->cread_off += rcvd; 935 queue->cread_off += rcvd;
719 if (queue->pread_off < sizeof (queue->pread_buf)) 936 if (queue->pread_off < sizeof (queue->pread_buf))
720 { 937 {
721 /* FIXME: decrypt */ 938 size_t max = GNUNET_MIN (sizeof (queue->pread_buf) - queue->pread_off,
722 939 queue->cread_off);
723 /* FIXME: check plaintext for complete messages, if complete, hand to CORE */ 940 GNUNET_assert (0 ==
724 /* FIXME: CORE flow control: suspend doing more until CORE has ACKed */ 941 gcry_cipher_decrypt (queue->in_cipher,
942 &queue->pread_buf[queue->pread_off],
943 max,
944 queue->cread_buf,
945 max));
946 queue->pread_off += max;
947 memmove (queue->cread_buf,
948 &queue->cread_buf[max],
949 queue->cread_off - max);
950 queue->cread_off -= max;
951 try_handle_plaintext (queue);
725 } 952 }
726 953
727 if (BUF_SIZE == queue->cread_off) 954 if (BUF_SIZE == queue->cread_off)
@@ -729,14 +956,15 @@ queue_read (void *cls)
729 left = GNUNET_TIME_absolute_get_remaining (queue->timeout); 956 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
730 if (0 != left.rel_value_us) 957 if (0 != left.rel_value_us)
731 { 958 {
732 /* not actually our turn yet, but let's at least update 959 if (max_queue_length < queue->backpressure)
733 the monitor, it may think we're about to die ... */ 960 {
734 queue->read_task 961 /* continue reading */
735 = GNUNET_SCHEDULER_add_read_net (left, 962 queue->read_task
736 queue->sock, 963 = GNUNET_SCHEDULER_add_read_net (left,
737 &queue_read, 964 queue->sock,
738 queue); 965 &queue_read,
739 966 queue);
967 }
740 return; 968 return;
741 } 969 }
742 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -760,9 +988,119 @@ tcp_address_to_sockaddr (const char *bindto,
760 socklen_t *sock_len) 988 socklen_t *sock_len)
761{ 989{
762 struct sockaddr *in; 990 struct sockaddr *in;
763 size_t slen; 991 unsigned int port;
992 char dummy[2];
993 char *colon;
994 char *cp;
995
996 if (1 == SSCANF (bindto,
997 "%u%1s",
998 &port,
999 dummy))
1000 {
1001 /* interpreting value as just a PORT number */
1002 if (port > UINT16_MAX)
1003 {
1004 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1005 "BINDTO specification `%s' invalid: value too large for port\n",
1006 bindto);
1007 return NULL;
1008 }
1009 if (GNUNET_YES ==
1010 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1011 COMMUNICATOR_CONFIG_SECTION,
1012 "DISABLE_V6"))
1013 {
1014 struct sockaddr_in *i4;
1015
1016 i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1017 i4->sin_family = AF_INET;
1018 i4->sin_port = htons ((uint16_t) port);
1019 *sock_len = sizeof (struct sockaddr_in);
1020 in = (struct sockaddr *) i4;
1021 }
1022 else
1023 {
1024 struct sockaddr_in6 *i6;
1025
1026 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1027 i6->sin6_family = AF_INET6;
1028 i6->sin6_port = htons ((uint16_t) port);
1029 *sock_len = sizeof (struct sockaddr_in6);
1030 in = (struct sockaddr *) i6;
1031 }
1032 return in;
1033 }
1034 cp = GNUNET_strdup (bindto);
1035 colon = strrchr (cp, ':');
1036 if (NULL != colon)
1037 {
1038 /* interpet value after colon as port */
1039 *colon = '\0';
1040 colon++;
1041 if (1 == SSCANF (colon,
1042 "%u%1s",
1043 &port,
1044 dummy))
1045 {
1046 /* interpreting value as just a PORT number */
1047 if (port > UINT16_MAX)
1048 {
1049 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1050 "BINDTO specification `%s' invalid: value too large for port\n",
1051 bindto);
1052 GNUNET_free (cp);
1053 return NULL;
1054 }
1055 }
1056 else
1057 {
1058 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1059 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1060 bindto);
1061 GNUNET_free (cp);
1062 return NULL;
1063 }
1064 }
1065 else
1066 {
1067 /* interpret missing port as 0, aka pick any free one */
1068 port = 0;
1069 }
1070 {
1071 /* try IPv4 */
1072 struct sockaddr_in v4;
764 1073
765 /* FIXME: parse, allocate, return! */ 1074 if (1 == inet_pton (AF_INET,
1075 cp,
1076 &v4))
1077 {
1078 v4.sin_port = htons ((uint16_t) port);
1079 in = GNUNET_memdup (&v4,
1080 sizeof (v4));
1081 *sock_len = sizeof (v4);
1082 GNUNET_free (cp);
1083 return in;
1084 }
1085 }
1086 {
1087 /* try IPv6 */
1088 struct sockaddr_in6 v6;
1089
1090 if (1 == inet_pton (AF_INET6,
1091 cp,
1092 &v6))
1093 {
1094 v6.sin6_port = htons ((uint16_t) port);
1095 in = GNUNET_memdup (&v6,
1096 sizeof (v6));
1097 *sock_len = sizeof (v6);
1098 GNUNET_free (cp);
1099 return in;
1100 }
1101 }
1102 /* FIXME (feature!): maybe also try getnameinfo()? */
1103 GNUNET_free (cp);
766 return NULL; 1104 return NULL;
767} 1105}
768 1106
@@ -966,8 +1304,8 @@ queue_write (void *cls)
966 size_t usent = (size_t) sent; 1304 size_t usent = (size_t) sent;
967 1305
968 memmove (queue->cwrite_buf, 1306 memmove (queue->cwrite_buf,
969 &queue->cwrite_buf[sent], 1307 &queue->cwrite_buf[usent],
970 queue->cwrite_off - sent); 1308 queue->cwrite_off - usent);
971 reschedule_queue_timeout (queue); 1309 reschedule_queue_timeout (queue);
972 } 1310 }
973 /* can we encrypt more? (always encrypt full messages, needed 1311 /* can we encrypt more? (always encrypt full messages, needed
@@ -1670,6 +2008,11 @@ get_queue_delete_it (void *cls,
1670static void 2008static void
1671do_shutdown (void *cls) 2009do_shutdown (void *cls)
1672{ 2010{
2011 if (NULL != nat)
2012 {
2013 GNUNET_NAT_unregister (nat);
2014 nat = NULL;
2015 }
1673 if (NULL != listen_task) 2016 if (NULL != listen_task)
1674 { 2017 {
1675 GNUNET_SCHEDULER_cancel (listen_task); 2018 GNUNET_SCHEDULER_cancel (listen_task);
@@ -1685,11 +2028,6 @@ do_shutdown (void *cls)
1685 &get_queue_delete_it, 2028 &get_queue_delete_it,
1686 NULL); 2029 NULL);
1687 GNUNET_CONTAINER_multipeermap_destroy (queue_map); 2030 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
1688 if (NULL != ai)
1689 {
1690 GNUNET_TRANSPORT_communicator_address_remove (ai);
1691 ai = NULL;
1692 }
1693 if (NULL != ch) 2031 if (NULL != ch)
1694 { 2032 {
1695 GNUNET_TRANSPORT_communicator_disconnect (ch); 2033 GNUNET_TRANSPORT_communicator_disconnect (ch);
@@ -1733,6 +2071,51 @@ enc_notify_cb (void *cls,
1733 2071
1734 2072
1735/** 2073/**
2074 * Signature of the callback passed to #GNUNET_NAT_register() for
2075 * a function to call whenever our set of 'valid' addresses changes.
2076 *
2077 * @param cls closure
2078 * @param add_remove #GNUNET_YES to add a new public IP address,
2079 * #GNUNET_NO to remove a previous (now invalid) one
2080 * @param ac address class the address belongs to
2081 * @param addr either the previous or the new public IP address
2082 * @param addrlen actual length of the @a addr
2083 */
2084static void
2085nat_address_cb (void *cls,
2086 int add_remove,
2087 enum GNUNET_NAT_AddressClass ac,
2088 const struct sockaddr *addr,
2089 socklen_t addrlen)
2090{
2091 char *my_addr;
2092 static struct GNUNET_TRANSPORT_AddressIdentifier *ai; // FIXME: store in *ctx of NAT!
2093
2094 if (GNUNET_YES == add_remove)
2095 {
2096 // FIXME: do better job at stringification of @a addr?
2097 GNUNET_asprintf (&my_addr,
2098 "%s-%s",
2099 COMMUNICATOR_ADDRESS_PREFIX,
2100 GNUNET_a2s (addr,
2101 addrlen));
2102 // FIXME: translate 'ac' to 'nt'?
2103 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2104 my_addr,
2105 GNUNET_NT_LOOPBACK, // FIXME: wrong NT!
2106 GNUNET_TIME_UNIT_FOREVER_REL);
2107 GNUNET_free (my_addr);
2108 }
2109 else
2110 {
2111 // FIXME: support removal! => improve NAT API!
2112 GNUNET_TRANSPORT_communicator_address_remove (ai);
2113 ai = NULL;
2114 }
2115}
2116
2117
2118/**
1736 * Setup communicator and launch network interactions. 2119 * Setup communicator and launch network interactions.
1737 * 2120 *
1738 * @param cls NULL (always) 2121 * @param cls NULL (always)
@@ -1749,9 +2132,8 @@ run (void *cls,
1749 char *bindto; 2132 char *bindto;
1750 struct sockaddr *in; 2133 struct sockaddr *in;
1751 socklen_t in_len; 2134 socklen_t in_len;
1752 char *my_addr;
1753 (void) cls;
1754 2135
2136 (void) cls;
1755 cfg = c; 2137 cfg = c;
1756 if (GNUNET_OK != 2138 if (GNUNET_OK !=
1757 GNUNET_CONFIGURATION_get_value_filename (cfg, 2139 GNUNET_CONFIGURATION_get_value_filename (cfg,
@@ -1810,6 +2192,7 @@ run (void *cls,
1810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1811 "Bound to `%s'\n", 2193 "Bound to `%s'\n",
1812 bindto); 2194 bindto);
2195 GNUNET_free (bindto);
1813 stats = GNUNET_STATISTICS_create ("C-TCP", 2196 stats = GNUNET_STATISTICS_create ("C-TCP",
1814 cfg); 2197 cfg);
1815 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 2198 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
@@ -1824,13 +2207,13 @@ run (void *cls,
1824 } 2207 }
1825 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, 2208 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1826 &my_identity.public_key); 2209 &my_identity.public_key);
1827 2210 /* start listening */
1828 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2211 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1829 listen_sock, 2212 listen_sock,
1830 &listen_cb, 2213 &listen_cb,
1831 NULL); 2214 NULL);
1832 queue_map = GNUNET_CONTAINER_multipeermap_create (10, 2215 queue_map = GNUNET_CONTAINER_multipeermap_create (10,
1833 GNUNET_NO); 2216 GNUNET_NO);
1834 ch = GNUNET_TRANSPORT_communicator_connect (cfg, 2217 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
1835 COMMUNICATOR_CONFIG_SECTION, 2218 COMMUNICATOR_CONFIG_SECTION,
1836 COMMUNICATOR_ADDRESS_PREFIX, 2219 COMMUNICATOR_ADDRESS_PREFIX,
@@ -1843,24 +2226,17 @@ run (void *cls,
1843 { 2226 {
1844 GNUNET_break (0); 2227 GNUNET_break (0);
1845 GNUNET_SCHEDULER_shutdown (); 2228 GNUNET_SCHEDULER_shutdown ();
1846 GNUNET_free (bindto);
1847 return; 2229 return;
1848 } 2230 }
1849 // FIXME: bindto is wrong here, we MUST get our external 2231 nat = GNUNET_NAT_register (cfg,
1850 // IP address and really look at 'in' here as we might 2232 COMMUNICATOR_CONFIG_SECTION,
1851 // be bound to loopback or some other specific IP address! 2233 IPPROTO_TCP,
1852 GNUNET_asprintf (&my_addr, 2234 1 /* one address */,
1853 "%s-%s", 2235 (const struct sockaddr **) &in,
1854 COMMUNICATOR_ADDRESS_PREFIX, 2236 &in_len,
1855 bindto); 2237 &nat_address_cb,
1856 GNUNET_free (bindto); 2238 NULL /* FIXME: support reversal! */,
1857 // FIXME: based on our bindto, we might not be able to tell the 2239 NULL /* closure */);
1858 // network type yet! What to do here!?
1859 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
1860 my_addr,
1861 GNUNET_NT_LOOPBACK, // FIXME: wrong NT!
1862 GNUNET_TIME_UNIT_FOREVER_REL);
1863 GNUNET_free (my_addr);
1864} 2240}
1865 2241
1866 2242