diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-06-26 22:26:57 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-06-26 22:26:57 +0000 |
commit | 1791f39fa6dc0bc37d14af98a0684fe1a23fc697 (patch) | |
tree | 66b33b772226f77289f669e6d9e4afa03b42a22b | |
parent | 8a3016481ba6aeb36de3950a56e641dda53ca544 (diff) | |
download | gnunet-1791f39fa6dc0bc37d14af98a0684fe1a23fc697.tar.gz gnunet-1791f39fa6dc0bc37d14af98a0684fe1a23fc697.zip |
partial fix of the NAT troubles
-rw-r--r-- | src/nat/nat.c | 43 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport.c | 653 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 5 | ||||
-rw-r--r-- | src/transport/test_transport_api.c | 102 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_peer1.conf | 2 | ||||
-rw-r--r-- | src/transport/transport.h | 2 | ||||
-rw-r--r-- | src/util/connection.c | 3 |
7 files changed, 504 insertions, 306 deletions
diff --git a/src/nat/nat.c b/src/nat/nat.c index e92f57259..99d2bbc7c 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c | |||
@@ -178,6 +178,11 @@ struct GNUNET_NAT_Handle | |||
178 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | 178 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; |
179 | 179 | ||
180 | /** | 180 | /** |
181 | * ID of interface IP-scan task | ||
182 | */ | ||
183 | GNUNET_SCHEDULER_TaskIdentifier ifc_task; | ||
184 | |||
185 | /** | ||
181 | * The process id of the server process (if behind NAT) | 186 | * The process id of the server process (if behind NAT) |
182 | */ | 187 | */ |
183 | struct GNUNET_OS_Process *server_proc; | 188 | struct GNUNET_OS_Process *server_proc; |
@@ -857,6 +862,27 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) | |||
857 | 862 | ||
858 | 863 | ||
859 | /** | 864 | /** |
865 | * Task to scan the local network interfaces for IP addresses. | ||
866 | * | ||
867 | * @param cls the NAT handle | ||
868 | * @param tc scheduler context | ||
869 | */ | ||
870 | static void | ||
871 | list_interfaces (void *cls, | ||
872 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
873 | { | ||
874 | struct GNUNET_NAT_Handle *h = cls; | ||
875 | |||
876 | h->ifc_task = GNUNET_SCHEDULER_NO_TASK; | ||
877 | GNUNET_OS_network_interfaces_list (&process_interfaces, h); | ||
878 | #if 0 | ||
879 | h->ifc_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FIXME, | ||
880 | &list_interfaces, h); | ||
881 | #endif | ||
882 | } | ||
883 | |||
884 | |||
885 | /** | ||
860 | * Attempt to enable port redirection and detect public IP address contacting | 886 | * Attempt to enable port redirection and detect public IP address contacting |
861 | * UPnP or NAT-PMP routers on the local network. Use addr to specify to which | 887 | * UPnP or NAT-PMP routers on the local network. Use addr to specify to which |
862 | * of the local host's addresses should the external port be mapped. The port | 888 | * of the local host's addresses should the external port be mapped. The port |
@@ -889,6 +915,10 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
889 | struct in_addr in_addr; | 915 | struct in_addr in_addr; |
890 | unsigned int i; | 916 | unsigned int i; |
891 | 917 | ||
918 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
919 | "Registered with NAT service at port %u with %u IP bound local addresses\n", | ||
920 | (unsigned int) adv_port, | ||
921 | num_addrs); | ||
892 | h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); | 922 | h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); |
893 | h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; | 923 | h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; |
894 | h->cfg = cfg; | 924 | h->cfg = cfg; |
@@ -1016,7 +1046,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1016 | 1046 | ||
1017 | if (NULL != h->address_callback) | 1047 | if (NULL != h->address_callback) |
1018 | { | 1048 | { |
1019 | GNUNET_OS_network_interfaces_list (&process_interfaces, h); | 1049 | h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); |
1020 | h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, | 1050 | h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, |
1021 | HOSTNAME_RESOLVE_TIMEOUT, | 1051 | HOSTNAME_RESOLVE_TIMEOUT, |
1022 | &process_hostname_ip, | 1052 | &process_hostname_ip, |
@@ -1053,6 +1083,11 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) | |||
1053 | GNUNET_SCHEDULER_cancel (h->server_read_task); | 1083 | GNUNET_SCHEDULER_cancel (h->server_read_task); |
1054 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 1084 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
1055 | } | 1085 | } |
1086 | if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task) | ||
1087 | { | ||
1088 | GNUNET_SCHEDULER_cancel (h->ifc_task); | ||
1089 | h->ifc_task = GNUNET_SCHEDULER_NO_TASK; | ||
1090 | } | ||
1056 | if (NULL != h->server_proc) | 1091 | if (NULL != h->server_proc) |
1057 | { | 1092 | { |
1058 | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) | 1093 | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) |
@@ -1172,7 +1207,7 @@ GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, | |||
1172 | struct LocalAddressList *pos; | 1207 | struct LocalAddressList *pos; |
1173 | const struct sockaddr_in *in4; | 1208 | const struct sockaddr_in *in4; |
1174 | const struct sockaddr_in6 *in6; | 1209 | const struct sockaddr_in6 *in6; |
1175 | 1210 | ||
1176 | if ( (addrlen != sizeof (struct in_addr)) && | 1211 | if ( (addrlen != sizeof (struct in_addr)) && |
1177 | (addrlen != sizeof (struct in6_addr)) ) | 1212 | (addrlen != sizeof (struct in6_addr)) ) |
1178 | { | 1213 | { |
@@ -1202,7 +1237,9 @@ GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, | |||
1202 | } | 1237 | } |
1203 | pos = pos->next; | 1238 | pos = pos->next; |
1204 | } | 1239 | } |
1205 | return GNUNET_YES; | 1240 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1241 | "Asked to validate one of my addresses and validation failed!\n"); | ||
1242 | return GNUNET_NO; | ||
1206 | } | 1243 | } |
1207 | 1244 | ||
1208 | 1245 | ||
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 2010c8d51..51e84e1dd 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -44,9 +44,9 @@ | |||
44 | 44 | ||
45 | #define DEBUG_BLACKLIST GNUNET_NO | 45 | #define DEBUG_BLACKLIST GNUNET_NO |
46 | 46 | ||
47 | #define DEBUG_PING_PONG GNUNET_YES | 47 | #define DEBUG_PING_PONG GNUNET_NO |
48 | 48 | ||
49 | #define DEBUG_TRANSPORT_HELLO GNUNET_YES | 49 | #define DEBUG_TRANSPORT_HELLO GNUNET_NO |
50 | 50 | ||
51 | #define DEBUG_ATS GNUNET_NO | 51 | #define DEBUG_ATS GNUNET_NO |
52 | 52 | ||
@@ -750,7 +750,7 @@ struct CheckHelloValidatedContext; | |||
750 | /** | 750 | /** |
751 | * Entry in map of all HELLOs awaiting validation. | 751 | * Entry in map of all HELLOs awaiting validation. |
752 | */ | 752 | */ |
753 | struct ValidationEntry | 753 | struct ValidationEntry |
754 | { | 754 | { |
755 | 755 | ||
756 | /** | 756 | /** |
@@ -1675,56 +1675,73 @@ a2s (const char *plugin, | |||
1675 | } | 1675 | } |
1676 | 1676 | ||
1677 | 1677 | ||
1678 | |||
1679 | |||
1678 | /** | 1680 | /** |
1679 | * Mark the given FAL entry as 'connected' (and hence preferred for | 1681 | * Iterator to free entries in the validation_map. |
1680 | * sending); also mark all others for the same peer as 'not connected' | ||
1681 | * (since only one can be preferred). | ||
1682 | * | 1682 | * |
1683 | * @param fal address to set to 'connected' | 1683 | * @param cls closure (unused) |
1684 | * @param key current key code | ||
1685 | * @param value value in the hash map (validation to abort) | ||
1686 | * @return GNUNET_YES (always) | ||
1684 | */ | 1687 | */ |
1685 | static void | 1688 | static int |
1686 | mark_address_connected (struct ForeignAddressList *fal) | 1689 | abort_validation (void *cls, |
1690 | const GNUNET_HashCode * key, | ||
1691 | void *value) | ||
1687 | { | 1692 | { |
1688 | struct ForeignAddressList *pos; | 1693 | struct ValidationEntry *va = value; |
1689 | int cnt; | ||
1690 | 1694 | ||
1691 | GNUNET_assert (GNUNET_YES == fal->validated); | 1695 | if (GNUNET_SCHEDULER_NO_TASK != va->timeout_task) |
1692 | if (fal->connected == GNUNET_YES) | 1696 | GNUNET_SCHEDULER_cancel (va->timeout_task); |
1693 | return; /* nothing to do */ | 1697 | GNUNET_free (va->transport_name); |
1694 | cnt = GNUNET_YES; | 1698 | if (va->chvc != NULL) |
1695 | pos = fal->ready_list->addresses; | ||
1696 | while (pos != NULL) | ||
1697 | { | 1699 | { |
1698 | if (GNUNET_YES == pos->connected) | 1700 | va->chvc->ve_count--; |
1701 | if (va->chvc->ve_count == 0) | ||
1699 | { | 1702 | { |
1700 | #if DEBUG_TRANSPORT | 1703 | GNUNET_CONTAINER_DLL_remove (chvc_head, |
1701 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1704 | chvc_tail, |
1702 | "Marking address `%s' as no longer connected (due to connect on other address)\n", | 1705 | va->chvc); |
1703 | a2s (pos->ready_list->plugin->short_name, | 1706 | GNUNET_free (va->chvc); |
1704 | pos->addr, | ||
1705 | pos->addrlen)); | ||
1706 | #endif | ||
1707 | GNUNET_break (cnt == GNUNET_YES); | ||
1708 | cnt = GNUNET_NO; | ||
1709 | pos->connected = GNUNET_NO; | ||
1710 | GNUNET_STATISTICS_update (stats, | ||
1711 | gettext_noop ("# connected addresses"), | ||
1712 | -1, | ||
1713 | GNUNET_NO); | ||
1714 | } | 1707 | } |
1715 | pos = pos->next; | 1708 | va->chvc = NULL; |
1716 | } | ||
1717 | fal->connected = GNUNET_YES; | ||
1718 | if (GNUNET_YES == cnt) | ||
1719 | { | ||
1720 | GNUNET_STATISTICS_update (stats, | ||
1721 | gettext_noop ("# connected addresses"), | ||
1722 | 1, | ||
1723 | GNUNET_NO); | ||
1724 | } | 1709 | } |
1710 | GNUNET_free (va); | ||
1711 | return GNUNET_YES; | ||
1712 | } | ||
1713 | |||
1714 | |||
1715 | /** | ||
1716 | * HELLO validation cleanup task (validation failed). | ||
1717 | * | ||
1718 | * @param cls the 'struct ValidationEntry' that failed | ||
1719 | * @param tc scheduler context (unused) | ||
1720 | */ | ||
1721 | static void | ||
1722 | timeout_hello_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1723 | { | ||
1724 | struct ValidationEntry *va = cls; | ||
1725 | struct GNUNET_PeerIdentity pid; | ||
1726 | |||
1727 | va->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
1728 | GNUNET_STATISTICS_update (stats, | ||
1729 | gettext_noop ("# address validation timeouts"), | ||
1730 | 1, | ||
1731 | GNUNET_NO); | ||
1732 | GNUNET_CRYPTO_hash (&va->publicKey, | ||
1733 | sizeof (struct | ||
1734 | GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
1735 | &pid.hashPubKey); | ||
1736 | GNUNET_break (GNUNET_OK == | ||
1737 | GNUNET_CONTAINER_multihashmap_remove (validation_map, | ||
1738 | &pid.hashPubKey, | ||
1739 | va)); | ||
1740 | abort_validation (NULL, NULL, va); | ||
1725 | } | 1741 | } |
1726 | 1742 | ||
1727 | 1743 | ||
1744 | |||
1728 | /** | 1745 | /** |
1729 | * Send the specified message to the specified client. Since multiple | 1746 | * Send the specified message to the specified client. Since multiple |
1730 | * messages may be pending for the same client at a time, this code | 1747 | * messages may be pending for the same client at a time, this code |
@@ -1808,6 +1825,17 @@ transmit_send_ok (struct TransportClient *client, | |||
1808 | 1825 | ||
1809 | 1826 | ||
1810 | /** | 1827 | /** |
1828 | * Mark the given FAL entry as 'connected' (and hence preferred for | ||
1829 | * sending); also mark all others for the same peer as 'not connected' | ||
1830 | * (since only one can be preferred). | ||
1831 | * | ||
1832 | * @param fal address to set to 'connected' | ||
1833 | */ | ||
1834 | static void | ||
1835 | mark_address_connected (struct ForeignAddressList *fal); | ||
1836 | |||
1837 | |||
1838 | /** | ||
1811 | * Function called by the GNUNET_TRANSPORT_TransmitFunction | 1839 | * Function called by the GNUNET_TRANSPORT_TransmitFunction |
1812 | * upon "completion" of a send request. This tells the API | 1840 | * upon "completion" of a send request. This tells the API |
1813 | * that it is now legal to send another message to the given | 1841 | * that it is now legal to send another message to the given |
@@ -1888,122 +1916,6 @@ transmit_send_continuation (void *cls, | |||
1888 | 1916 | ||
1889 | 1917 | ||
1890 | /** | 1918 | /** |
1891 | * Find an address in any of the available transports for | ||
1892 | * the given neighbour that would be good for message | ||
1893 | * transmission. This is essentially the transport selection | ||
1894 | * routine. | ||
1895 | * | ||
1896 | * @param neighbour for whom to select an address | ||
1897 | * @return selected address, NULL if we have none | ||
1898 | */ | ||
1899 | struct ForeignAddressList * | ||
1900 | find_ready_address(struct NeighbourList *neighbour) | ||
1901 | { | ||
1902 | struct ReadyList *head = neighbour->plugins; | ||
1903 | struct ForeignAddressList *addresses; | ||
1904 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | ||
1905 | struct ForeignAddressList *best_address; | ||
1906 | |||
1907 | /* Hack to prefer unix domain sockets */ | ||
1908 | struct ForeignAddressList *unix_address = NULL; | ||
1909 | |||
1910 | best_address = NULL; | ||
1911 | while (head != NULL) | ||
1912 | { | ||
1913 | addresses = head->addresses; | ||
1914 | while (addresses != NULL) | ||
1915 | { | ||
1916 | if ( (addresses->timeout.abs_value < now.abs_value) && | ||
1917 | (addresses->connected == GNUNET_YES) ) | ||
1918 | { | ||
1919 | #if DEBUG_TRANSPORT | ||
1920 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1921 | "Marking long-time inactive connection to `%4s' as down.\n", | ||
1922 | GNUNET_i2s (&neighbour->id)); | ||
1923 | #endif | ||
1924 | GNUNET_STATISTICS_update (stats, | ||
1925 | gettext_noop ("# connected addresses"), | ||
1926 | -1, | ||
1927 | GNUNET_NO); | ||
1928 | addresses->connected = GNUNET_NO; | ||
1929 | } | ||
1930 | addresses = addresses->next; | ||
1931 | } | ||
1932 | |||
1933 | addresses = head->addresses; | ||
1934 | while (addresses != NULL) | ||
1935 | { | ||
1936 | #if DEBUG_TRANSPORT > 1 | ||
1937 | if (addresses->addr != NULL) | ||
1938 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1939 | "Have address `%s' for peer `%4s' (status: %d, %d, %d, %u, %llums, %u)\n", | ||
1940 | a2s (head->plugin->short_name, | ||
1941 | addresses->addr, | ||
1942 | addresses->addrlen), | ||
1943 | GNUNET_i2s (&neighbour->id), | ||
1944 | addresses->connected, | ||
1945 | addresses->in_transmit, | ||
1946 | addresses->validated, | ||
1947 | addresses->connect_attempts, | ||
1948 | (unsigned long long) addresses->timeout.abs_value, | ||
1949 | (unsigned int) addresses->distance); | ||
1950 | #endif | ||
1951 | if (0==strcmp(head->plugin->short_name,"unix")) | ||
1952 | { | ||
1953 | if ((unix_address == NULL) || ((unix_address != NULL) && | ||
1954 | (addresses->latency.rel_value < unix_address->latency.rel_value))) | ||
1955 | unix_address = addresses; | ||
1956 | } | ||
1957 | if ( ( (best_address == NULL) || | ||
1958 | (addresses->connected == GNUNET_YES) || | ||
1959 | (best_address->connected == GNUNET_NO) ) && | ||
1960 | (addresses->in_transmit == GNUNET_NO) && | ||
1961 | ( (best_address == NULL) || | ||
1962 | (addresses->latency.rel_value < best_address->latency.rel_value)) ) | ||
1963 | best_address = addresses; | ||
1964 | /* FIXME: also give lower-latency addresses that are not | ||
1965 | connected a chance some times... */ | ||
1966 | addresses = addresses->next; | ||
1967 | } | ||
1968 | if (unix_address != NULL) | ||
1969 | break; | ||
1970 | head = head->next; | ||
1971 | } | ||
1972 | if (unix_address != NULL) | ||
1973 | { | ||
1974 | best_address = unix_address; | ||
1975 | #if DEBUG_TRANSPORT | ||
1976 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1977 | "Found UNIX address, forced this address\n"); | ||
1978 | #endif | ||
1979 | } | ||
1980 | if (best_address != NULL) | ||
1981 | { | ||
1982 | #if DEBUG_TRANSPORT | ||
1983 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1984 | "Best address found (`%s') has latency of %llu ms.\n", | ||
1985 | (best_address->addrlen > 0) | ||
1986 | ? a2s (best_address->ready_list->plugin->short_name, | ||
1987 | best_address->addr, | ||
1988 | best_address->addrlen) | ||
1989 | : "<inbound>", | ||
1990 | best_address->latency.rel_value); | ||
1991 | #endif | ||
1992 | } | ||
1993 | else | ||
1994 | { | ||
1995 | GNUNET_STATISTICS_update (stats, | ||
1996 | gettext_noop ("# transmission attempts failed (no address)"), | ||
1997 | 1, | ||
1998 | GNUNET_NO); | ||
1999 | } | ||
2000 | |||
2001 | return best_address; | ||
2002 | |||
2003 | } | ||
2004 | |||
2005 | |||
2006 | /** | ||
2007 | * We should re-try transmitting to the given peer, | 1919 | * We should re-try transmitting to the given peer, |
2008 | * hopefully we've learned something in the meantime. | 1920 | * hopefully we've learned something in the meantime. |
2009 | */ | 1921 | */ |
@@ -2228,6 +2140,248 @@ transmit_to_peer (struct TransportClient *client, | |||
2228 | 2140 | ||
2229 | 2141 | ||
2230 | /** | 2142 | /** |
2143 | * Send a plain PING (without address or our HELLO) to the given | ||
2144 | * foreign address to try to establish a connection (and validate | ||
2145 | * that the other peer is really who he claimed he is). | ||
2146 | * | ||
2147 | * @param n neighbour to PING | ||
2148 | */ | ||
2149 | static void | ||
2150 | transmit_plain_ping (struct NeighbourList *n) | ||
2151 | { | ||
2152 | struct ValidationEntry *ve; | ||
2153 | struct TransportPingMessage ping; | ||
2154 | struct ReadyList *rl; | ||
2155 | struct TransportPlugin *plugin; | ||
2156 | struct ForeignAddressList *fal; | ||
2157 | |||
2158 | if (! n->public_key_valid) | ||
2159 | { | ||
2160 | /* This should not happen since the other peer | ||
2161 | should send us a HELLO prior to sending his | ||
2162 | PING */ | ||
2163 | GNUNET_break_op (0); | ||
2164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2165 | "Could not transmit plain PING to `%s': public key not known\n", | ||
2166 | GNUNET_i2s (&n->id)); | ||
2167 | return; | ||
2168 | } | ||
2169 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2170 | "Looking for addresses to transmit plain PING to `%s'\n", | ||
2171 | GNUNET_i2s (&n->id)); | ||
2172 | for (rl = n->plugins; rl != NULL; rl = rl->next) | ||
2173 | { | ||
2174 | plugin = rl->plugin; | ||
2175 | for (fal = rl->addresses; fal != NULL; fal = fal->next) | ||
2176 | { | ||
2177 | if (! fal->connected) | ||
2178 | continue; | ||
2179 | ve = GNUNET_malloc (sizeof (struct ValidationEntry)); | ||
2180 | ve->transport_name = GNUNET_strdup (plugin->short_name); | ||
2181 | ve->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
2182 | UINT_MAX); | ||
2183 | ve->send_time = GNUNET_TIME_absolute_get(); | ||
2184 | ve->session = fal->session; | ||
2185 | memcpy(&ve->publicKey, | ||
2186 | &n->publicKey, | ||
2187 | sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
2188 | ve->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT, | ||
2189 | &timeout_hello_validation, | ||
2190 | ve); | ||
2191 | GNUNET_CONTAINER_multihashmap_put (validation_map, | ||
2192 | &n->id.hashPubKey, | ||
2193 | ve, | ||
2194 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
2195 | ping.header.size = htons(sizeof(struct TransportPingMessage)); | ||
2196 | ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING); | ||
2197 | ping.challenge = htonl(ve->challenge); | ||
2198 | memcpy(&ping.target, &n->id, sizeof(struct GNUNET_PeerIdentity)); | ||
2199 | GNUNET_STATISTICS_update (stats, | ||
2200 | gettext_noop ("# PING without HELLO messages sent"), | ||
2201 | 1, | ||
2202 | GNUNET_NO); | ||
2203 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2204 | "Transmitting plain PING to `%s'\n", | ||
2205 | GNUNET_i2s (&n->id)); | ||
2206 | transmit_to_peer (NULL, | ||
2207 | fal, | ||
2208 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
2209 | HELLO_VERIFICATION_TIMEOUT, | ||
2210 | (const char*) &ping, sizeof (ping), | ||
2211 | GNUNET_YES, n); | ||
2212 | } | ||
2213 | } | ||
2214 | } | ||
2215 | |||
2216 | |||
2217 | /** | ||
2218 | * Mark the given FAL entry as 'connected' (and hence preferred for | ||
2219 | * sending); also mark all others for the same peer as 'not connected' | ||
2220 | * (since only one can be preferred). | ||
2221 | * | ||
2222 | * @param fal address to set to 'connected' | ||
2223 | */ | ||
2224 | static void | ||
2225 | mark_address_connected (struct ForeignAddressList *fal) | ||
2226 | { | ||
2227 | struct ForeignAddressList *pos; | ||
2228 | int cnt; | ||
2229 | |||
2230 | GNUNET_assert (GNUNET_YES == fal->validated); | ||
2231 | if (fal->connected == GNUNET_YES) | ||
2232 | return; /* nothing to do */ | ||
2233 | cnt = GNUNET_YES; | ||
2234 | pos = fal->ready_list->addresses; | ||
2235 | while (pos != NULL) | ||
2236 | { | ||
2237 | if (GNUNET_YES == pos->connected) | ||
2238 | { | ||
2239 | #if DEBUG_TRANSPORT | ||
2240 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2241 | "Marking address `%s' as no longer connected (due to connect on other address)\n", | ||
2242 | a2s (pos->ready_list->plugin->short_name, | ||
2243 | pos->addr, | ||
2244 | pos->addrlen)); | ||
2245 | #endif | ||
2246 | GNUNET_break (cnt == GNUNET_YES); | ||
2247 | cnt = GNUNET_NO; | ||
2248 | pos->connected = GNUNET_NO; | ||
2249 | GNUNET_STATISTICS_update (stats, | ||
2250 | gettext_noop ("# connected addresses"), | ||
2251 | -1, | ||
2252 | GNUNET_NO); | ||
2253 | } | ||
2254 | pos = pos->next; | ||
2255 | } | ||
2256 | fal->connected = GNUNET_YES; | ||
2257 | if (GNUNET_YES == cnt) | ||
2258 | { | ||
2259 | GNUNET_STATISTICS_update (stats, | ||
2260 | gettext_noop ("# connected addresses"), | ||
2261 | 1, | ||
2262 | GNUNET_NO); | ||
2263 | } | ||
2264 | } | ||
2265 | |||
2266 | |||
2267 | /** | ||
2268 | * Find an address in any of the available transports for | ||
2269 | * the given neighbour that would be good for message | ||
2270 | * transmission. This is essentially the transport selection | ||
2271 | * routine. | ||
2272 | * | ||
2273 | * @param neighbour for whom to select an address | ||
2274 | * @return selected address, NULL if we have none | ||
2275 | */ | ||
2276 | struct ForeignAddressList * | ||
2277 | find_ready_address(struct NeighbourList *neighbour) | ||
2278 | { | ||
2279 | struct ReadyList *head = neighbour->plugins; | ||
2280 | struct ForeignAddressList *addresses; | ||
2281 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | ||
2282 | struct ForeignAddressList *best_address; | ||
2283 | |||
2284 | /* Hack to prefer unix domain sockets */ | ||
2285 | struct ForeignAddressList *unix_address = NULL; | ||
2286 | |||
2287 | best_address = NULL; | ||
2288 | while (head != NULL) | ||
2289 | { | ||
2290 | addresses = head->addresses; | ||
2291 | while (addresses != NULL) | ||
2292 | { | ||
2293 | if ( (addresses->timeout.abs_value < now.abs_value) && | ||
2294 | (addresses->connected == GNUNET_YES) ) | ||
2295 | { | ||
2296 | #if DEBUG_TRANSPORT | ||
2297 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2298 | "Marking long-time inactive connection to `%4s' as down.\n", | ||
2299 | GNUNET_i2s (&neighbour->id)); | ||
2300 | #endif | ||
2301 | GNUNET_STATISTICS_update (stats, | ||
2302 | gettext_noop ("# connected addresses"), | ||
2303 | -1, | ||
2304 | GNUNET_NO); | ||
2305 | addresses->connected = GNUNET_NO; | ||
2306 | } | ||
2307 | addresses = addresses->next; | ||
2308 | } | ||
2309 | |||
2310 | addresses = head->addresses; | ||
2311 | while (addresses != NULL) | ||
2312 | { | ||
2313 | #if DEBUG_TRANSPORT | ||
2314 | if (addresses->addr != NULL) | ||
2315 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2316 | "Have address `%s' for peer `%4s' (status: %d, %d, %d, %u, %llums, %u)\n", | ||
2317 | a2s (head->plugin->short_name, | ||
2318 | addresses->addr, | ||
2319 | addresses->addrlen), | ||
2320 | GNUNET_i2s (&neighbour->id), | ||
2321 | addresses->connected, | ||
2322 | addresses->in_transmit, | ||
2323 | addresses->validated, | ||
2324 | addresses->connect_attempts, | ||
2325 | (unsigned long long) addresses->timeout.abs_value, | ||
2326 | (unsigned int) addresses->distance); | ||
2327 | #endif | ||
2328 | if (0==strcmp(head->plugin->short_name,"unix")) | ||
2329 | { | ||
2330 | if ( (unix_address == NULL) || | ||
2331 | ( (unix_address != NULL) && | ||
2332 | (addresses->latency.rel_value < unix_address->latency.rel_value) ) ) | ||
2333 | unix_address = addresses; | ||
2334 | } | ||
2335 | if ( ( (best_address == NULL) || | ||
2336 | (addresses->connected == GNUNET_YES) || | ||
2337 | (best_address->connected == GNUNET_NO) ) && | ||
2338 | (addresses->in_transmit == GNUNET_NO) && | ||
2339 | ( (best_address == NULL) || | ||
2340 | (addresses->latency.rel_value < best_address->latency.rel_value)) ) | ||
2341 | best_address = addresses; | ||
2342 | /* FIXME: also give lower-latency addresses that are not | ||
2343 | connected a chance some times... */ | ||
2344 | addresses = addresses->next; | ||
2345 | } | ||
2346 | if (unix_address != NULL) | ||
2347 | break; | ||
2348 | head = head->next; | ||
2349 | } | ||
2350 | if (unix_address != NULL) | ||
2351 | { | ||
2352 | best_address = unix_address; | ||
2353 | #if DEBUG_TRANSPORT | ||
2354 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2355 | "Found UNIX address, forced this address\n"); | ||
2356 | #endif | ||
2357 | } | ||
2358 | if (best_address != NULL) | ||
2359 | { | ||
2360 | #if DEBUG_TRANSPORT | ||
2361 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2362 | "Best address found (`%s') has latency of %llu ms.\n", | ||
2363 | (best_address->addrlen > 0) | ||
2364 | ? a2s (best_address->ready_list->plugin->short_name, | ||
2365 | best_address->addr, | ||
2366 | best_address->addrlen) | ||
2367 | : "<inbound>", | ||
2368 | best_address->latency.rel_value); | ||
2369 | #endif | ||
2370 | } | ||
2371 | else | ||
2372 | { | ||
2373 | GNUNET_STATISTICS_update (stats, | ||
2374 | gettext_noop ("# transmission attempts failed (no address)"), | ||
2375 | 1, | ||
2376 | GNUNET_NO); | ||
2377 | } | ||
2378 | |||
2379 | return best_address; | ||
2380 | |||
2381 | } | ||
2382 | |||
2383 | |||
2384 | /** | ||
2231 | * FIXME: document. | 2385 | * FIXME: document. |
2232 | */ | 2386 | */ |
2233 | struct GeneratorContext | 2387 | struct GeneratorContext |
@@ -2302,9 +2456,10 @@ refresh_hello () | |||
2302 | GNUNET_free_non_null (our_hello); | 2456 | GNUNET_free_non_null (our_hello); |
2303 | our_hello = hello; | 2457 | our_hello = hello; |
2304 | GNUNET_PEERINFO_add_peer (peerinfo, our_hello); | 2458 | GNUNET_PEERINFO_add_peer (peerinfo, our_hello); |
2305 | npos = neighbours; | 2459 | for (npos = neighbours; npos != NULL; npos = npos->next) |
2306 | while (npos != NULL) | ||
2307 | { | 2460 | { |
2461 | if (! npos->received_pong) | ||
2462 | continue; | ||
2308 | #if DEBUG_TRANSPORT | 2463 | #if DEBUG_TRANSPORT |
2309 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | 2464 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, |
2310 | "Transmitting updated `%s' to neighbour `%4s'\n", | 2465 | "Transmitting updated `%s' to neighbour `%4s'\n", |
@@ -2319,7 +2474,6 @@ refresh_hello () | |||
2319 | (const char *) our_hello, | 2474 | (const char *) our_hello, |
2320 | GNUNET_HELLO_size(our_hello), | 2475 | GNUNET_HELLO_size(our_hello), |
2321 | GNUNET_NO, npos); | 2476 | GNUNET_NO, npos); |
2322 | npos = npos->next; | ||
2323 | } | 2477 | } |
2324 | } | 2478 | } |
2325 | 2479 | ||
@@ -2611,6 +2765,14 @@ plugin_env_notify_address (void *cls, | |||
2611 | struct OwnAddressList *al; | 2765 | struct OwnAddressList *al; |
2612 | struct OwnAddressList *prev; | 2766 | struct OwnAddressList *prev; |
2613 | 2767 | ||
2768 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2769 | (add_remove == GNUNET_YES) | ||
2770 | ? "Adding `%s':%s to the set of our addresses\n" | ||
2771 | : "Removing `%s':%s from the set of our addresses\n", | ||
2772 | a2s (p->short_name, | ||
2773 | addr, addrlen), | ||
2774 | p->short_name); | ||
2775 | |||
2614 | GNUNET_assert (addr != NULL); | 2776 | GNUNET_assert (addr != NULL); |
2615 | if (GNUNET_NO == add_remove) | 2777 | if (GNUNET_NO == add_remove) |
2616 | { | 2778 | { |
@@ -2666,7 +2828,7 @@ notify_clients_connect (const struct GNUNET_PeerIdentity *peer, | |||
2666 | } | 2828 | } |
2667 | #if DEBUG_TRANSPORT | 2829 | #if DEBUG_TRANSPORT |
2668 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2830 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2669 | "Notifying clients about connection from `%s'\n", | 2831 | "Notifying clients about connection with `%s'\n", |
2670 | GNUNET_i2s (peer)); | 2832 | GNUNET_i2s (peer)); |
2671 | #endif | 2833 | #endif |
2672 | GNUNET_STATISTICS_update (stats, | 2834 | GNUNET_STATISTICS_update (stats, |
@@ -3021,71 +3183,6 @@ check_address_exists (void *cls, | |||
3021 | } | 3183 | } |
3022 | 3184 | ||
3023 | 3185 | ||
3024 | |||
3025 | /** | ||
3026 | * Iterator to free entries in the validation_map. | ||
3027 | * | ||
3028 | * @param cls closure (unused) | ||
3029 | * @param key current key code | ||
3030 | * @param value value in the hash map (validation to abort) | ||
3031 | * @return GNUNET_YES (always) | ||
3032 | */ | ||
3033 | static int | ||
3034 | abort_validation (void *cls, | ||
3035 | const GNUNET_HashCode * key, | ||
3036 | void *value) | ||
3037 | { | ||
3038 | struct ValidationEntry *va = value; | ||
3039 | |||
3040 | if (GNUNET_SCHEDULER_NO_TASK != va->timeout_task) | ||
3041 | GNUNET_SCHEDULER_cancel (va->timeout_task); | ||
3042 | GNUNET_free (va->transport_name); | ||
3043 | if (va->chvc != NULL) | ||
3044 | { | ||
3045 | va->chvc->ve_count--; | ||
3046 | if (va->chvc->ve_count == 0) | ||
3047 | { | ||
3048 | GNUNET_CONTAINER_DLL_remove (chvc_head, | ||
3049 | chvc_tail, | ||
3050 | va->chvc); | ||
3051 | GNUNET_free (va->chvc); | ||
3052 | } | ||
3053 | va->chvc = NULL; | ||
3054 | } | ||
3055 | GNUNET_free (va); | ||
3056 | return GNUNET_YES; | ||
3057 | } | ||
3058 | |||
3059 | |||
3060 | /** | ||
3061 | * HELLO validation cleanup task (validation failed). | ||
3062 | * | ||
3063 | * @param cls the 'struct ValidationEntry' that failed | ||
3064 | * @param tc scheduler context (unused) | ||
3065 | */ | ||
3066 | static void | ||
3067 | timeout_hello_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
3068 | { | ||
3069 | struct ValidationEntry *va = cls; | ||
3070 | struct GNUNET_PeerIdentity pid; | ||
3071 | |||
3072 | va->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
3073 | GNUNET_STATISTICS_update (stats, | ||
3074 | gettext_noop ("# address validation timeouts"), | ||
3075 | 1, | ||
3076 | GNUNET_NO); | ||
3077 | GNUNET_CRYPTO_hash (&va->publicKey, | ||
3078 | sizeof (struct | ||
3079 | GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
3080 | &pid.hashPubKey); | ||
3081 | GNUNET_break (GNUNET_OK == | ||
3082 | GNUNET_CONTAINER_multihashmap_remove (validation_map, | ||
3083 | &pid.hashPubKey, | ||
3084 | va)); | ||
3085 | abort_validation (NULL, NULL, va); | ||
3086 | } | ||
3087 | |||
3088 | |||
3089 | static void | 3186 | static void |
3090 | neighbour_timeout_task (void *cls, | 3187 | neighbour_timeout_task (void *cls, |
3091 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 3188 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
@@ -4150,7 +4247,8 @@ check_pending_validation (void *cls, | |||
4150 | &my_identity, | 4247 | &my_identity, |
4151 | sizeof (struct GNUNET_PeerIdentity))) | 4248 | sizeof (struct GNUNET_PeerIdentity))) |
4152 | { | 4249 | { |
4153 | char * peer; | 4250 | char * peer; |
4251 | |||
4154 | GNUNET_asprintf(&peer, "%s",GNUNET_i2s (&pong->pid)); | 4252 | GNUNET_asprintf(&peer, "%s",GNUNET_i2s (&pong->pid)); |
4155 | #if DEBUG_TRANSPORT | 4253 | #if DEBUG_TRANSPORT |
4156 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4254 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -4185,11 +4283,17 @@ check_pending_validation (void *cls, | |||
4185 | if (oal == NULL) | 4283 | if (oal == NULL) |
4186 | { | 4284 | { |
4187 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 4285 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
4188 | _("Not accepting PONG with address `%s' since I cannot confirm having this address.\n"), | 4286 | _("Not accepting PONG from `%s' with address `%s' since I cannot confirm using this address.\n"), |
4287 | GNUNET_i2s (&pong->pid), | ||
4189 | a2s (ve->transport_name, | 4288 | a2s (ve->transport_name, |
4190 | &addr[slen], | 4289 | &addr[slen], |
4191 | alen)); | 4290 | alen)); |
4291 | /* FIXME: since the sender of the PONG currently uses the | ||
4292 | wrong address (see FIMXE there!), we cannot run a | ||
4293 | proper check here... */ | ||
4294 | #if FIXME_URGENT | ||
4192 | return GNUNET_NO; | 4295 | return GNUNET_NO; |
4296 | #endif | ||
4193 | } | 4297 | } |
4194 | if (GNUNET_OK != | 4298 | if (GNUNET_OK != |
4195 | GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING, | 4299 | GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING, |
@@ -4323,9 +4427,11 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message, | |||
4323 | sizeof (struct GNUNET_PeerIdentity))) | 4427 | sizeof (struct GNUNET_PeerIdentity))) |
4324 | { | 4428 | { |
4325 | /* PONG send to self, ignore */ | 4429 | /* PONG send to self, ignore */ |
4430 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4431 | "Receiving `%s' message from myself\n", | ||
4432 | "PONG"); | ||
4326 | return; | 4433 | return; |
4327 | } | 4434 | } |
4328 | |||
4329 | #if DEBUG_TRANSPORT > 1 | 4435 | #if DEBUG_TRANSPORT > 1 |
4330 | /* we get tons of these that just get discarded, only log | 4436 | /* we get tons of these that just get discarded, only log |
4331 | if we are quite verbose */ | 4437 | if we are quite verbose */ |
@@ -4740,9 +4846,11 @@ process_hello (struct TransportPlugin *plugin, | |||
4740 | const struct GNUNET_HELLO_Message *hello; | 4846 | const struct GNUNET_HELLO_Message *hello; |
4741 | struct CheckHelloValidatedContext *chvc; | 4847 | struct CheckHelloValidatedContext *chvc; |
4742 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey; | 4848 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey; |
4849 | struct NeighbourList *n; | ||
4743 | #if DEBUG_TRANSPORT_HELLO > 2 | 4850 | #if DEBUG_TRANSPORT_HELLO > 2 |
4744 | char *my_id; | 4851 | char *my_id; |
4745 | #endif | 4852 | #endif |
4853 | |||
4746 | hsize = ntohs (message->size); | 4854 | hsize = ntohs (message->size); |
4747 | if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_HELLO) || | 4855 | if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_HELLO) || |
4748 | (hsize < sizeof (struct GNUNET_MessageHeader))) | 4856 | (hsize < sizeof (struct GNUNET_MessageHeader))) |
@@ -4755,21 +4863,6 @@ process_hello (struct TransportPlugin *plugin, | |||
4755 | 1, | 4863 | 1, |
4756 | GNUNET_NO); | 4864 | GNUNET_NO); |
4757 | 4865 | ||
4758 | /* first, check if load is too high */ | ||
4759 | if (GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_BACKGROUND) > MAX_HELLO_LOAD) | ||
4760 | { | ||
4761 | GNUNET_STATISTICS_update (stats, | ||
4762 | gettext_noop ("# HELLOs ignored due to high load"), | ||
4763 | 1, | ||
4764 | GNUNET_NO); | ||
4765 | #if DEBUG_TRANSPORT_HELLO | ||
4766 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4767 | "Ignoring `%s' for `%4s', load too high.\n", | ||
4768 | "HELLO", | ||
4769 | GNUNET_i2s (&target)); | ||
4770 | #endif | ||
4771 | return GNUNET_OK; | ||
4772 | } | ||
4773 | hello = (const struct GNUNET_HELLO_Message *) message; | 4866 | hello = (const struct GNUNET_HELLO_Message *) message; |
4774 | if (GNUNET_OK != GNUNET_HELLO_get_key (hello, &publicKey)) | 4867 | if (GNUNET_OK != GNUNET_HELLO_get_key (hello, &publicKey)) |
4775 | { | 4868 | { |
@@ -4782,7 +4875,6 @@ process_hello (struct TransportPlugin *plugin, | |||
4782 | GNUNET_break_op (0); | 4875 | GNUNET_break_op (0); |
4783 | return GNUNET_SYSERR; | 4876 | return GNUNET_SYSERR; |
4784 | } | 4877 | } |
4785 | |||
4786 | GNUNET_CRYPTO_hash (&publicKey, | 4878 | GNUNET_CRYPTO_hash (&publicKey, |
4787 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | 4879 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), |
4788 | &target.hashPubKey); | 4880 | &target.hashPubKey); |
@@ -4793,7 +4885,6 @@ process_hello (struct TransportPlugin *plugin, | |||
4793 | "HELLO", | 4885 | "HELLO", |
4794 | GNUNET_i2s (&target)); | 4886 | GNUNET_i2s (&target)); |
4795 | #endif | 4887 | #endif |
4796 | |||
4797 | if (0 == memcmp (&my_identity, | 4888 | if (0 == memcmp (&my_identity, |
4798 | &target, | 4889 | &target, |
4799 | sizeof (struct GNUNET_PeerIdentity))) | 4890 | sizeof (struct GNUNET_PeerIdentity))) |
@@ -4804,6 +4895,31 @@ process_hello (struct TransportPlugin *plugin, | |||
4804 | GNUNET_NO); | 4895 | GNUNET_NO); |
4805 | return GNUNET_OK; | 4896 | return GNUNET_OK; |
4806 | } | 4897 | } |
4898 | n = find_neighbour (&target); | ||
4899 | if ( (NULL != n) && | ||
4900 | (! n->public_key_valid) ) | ||
4901 | { | ||
4902 | GNUNET_HELLO_get_key (hello, &n->publicKey); | ||
4903 | n->public_key_valid = GNUNET_YES; | ||
4904 | } | ||
4905 | |||
4906 | /* check if load is too high before doing expensive stuff */ | ||
4907 | if (GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_BACKGROUND) > MAX_HELLO_LOAD) | ||
4908 | { | ||
4909 | GNUNET_STATISTICS_update (stats, | ||
4910 | gettext_noop ("# HELLOs ignored due to high load"), | ||
4911 | 1, | ||
4912 | GNUNET_NO); | ||
4913 | #if DEBUG_TRANSPORT_HELLO | ||
4914 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4915 | "Ignoring `%s' for `%4s', load too high.\n", | ||
4916 | "HELLO", | ||
4917 | GNUNET_i2s (&target)); | ||
4918 | #endif | ||
4919 | return GNUNET_OK; | ||
4920 | } | ||
4921 | |||
4922 | |||
4807 | chvc = chvc_head; | 4923 | chvc = chvc_head; |
4808 | while (NULL != chvc) | 4924 | while (NULL != chvc) |
4809 | { | 4925 | { |
@@ -4819,7 +4935,7 @@ process_hello (struct TransportPlugin *plugin, | |||
4819 | #endif | 4935 | #endif |
4820 | return GNUNET_OK; /* validation already pending */ | 4936 | return GNUNET_OK; /* validation already pending */ |
4821 | } | 4937 | } |
4822 | if (GNUNET_HELLO_size(hello) == GNUNET_HELLO_size (chvc->hello)) | 4938 | if (GNUNET_HELLO_size (hello) == GNUNET_HELLO_size (chvc->hello)) |
4823 | GNUNET_break (0 != memcmp (hello, chvc->hello, | 4939 | GNUNET_break (0 != memcmp (hello, chvc->hello, |
4824 | GNUNET_HELLO_size(hello))); | 4940 | GNUNET_HELLO_size(hello))); |
4825 | chvc = chvc->next; | 4941 | chvc = chvc->next; |
@@ -5034,11 +5150,11 @@ disconnect_neighbour (struct NeighbourList *n, int check) | |||
5034 | * in response to the peer by any means necessary. | 5150 | * in response to the peer by any means necessary. |
5035 | */ | 5151 | */ |
5036 | static int | 5152 | static int |
5037 | handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | 5153 | handle_ping (void *cls, const struct GNUNET_MessageHeader *message, |
5038 | const struct GNUNET_PeerIdentity *peer, | 5154 | const struct GNUNET_PeerIdentity *peer, |
5039 | struct Session *session, | 5155 | struct Session *session, |
5040 | const char *sender_address, | 5156 | const char *sender_address, |
5041 | uint16_t sender_address_len) | 5157 | uint16_t sender_address_len) |
5042 | { | 5158 | { |
5043 | struct TransportPlugin *plugin = cls; | 5159 | struct TransportPlugin *plugin = cls; |
5044 | struct SessionHeader *session_header = (struct SessionHeader*) session; | 5160 | struct SessionHeader *session_header = (struct SessionHeader*) session; |
@@ -5051,6 +5167,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5051 | const char *addr; | 5167 | const char *addr; |
5052 | size_t alen; | 5168 | size_t alen; |
5053 | size_t slen; | 5169 | size_t slen; |
5170 | int did_pong; | ||
5054 | 5171 | ||
5055 | if (ntohs (message->size) < sizeof (struct TransportPingMessage)) | 5172 | if (ntohs (message->size) < sizeof (struct TransportPingMessage)) |
5056 | { | 5173 | { |
@@ -5103,6 +5220,19 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5103 | GNUNET_i2s (peer)); | 5220 | GNUNET_i2s (peer)); |
5104 | return GNUNET_SYSERR; | 5221 | return GNUNET_SYSERR; |
5105 | } | 5222 | } |
5223 | /* FIXME-urg: the use of 'sender_address' in the code below is doubly-wrong: | ||
5224 | 1) it is NULL when we need to have a real value | ||
5225 | 2) it is documented to be the address of the sender (source-IP), where | ||
5226 | what we actually want is our LISTEN IP (what we 'bound' to); which we don't even | ||
5227 | have... | ||
5228 | */ | ||
5229 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
5230 | "Creating PONG indicating that we received a connection at our address `%s' from `%s'.\n", | ||
5231 | a2s (plugin->short_name, | ||
5232 | sender_address, | ||
5233 | sender_address_len), | ||
5234 | GNUNET_i2s (peer)); | ||
5235 | |||
5106 | pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len + slen); | 5236 | pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len + slen); |
5107 | pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len + slen); | 5237 | pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len + slen); |
5108 | pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); | 5238 | pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); |
@@ -5229,6 +5359,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5229 | } | 5359 | } |
5230 | n = find_neighbour(peer); | 5360 | n = find_neighbour(peer); |
5231 | GNUNET_assert (n != NULL); | 5361 | GNUNET_assert (n != NULL); |
5362 | did_pong = GNUNET_NO; | ||
5232 | /* first try reliable response transmission */ | 5363 | /* first try reliable response transmission */ |
5233 | rl = n->plugins; | 5364 | rl = n->plugins; |
5234 | while (rl != NULL) | 5365 | while (rl != NULL) |
@@ -5248,6 +5379,9 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5248 | GNUNET_SYSERR, | 5379 | GNUNET_SYSERR, |
5249 | NULL, NULL)) | 5380 | NULL, NULL)) |
5250 | { | 5381 | { |
5382 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
5383 | "Transmitted PONG to `%s' via reliable mechanism\n", | ||
5384 | GNUNET_i2s (peer)); | ||
5251 | /* done! */ | 5385 | /* done! */ |
5252 | GNUNET_STATISTICS_update (stats, | 5386 | GNUNET_STATISTICS_update (stats, |
5253 | gettext_noop ("# PONGs unicast via reliable transport"), | 5387 | gettext_noop ("# PONGs unicast via reliable transport"), |
@@ -5256,6 +5390,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5256 | GNUNET_free (pong); | 5390 | GNUNET_free (pong); |
5257 | return GNUNET_OK; | 5391 | return GNUNET_OK; |
5258 | } | 5392 | } |
5393 | did_pong = GNUNET_YES; | ||
5259 | fal = fal->next; | 5394 | fal = fal->next; |
5260 | } | 5395 | } |
5261 | rl = rl->next; | 5396 | rl = rl->next; |
@@ -5271,6 +5406,13 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5271 | fal = rl->addresses; | 5406 | fal = rl->addresses; |
5272 | while (fal != NULL) | 5407 | while (fal != NULL) |
5273 | { | 5408 | { |
5409 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
5410 | "Transmitting PONG to `%s' via unreliable mechanism `%s':%s\n", | ||
5411 | GNUNET_i2s (peer), | ||
5412 | a2s (rl->plugin->short_name, | ||
5413 | fal->addr, | ||
5414 | fal->addrlen), | ||
5415 | rl->plugin->short_name); | ||
5274 | transmit_to_peer(NULL, fal, | 5416 | transmit_to_peer(NULL, fal, |
5275 | TRANSPORT_PONG_PRIORITY, | 5417 | TRANSPORT_PONG_PRIORITY, |
5276 | HELLO_VERIFICATION_TIMEOUT, | 5418 | HELLO_VERIFICATION_TIMEOUT, |
@@ -5278,11 +5420,16 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5278 | ntohs(pong->header.size), | 5420 | ntohs(pong->header.size), |
5279 | GNUNET_YES, | 5421 | GNUNET_YES, |
5280 | n); | 5422 | n); |
5423 | did_pong = GNUNET_YES; | ||
5281 | fal = fal->next; | 5424 | fal = fal->next; |
5282 | } | 5425 | } |
5283 | rl = rl->next; | 5426 | rl = rl->next; |
5284 | } | 5427 | } |
5285 | GNUNET_free(pong); | 5428 | GNUNET_free(pong); |
5429 | if (GNUNET_YES != did_pong) | ||
5430 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
5431 | _("Could not send PONG to `%s': no address available\n"), | ||
5432 | GNUNET_i2s (peer)); | ||
5286 | return GNUNET_OK; | 5433 | return GNUNET_OK; |
5287 | } | 5434 | } |
5288 | 5435 | ||
@@ -5441,6 +5588,8 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
5441 | break; | 5588 | break; |
5442 | case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: | 5589 | case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: |
5443 | handle_ping (plugin, message, peer, session, sender_address, sender_address_len); | 5590 | handle_ping (plugin, message, peer, session, sender_address, sender_address_len); |
5591 | if (! n->received_pong) | ||
5592 | transmit_plain_ping (n); | ||
5444 | break; | 5593 | break; |
5445 | case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: | 5594 | case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: |
5446 | handle_pong (plugin, message, peer, sender_address, sender_address_len); | 5595 | handle_pong (plugin, message, peer, sender_address, sender_address_len); |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index a8eee970c..af9538a68 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -38,9 +38,9 @@ | |||
38 | #include "gnunet_transport_plugin.h" | 38 | #include "gnunet_transport_plugin.h" |
39 | #include "transport.h" | 39 | #include "transport.h" |
40 | 40 | ||
41 | #define DEBUG_TCP GNUNET_YES | 41 | #define DEBUG_TCP GNUNET_NO |
42 | 42 | ||
43 | #define DEBUG_TCP_NAT GNUNET_YES | 43 | #define DEBUG_TCP_NAT GNUNET_NO |
44 | 44 | ||
45 | 45 | ||
46 | /** | 46 | /** |
@@ -1517,7 +1517,6 @@ handle_tcp_nat_probe (void *cls, | |||
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | tcp_nat_probe = (const struct TCP_NAT_ProbeMessage *)message; | 1519 | tcp_nat_probe = (const struct TCP_NAT_ProbeMessage *)message; |
1520 | |||
1521 | if (0 == memcmp (&tcp_nat_probe->clientIdentity, | 1520 | if (0 == memcmp (&tcp_nat_probe->clientIdentity, |
1522 | plugin->env->my_identity, | 1521 | plugin->env->my_identity, |
1523 | sizeof (struct GNUNET_PeerIdentity))) | 1522 | sizeof (struct GNUNET_PeerIdentity))) |
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index ac818d557..ae56c939f 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "transport.h" | 37 | #include "transport.h" |
38 | #include "transport-testing.h" | 38 | #include "transport-testing.h" |
39 | 39 | ||
40 | #define VERBOSE GNUNET_YES | 40 | #define VERBOSE GNUNET_NO |
41 | 41 | ||
42 | #define VERBOSE_ARM GNUNET_NO | 42 | #define VERBOSE_ARM GNUNET_NO |
43 | 43 | ||
@@ -122,16 +122,57 @@ static void | |||
122 | stop_arm (struct PeerContext *p) | 122 | stop_arm (struct PeerContext *p) |
123 | { | 123 | { |
124 | #if START_ARM | 124 | #if START_ARM |
125 | if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) | 125 | if (NULL != p->arm_proc) |
126 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 126 | { |
127 | GNUNET_OS_process_wait (p->arm_proc); | 127 | if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) |
128 | GNUNET_OS_process_close (p->arm_proc); | 128 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
129 | p->arm_proc = NULL; | 129 | GNUNET_OS_process_wait (p->arm_proc); |
130 | GNUNET_OS_process_close (p->arm_proc); | ||
131 | p->arm_proc = NULL; | ||
132 | } | ||
130 | #endif | 133 | #endif |
131 | GNUNET_CONFIGURATION_destroy (p->cfg); | 134 | GNUNET_CONFIGURATION_destroy (p->cfg); |
132 | } | 135 | } |
133 | 136 | ||
134 | 137 | ||
138 | |||
139 | |||
140 | static void | ||
141 | exchange_hello_last (void *cls, | ||
142 | const struct GNUNET_MessageHeader *message) | ||
143 | { | ||
144 | struct PeerContext *me = cls; | ||
145 | |||
146 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
147 | "Exchanging HELLO of size %d with peer (%s)!\n", | ||
148 | (int) GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message), | ||
149 | GNUNET_i2s (&me->id)); | ||
150 | GNUNET_assert (message != NULL); | ||
151 | GNUNET_assert (GNUNET_OK == | ||
152 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | ||
153 | message, &me->id)); | ||
154 | GNUNET_TRANSPORT_offer_hello (p1.th, message, NULL, NULL); | ||
155 | } | ||
156 | |||
157 | |||
158 | static void | ||
159 | exchange_hello (void *cls, | ||
160 | const struct GNUNET_MessageHeader *message) | ||
161 | { | ||
162 | struct PeerContext *me = cls; | ||
163 | |||
164 | GNUNET_assert (message != NULL); | ||
165 | GNUNET_assert (GNUNET_OK == | ||
166 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | ||
167 | message, &me->id)); | ||
168 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
169 | "Exchanging HELLO of size %d from peer %s!\n", | ||
170 | (int) GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message), | ||
171 | GNUNET_i2s (&me->id)); | ||
172 | GNUNET_TRANSPORT_offer_hello (p2.th, message, NULL, NULL); | ||
173 | } | ||
174 | |||
175 | |||
135 | static void | 176 | static void |
136 | end_badly () | 177 | end_badly () |
137 | { | 178 | { |
@@ -139,8 +180,15 @@ end_badly () | |||
139 | GNUNET_break (0); | 180 | GNUNET_break (0); |
140 | 181 | ||
141 | if (th != NULL) | 182 | if (th != NULL) |
142 | GNUNET_TRANSPORT_notify_transmit_ready_cancel(th); | 183 | { |
143 | th = NULL; | 184 | GNUNET_TRANSPORT_notify_transmit_ready_cancel(th); |
185 | th = NULL; | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_last, &p2); | ||
190 | GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, &p1); | ||
191 | } | ||
144 | 192 | ||
145 | GNUNET_TRANSPORT_disconnect (p1.th); | 193 | GNUNET_TRANSPORT_disconnect (p1.th); |
146 | GNUNET_TRANSPORT_disconnect (p2.th); | 194 | GNUNET_TRANSPORT_disconnect (p2.th); |
@@ -199,44 +247,6 @@ notify_ready (void *cls, size_t size, void *buf) | |||
199 | 247 | ||
200 | 248 | ||
201 | static void | 249 | static void |
202 | exchange_hello_last (void *cls, | ||
203 | const struct GNUNET_MessageHeader *message) | ||
204 | { | ||
205 | struct PeerContext *me = cls; | ||
206 | |||
207 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
208 | "Exchanging HELLO of size %d with peer (%s)!\n", | ||
209 | (int) GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message), | ||
210 | GNUNET_i2s (&me->id)); | ||
211 | GNUNET_assert (message != NULL); | ||
212 | GNUNET_assert (GNUNET_OK == | ||
213 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | ||
214 | message, &me->id)); | ||
215 | GNUNET_TRANSPORT_offer_hello (p1.th, message, NULL, NULL); | ||
216 | } | ||
217 | |||
218 | |||
219 | |||
220 | static void | ||
221 | exchange_hello (void *cls, | ||
222 | const struct GNUNET_MessageHeader *message) | ||
223 | { | ||
224 | struct PeerContext *me = cls; | ||
225 | |||
226 | GNUNET_assert (message != NULL); | ||
227 | GNUNET_assert (GNUNET_OK == | ||
228 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | ||
229 | message, &me->id)); | ||
230 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
231 | "Exchanging HELLO of size %d from peer %s!\n", | ||
232 | (int) GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message), | ||
233 | GNUNET_i2s (&me->id)); | ||
234 | GNUNET_TRANSPORT_offer_hello (p2.th, message, NULL, NULL); | ||
235 | } | ||
236 | |||
237 | |||
238 | |||
239 | static void | ||
240 | notify_connect (void *cls, | 250 | notify_connect (void *cls, |
241 | const struct GNUNET_PeerIdentity *peer, | 251 | const struct GNUNET_PeerIdentity *peer, |
242 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | 252 | const struct GNUNET_TRANSPORT_ATS_Information *ats, |
diff --git a/src/transport/test_transport_api_tcp_peer1.conf b/src/transport/test_transport_api_tcp_peer1.conf index d6b0cc8ab..4db080cda 100644 --- a/src/transport/test_transport_api_tcp_peer1.conf +++ b/src/transport/test_transport_api_tcp_peer1.conf | |||
@@ -31,7 +31,7 @@ MINIMUM-FRIENDS = 0 | |||
31 | 31 | ||
32 | [transport] | 32 | [transport] |
33 | PLUGINS = tcp | 33 | PLUGINS = tcp |
34 | DEBUG = YES | 34 | #DEBUG = YES |
35 | #PREFIX = xterm -T transport2 -e gdb --command=cmd --args | 35 | #PREFIX = xterm -T transport2 -e gdb --command=cmd --args |
36 | #PREFIX = valgrind --tool=memcheck --leak-check=full --log-file=transport%p.vg | 36 | #PREFIX = valgrind --tool=memcheck --leak-check=full --log-file=transport%p.vg |
37 | ACCEPT_FROM6 = ::1; | 37 | ACCEPT_FROM6 = ::1; |
diff --git a/src/transport/transport.h b/src/transport/transport.h index 504cbe62b..0e4fba731 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #define ATS_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) | 36 | #define ATS_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) |
37 | #define ATS_MAX_ITERATIONS INT_MAX | 37 | #define ATS_MAX_ITERATIONS INT_MAX |
38 | 38 | ||
39 | #define DEBUG_TRANSPORT GNUNET_YES | 39 | #define DEBUG_TRANSPORT 3 |
40 | 40 | ||
41 | #define DEBUG_TRANSPORT_TIMEOUT GNUNET_NO | 41 | #define DEBUG_TRANSPORT_TIMEOUT GNUNET_NO |
42 | 42 | ||
diff --git a/src/util/connection.c b/src/util/connection.c index ccdaaa9ed..200f7aed6 100644 --- a/src/util/connection.c +++ b/src/util/connection.c | |||
@@ -1028,6 +1028,9 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, | |||
1028 | { | 1028 | { |
1029 | /* maybe refused / unsupported address, try next */ | 1029 | /* maybe refused / unsupported address, try next */ |
1030 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect"); | 1030 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect"); |
1031 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1032 | _("Attempt to connect to `%s' failed\n"), | ||
1033 | GNUNET_a2s (serv_addr, addrlen)); | ||
1031 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); | 1034 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); |
1032 | return NULL; | 1035 | return NULL; |
1033 | } | 1036 | } |