aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-04-09 16:55:39 +0000
committerng0 <ng0@n0.is>2019-04-09 16:55:39 +0000
commit6e626937fd5133188d2bd06f280a1b889219eef2 (patch)
tree5cce69b3fe6f74297b8246656c8bf611d98022fb /src
parentc2e1ab0e17a7b76e66be1b4fff0d02f196cba34a (diff)
parentac1134ca9fb7ff972cf5e5f7e0e070368f77789b (diff)
downloadgnunet-6e626937fd5133188d2bd06f280a1b889219eef2.tar.gz
gnunet-6e626937fd5133188d2bd06f280a1b889219eef2.zip
Merge branch 'master' of gnunet.org:gnunet
Diffstat (limited to 'src')
-rw-r--r--src/abe/Makefile.am2
-rw-r--r--src/include/gnunet_hello_lib.h18
-rw-r--r--src/include/gnunet_protocols.h7
-rw-r--r--src/include/gnunet_rps_service.h40
-rw-r--r--src/include/gnunet_transport_application_service.h46
-rw-r--r--src/nt/nt.c24
-rw-r--r--src/reclaim/Makefile.am2
-rw-r--r--src/rps/gnunet-rps-profiler.c93
-rw-r--r--src/rps/gnunet-service-rps.c11
-rw-r--r--src/rps/gnunet-service-rps_sampler.c2
-rw-r--r--src/rps/rps-sampler_client.c70
-rw-r--r--src/rps/rps-sampler_client.h8
-rw-r--r--src/rps/rps-sampler_common.c187
-rw-r--r--src/rps/rps-sampler_common.h56
-rw-r--r--src/rps/rps-test_util.h22
-rw-r--r--src/rps/rps_api.c218
-rw-r--r--src/transport/Makefile.am1
-rw-r--r--src/transport/gnunet-communicator-udp.c463
-rw-r--r--src/transport/gnunet-service-tng.c265
-rw-r--r--src/transport/transport.h31
-rw-r--r--src/transport/transport_api2_application.c52
-rw-r--r--src/util/common_logging.c23
22 files changed, 1227 insertions, 414 deletions
diff --git a/src/abe/Makefile.am b/src/abe/Makefile.am
index 23a7ae68e..cccd3ccb0 100644
--- a/src/abe/Makefile.am
+++ b/src/abe/Makefile.am
@@ -20,6 +20,8 @@ libgnunetabe_la_LIBADD = \
20 $(LTLIBICONV) \ 20 $(LTLIBICONV) \
21 $(LTLIBINTL) \ 21 $(LTLIBINTL) \
22 $(ABE_LIBADD) \ 22 $(ABE_LIBADD) \
23 $(top_builddir)/src/util/libgnunetutil.la \
24 -lgmp \
23 -lgabe \ 25 -lgabe \
24 -lpbc \ 26 -lpbc \
25 -lglib-2.0 \ 27 -lglib-2.0 \
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
index fcd422701..5e2190cc6 100644
--- a/src/include/gnunet_hello_lib.h
+++ b/src/include/gnunet_hello_lib.h
@@ -495,11 +495,11 @@ GNUNET_HELLO_parse_uri (const char *uri,
495 */ 495 */
496void 496void
497GNUNET_HELLO_sign_address (const char *address, 497GNUNET_HELLO_sign_address (const char *address,
498 enum GNUNET_NetworkType nt, 498 enum GNUNET_NetworkType nt,
499 struct GNUNET_TIME_Absolute expiration, 499 struct GNUNET_TIME_Absolute expiration,
500 const struct GNUNET_CRYPTO_EddsaPrivateKey *private_key, 500 const struct GNUNET_CRYPTO_EddsaPrivateKey *private_key,
501 void **result, 501 void **result,
502 size_t *result_size); 502 size_t *result_size);
503 503
504 504
505/** 505/**
@@ -514,10 +514,10 @@ GNUNET_HELLO_sign_address (const char *address,
514 */ 514 */
515char * 515char *
516GNUNET_HELLO_extract_address (const void *raw, 516GNUNET_HELLO_extract_address (const void *raw,
517 size_t raw_size, 517 size_t raw_size,
518 const struct GNUNET_PeerIdentity *pid, 518 const struct GNUNET_PeerIdentity *pid,
519 enum GNUNET_NetworkType *nt, 519 enum GNUNET_NetworkType *nt,
520 struct GNUNET_TIME_Absolute *expiration); 520 struct GNUNET_TIME_Absolute *expiration);
521 521
522 522
523/** 523/**
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 7f1667d51..4f97d3078 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3189,8 +3189,15 @@ extern "C"
3189 */ 3189 */
3190#define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL 1301 3190#define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL 1301
3191 3191
3192/**
3193 * Type of the 'struct RequestHelloValidationMessage' send by clients to TRANSPORT
3194 * to trigger validation of addresses.
3195 */
3196#define GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION 1302
3197
3192 3198
3193/* ************** NEW (NG) ATS Messages ************* */ 3199/* ************** NEW (NG) ATS Messages ************* */
3200/* NOTE: it is not clear ATS will survive in TNG */
3194 3201
3195/** 3202/**
3196 * Type of the 'struct ExpressPreferenceMessage' send by clients to ATS 3203 * Type of the 'struct ExpressPreferenceMessage' send by clients to ATS
diff --git a/src/include/gnunet_rps_service.h b/src/include/gnunet_rps_service.h
index b1dd1b5af..c88e75cc7 100644
--- a/src/include/gnunet_rps_service.h
+++ b/src/include/gnunet_rps_service.h
@@ -67,6 +67,21 @@ typedef void (* GNUNET_RPS_NotifyReadyCB) (void *cls,
67 67
68 68
69/** 69/**
70 * Callback called when requested random peer with additional information is
71 * available.
72 *
73 * @param cls the closure given with the request
74 * @param peer The Peer ID
75 * @param probability The probability with which all elements have been observed
76 * @param num_observed Number of IDs this sampler has observed
77 */
78typedef void (* GNUNET_RPS_NotifyReadySingleInfoCB) (void *cls,
79 const struct GNUNET_PeerIdentity *peer,
80 double probability,
81 uint32_t num_observed);
82
83
84/**
70 * Connect to the rps service 85 * Connect to the rps service
71 * 86 *
72 * @param cfg configuration to use 87 * @param cfg configuration to use
@@ -117,6 +132,21 @@ GNUNET_RPS_request_peers (struct GNUNET_RPS_Handle *h, uint32_t n,
117 GNUNET_RPS_NotifyReadyCB ready_cb, 132 GNUNET_RPS_NotifyReadyCB ready_cb,
118 void *cls); 133 void *cls);
119 134
135
136/**
137 * Request one random peer, getting additional information.
138 *
139 * @param rps_handle handle to the rps service
140 * @param ready_cb the callback called when the peers are available
141 * @param cls closure given to the callback
142 * @return a handle to cancel this request
143 */
144struct GNUNET_RPS_Request_Handle_Single_Info *
145GNUNET_RPS_request_peer_info (struct GNUNET_RPS_Handle *rps_handle,
146 GNUNET_RPS_NotifyReadySingleInfoCB ready_cb,
147 void *cls);
148
149
120/** 150/**
121 * Seed rps service with peerIDs. 151 * Seed rps service with peerIDs.
122 * 152 *
@@ -137,6 +167,16 @@ GNUNET_RPS_seed_ids (struct GNUNET_RPS_Handle *h, uint32_t n,
137GNUNET_RPS_request_cancel (struct GNUNET_RPS_Request_Handle *rh); 167GNUNET_RPS_request_cancel (struct GNUNET_RPS_Request_Handle *rh);
138 168
139 169
170/**
171 * Cancle an issued single info request.
172 *
173 * @param rhs request handle of request to cancle
174 */
175void
176GNUNET_RPS_request_single_info_cancel (
177 struct GNUNET_RPS_Request_Handle_Single_Info *rhs);
178
179
140#if ENABLE_MALICIOUS 180#if ENABLE_MALICIOUS
141/** 181/**
142 * Turn RPS service to act malicious. 182 * Turn RPS service to act malicious.
diff --git a/src/include/gnunet_transport_application_service.h b/src/include/gnunet_transport_application_service.h
index 31097b88e..bbd4e3ddf 100644
--- a/src/include/gnunet_transport_application_service.h
+++ b/src/include/gnunet_transport_application_service.h
@@ -34,6 +34,7 @@
34 34
35#include "gnunet_constants.h" 35#include "gnunet_constants.h"
36#include "gnunet_util_lib.h" 36#include "gnunet_util_lib.h"
37#include "gnunet_nt_lib.h"
37 38
38/** 39/**
39 * Handle to the TRANSPORT subsystem for making suggestions about 40 * Handle to the TRANSPORT subsystem for making suggestions about
@@ -62,37 +63,28 @@ GNUNET_TRANSPORT_application_done (struct GNUNET_TRANSPORT_ApplicationHandle *ch
62 63
63 64
64/** 65/**
65 * Handle for suggestion requests. 66 * An application (or a communicator) has received a HELLO (or other address
66 */ 67 * data of another peer) and wants TRANSPORT to validate that the address is
67struct GNUNET_TRANSPORT_ApplicationSuggestHandle; 68 * correct. The result is NOT returned, in fact TRANSPORT may do nothing
68 69 * (i.e. if it has too many active validations or recently tried this one
69 70 * already). If the @a addr validates, TRANSPORT will persist the address
70/** 71 * with PEERSTORE.
71 * An application would like to communicate with a peer. TRANSPORT should
72 * allocate bandwith using a suitable address for requiremetns @a pk
73 * to transport.
74 * 72 *
75 * @param ch handle 73 * @param ch handle
76 * @param peer identity of the peer we need an address for 74 * @param peer identity of the peer we have an address for
77 * @param pk what kind of application will the application require (can be 75 * @param expiration when does @a addr expire; used by TRANSPORT to know when
78 * #GNUNET_MQ_PREFERENCE_NONE, we will still try to connect) 76 * to definitively give up attempting to validate
79 * @param bw desired bandwith, can be zero (we will still try to connect) 77 * @param nt network type of @a addr (as claimed by the other peer);
80 * @return suggestion handle, NULL if request is already pending 78 * used by TRANSPORT to avoid trying @a addr's that really cannot work
81 */ 79 * due to network type missmatches
82struct GNUNET_TRANSPORT_ApplicationSuggestHandle * 80 * @param addr address to validate
83GNUNET_TRANSPORT_application_suggest (struct GNUNET_TRANSPORT_ApplicationHandle *ch,
84 const struct GNUNET_PeerIdentity *peer,
85 enum GNUNET_MQ_PreferenceKind pk,
86 struct GNUNET_BANDWIDTH_Value32NBO bw);
87
88
89/**
90 * We no longer care about communicating with a peer.
91 *
92 * @param sh handle
93 */ 81 */
94void 82void
95GNUNET_TRANSPORT_application_suggest_cancel (struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh); 83GNUNET_TRANSPORT_application_validate (struct GNUNET_TRANSPORT_ApplicationHandle *ch,
84 const struct GNUNET_PeerIdentity *peer,
85 struct GNUNET_TIME_Absolute expiration,
86 enum GNUNET_NetworkType nt,
87 const char *addr);
96 88
97/** @} */ /* end of group */ 89/** @} */ /* end of group */
98 90
diff --git a/src/nt/nt.c b/src/nt/nt.c
index 3b95738e8..45d24520f 100644
--- a/src/nt/nt.c
+++ b/src/nt/nt.c
@@ -200,15 +200,21 @@ interface_proc (void *cls,
200 net->netmask = (struct sockaddr *) &tmp[1]; 200 net->netmask = (struct sockaddr *) &tmp[1];
201 net->length = addrlen; 201 net->length = addrlen;
202 202
203 memset (&network4, 0, sizeof (network4)); 203 memset (&network4,
204 0,
205 sizeof (network4));
204 network4.sin_family = AF_INET; 206 network4.sin_family = AF_INET;
205#if HAVE_SOCKADDR_IN_SIN_LEN 207#if HAVE_SOCKADDR_IN_SIN_LEN
206 network4.sin_len = sizeof (network4); 208 network4.sin_len = sizeof (network4);
207#endif 209#endif
208 network4.sin_addr.s_addr = (addr4->sin_addr.s_addr & netmask4->sin_addr.s_addr); 210 network4.sin_addr.s_addr = (addr4->sin_addr.s_addr & netmask4->sin_addr.s_addr);
209 211
210 GNUNET_memcpy (net->netmask, netmask4, sizeof (struct sockaddr_in)); 212 GNUNET_memcpy (net->netmask,
211 GNUNET_memcpy (net->network, &network4, sizeof (struct sockaddr_in)); 213 netmask4,
214 sizeof (struct sockaddr_in));
215 GNUNET_memcpy (net->network,
216 &network4,
217 sizeof (struct sockaddr_in));
212 } 218 }
213 219
214 if (addr->sa_family == AF_INET6) 220 if (addr->sa_family == AF_INET6)
@@ -236,8 +242,12 @@ interface_proc (void *cls,
236 for (c = 0; c < 4; c++) 242 for (c = 0; c < 4; c++)
237 net_elem[c] = addr_elem[c] & mask_elem[c]; 243 net_elem[c] = addr_elem[c] & mask_elem[c];
238 244
239 GNUNET_memcpy (net->netmask, netmask6, sizeof (struct sockaddr_in6)); 245 GNUNET_memcpy (net->netmask,
240 GNUNET_memcpy (net->network, &network6, sizeof (struct sockaddr_in6)); 246 netmask6,
247 sizeof (struct sockaddr_in6));
248 GNUNET_memcpy (net->network,
249 &network6,
250 sizeof (struct sockaddr_in6));
241 } 251 }
242 if (NULL == net) 252 if (NULL == net)
243 return GNUNET_OK; /* odd / unsupported address family */ 253 return GNUNET_OK; /* odd / unsupported address family */
@@ -291,8 +301,8 @@ get_addresses (void *cls)
291 */ 301 */
292enum GNUNET_NetworkType 302enum GNUNET_NetworkType
293GNUNET_NT_scanner_get_type (struct GNUNET_NT_InterfaceScanner *is, 303GNUNET_NT_scanner_get_type (struct GNUNET_NT_InterfaceScanner *is,
294 const struct sockaddr *addr, 304 const struct sockaddr *addr,
295 socklen_t addrlen) 305 socklen_t addrlen)
296{ 306{
297 struct NT_Network *cur = is->net_head; 307 struct NT_Network *cur = is->net_head;
298 enum GNUNET_NetworkType type = GNUNET_NT_UNSPECIFIED; 308 enum GNUNET_NetworkType type = GNUNET_NT_UNSPECIFIED;
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 13918508e..be50cce26 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -99,6 +99,7 @@ libgnunet_plugin_reclaim_sqlite_la_LIBADD = \
99 libgnunetreclaim.la \ 99 libgnunetreclaim.la \
100 $(top_builddir)/src/sq/libgnunetsq.la \ 100 $(top_builddir)/src/sq/libgnunetsq.la \
101 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 101 $(top_builddir)/src/statistics/libgnunetstatistics.la \
102 $(top_builddir)/src/reclaim-attribute/libgnunetreclaimattribute.la \
102 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 \ 103 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 \
103 $(LTLIBINTL) 104 $(LTLIBINTL)
104libgnunet_plugin_reclaim_sqlite_la_LDFLAGS = \ 105libgnunet_plugin_reclaim_sqlite_la_LDFLAGS = \
@@ -126,6 +127,7 @@ libgnunetreclaim_la_SOURCES = \
126 reclaim.h 127 reclaim.h
127libgnunetreclaim_la_LIBADD = \ 128libgnunetreclaim_la_LIBADD = \
128 $(top_builddir)/src/util/libgnunetutil.la \ 129 $(top_builddir)/src/util/libgnunetutil.la \
130 $(top_builddir)/src/reclaim-attribute/libgnunetreclaimattribute.la \
129 $(GN_LIBINTL) $(XLIB) 131 $(GN_LIBINTL) $(XLIB)
130libgnunetreclaim_la_LDFLAGS = \ 132libgnunetreclaim_la_LDFLAGS = \
131 $(GN_LIB_LDFLAGS) $(WINFLAGS) \ 133 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
diff --git a/src/rps/gnunet-rps-profiler.c b/src/rps/gnunet-rps-profiler.c
index a852d94b1..a13ee4078 100644
--- a/src/rps/gnunet-rps-profiler.c
+++ b/src/rps/gnunet-rps-profiler.c
@@ -429,7 +429,7 @@ struct PendingReply
429 /** 429 /**
430 * Handle to the request we are waiting for 430 * Handle to the request we are waiting for
431 */ 431 */
432 struct GNUNET_RPS_Request_Handle *req_handle; 432 struct GNUNET_RPS_Request_Handle_Single_Info *req_handle;
433 433
434 /** 434 /**
435 * The peer that requested 435 * The peer that requested
@@ -1040,7 +1040,7 @@ cancel_request (struct PendingReply *pending_rep)
1040 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1040 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1041 "Cancelling rps get reply\n"); 1041 "Cancelling rps get reply\n");
1042 GNUNET_assert (NULL != pending_rep->req_handle); 1042 GNUNET_assert (NULL != pending_rep->req_handle);
1043 GNUNET_RPS_request_cancel (pending_rep->req_handle); 1043 GNUNET_RPS_request_single_info_cancel (pending_rep->req_handle);
1044 pending_rep->req_handle = NULL; 1044 pending_rep->req_handle = NULL;
1045 GNUNET_free (pending_rep); 1045 GNUNET_free (pending_rep);
1046 pending_rep = NULL; 1046 pending_rep = NULL;
@@ -1489,6 +1489,13 @@ default_reply_handle (void *cls,
1489 } 1489 }
1490} 1490}
1491 1491
1492
1493static void
1494profiler_reply_handle_info (void *cls,
1495 const struct GNUNET_PeerIdentity *recv_peer,
1496 double probability,
1497 uint32_t num_observed);
1498
1492/** 1499/**
1493 * Request random peers. 1500 * Request random peers.
1494 */ 1501 */
@@ -1510,9 +1517,12 @@ request_peers (void *cls)
1510 "Requesting one peer\n"); 1517 "Requesting one peer\n");
1511 pending_rep = GNUNET_new (struct PendingReply); 1518 pending_rep = GNUNET_new (struct PendingReply);
1512 pending_rep->rps_peer = rps_peer; 1519 pending_rep->rps_peer = rps_peer;
1513 pending_rep->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle, 1520 //pending_rep->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle,
1514 1, 1521 // 1,
1515 cur_test_run.reply_handle, 1522 // cur_test_run.reply_handle,
1523 // pending_rep);
1524 pending_rep->req_handle = GNUNET_RPS_request_peer_info (rps_peer->rps_handle,
1525 profiler_reply_handle_info,
1516 pending_rep); 1526 pending_rep);
1517 GNUNET_CONTAINER_DLL_insert_tail (rps_peer->pending_rep_head, 1527 GNUNET_CONTAINER_DLL_insert_tail (rps_peer->pending_rep_head,
1518 rps_peer->pending_rep_tail, 1528 rps_peer->pending_rep_tail,
@@ -1979,6 +1989,77 @@ profiler_reply_handle (void *cls,
1979} 1989}
1980 1990
1981 1991
1992/**
1993 * Callback to call on receipt of a reply
1994 *
1995 * @param cls closure
1996 * @param n number of peers
1997 * @param recv_peers the received peers
1998 */
1999static void
2000profiler_reply_handle_info (void *cls,
2001 const struct GNUNET_PeerIdentity *recv_peer,
2002 double probability,
2003 uint32_t num_observed)
2004{
2005 struct RPSPeer *rps_peer;
2006 struct RPSPeer *rcv_rps_peer;
2007 char file_name_buf[128];
2008 char file_name_dh_buf[128];
2009 char file_name_dhr_buf[128];
2010 char file_name_dhru_buf[128];
2011 char *file_name = file_name_buf;
2012 char *file_name_dh = file_name_dh_buf;
2013 char *file_name_dhr = file_name_dhr_buf;
2014 char *file_name_dhru = file_name_dhru_buf;
2015 unsigned int i;
2016 struct PendingReply *pending_rep = (struct PendingReply *) cls;
2017
2018 pending_rep->req_handle = NULL;
2019 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
2020 rps_peer = pending_rep->rps_peer;
2021 (void) GNUNET_asprintf (&file_name,
2022 "/tmp/rps/received_ids-%u",
2023 rps_peer->index);
2024
2025 (void) GNUNET_asprintf (&file_name_dh,
2026 "/tmp/rps/diehard_input-%u",
2027 rps_peer->index);
2028 (void) GNUNET_asprintf (&file_name_dhr,
2029 "/tmp/rps/diehard_input_raw-%u",
2030 rps_peer->index);
2031 (void) GNUNET_asprintf (&file_name_dhru,
2032 "/tmp/rps/diehard_input_raw_aligned-%u",
2033 rps_peer->index);
2034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2035 "[%s] got peer with info:\n",
2036 GNUNET_i2s (rps_peer->peer_id));
2037 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2038 " %s\n",
2039 GNUNET_i2s (recv_peer));
2040 tofile (file_name,
2041 "%s %d %" PRIu32 " \n",
2042 GNUNET_i2s_full (recv_peer),
2043 probability,
2044 num_observed);
2045 rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, recv_peer);
2046 GNUNET_assert (NULL != rcv_rps_peer);
2047 tofile (file_name_dh,
2048 "%" PRIu32 "\n",
2049 (uint32_t) rcv_rps_peer->index);
2050#ifdef TO_FILE
2051 to_file_raw (file_name_dhr,
2052 (char *) &rcv_rps_peer->index,
2053 sizeof (uint32_t));
2054 to_file_raw_unaligned (file_name_dhru,
2055 (char *) &rcv_rps_peer->index,
2056 sizeof (uint32_t),
2057 bits_needed);
2058#endif /* TO_FILE */
2059 default_reply_handle (cls, 1, recv_peer);
2060}
2061
2062
1982static void 2063static void
1983profiler_cb (struct RPSPeer *rps_peer) 2064profiler_cb (struct RPSPeer *rps_peer)
1984{ 2065{
@@ -2141,7 +2222,7 @@ static void compute_probabilities (uint32_t peer_idx)
2141{ 2222{
2142 //double probs[num_peers] = { 0 }; 2223 //double probs[num_peers] = { 0 };
2143 double probs[num_peers]; 2224 double probs[num_peers];
2144 size_t probs_as_str_size = (num_peers * 10 + 1) * sizeof (char); 2225 size_t probs_as_str_size = (num_peers * 10 + 2) * sizeof (char);
2145 char *probs_as_str = GNUNET_malloc (probs_as_str_size); 2226 char *probs_as_str = GNUNET_malloc (probs_as_str_size);
2146 char *probs_as_str_cpy; 2227 char *probs_as_str_cpy;
2147 uint32_t i; 2228 uint32_t i;
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index f6fe17589..e929c89de 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -2602,6 +2602,13 @@ insert_in_sampler (void *cls,
2602 * messages to it */ 2602 * messages to it */
2603 //indicate_sending_intention (peer); 2603 //indicate_sending_intention (peer);
2604 } 2604 }
2605 if (sub == msub)
2606 {
2607 GNUNET_STATISTICS_update (stats,
2608 "# observed peers in gossip",
2609 1,
2610 GNUNET_NO);
2611 }
2605#ifdef TO_FILE 2612#ifdef TO_FILE
2606 sub->num_observed_peers++; 2613 sub->num_observed_peers++;
2607 GNUNET_CONTAINER_multipeermap_put 2614 GNUNET_CONTAINER_multipeermap_put
@@ -2611,6 +2618,10 @@ insert_in_sampler (void *cls,
2611 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 2618 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2612 uint32_t num_observed_unique_peers = 2619 uint32_t num_observed_unique_peers =
2613 GNUNET_CONTAINER_multipeermap_size (sub->observed_unique_peers); 2620 GNUNET_CONTAINER_multipeermap_size (sub->observed_unique_peers);
2621 GNUNET_STATISTICS_set (stats,
2622 "# unique peers in gossip",
2623 num_observed_unique_peers,
2624 GNUNET_NO);
2614#ifdef TO_FILE_FULL 2625#ifdef TO_FILE_FULL
2615 to_file (sub->file_name_observed_log, 2626 to_file (sub->file_name_observed_log,
2616 "%" PRIu32 " %" PRIu32 " %f\n", 2627 "%" PRIu32 " %" PRIu32 " %f\n",
diff --git a/src/rps/gnunet-service-rps_sampler.c b/src/rps/gnunet-service-rps_sampler.c
index a95ac82d4..e17b154ca 100644
--- a/src/rps/gnunet-service-rps_sampler.c
+++ b/src/rps/gnunet-service-rps_sampler.c
@@ -257,7 +257,7 @@ sampler_get_rand_peer (void *cls)
257 gpc->req_handle->gpc_tail, 257 gpc->req_handle->gpc_tail,
258 gpc); 258 gpc);
259 *gpc->id = sampler->sampler_elements[r_index]->peer_id; 259 *gpc->id = sampler->sampler_elements[r_index]->peer_id;
260 gpc->cont (gpc->cont_cls, gpc->id); 260 gpc->cont (gpc->cont_cls, gpc->id, 0, sampler->sampler_elements[r_index]->num_peers);
261 261
262 GNUNET_free (gpc); 262 GNUNET_free (gpc);
263} 263}
diff --git a/src/rps/rps-sampler_client.c b/src/rps/rps-sampler_client.c
index 0de25df07..20cd9d0c4 100644
--- a/src/rps/rps-sampler_client.c
+++ b/src/rps/rps-sampler_client.c
@@ -158,6 +158,46 @@ struct RPS_SamplerRequestHandle
158 void *cls; 158 void *cls;
159}; 159};
160 160
161
162/**
163 * Closure to _get_rand_peer_info()
164 */
165struct RPS_SamplerRequestHandleSingleInfo
166{
167 /**
168 * DLL
169 */
170 struct RPS_SamplerRequestHandleSingleInfo *next;
171 struct RPS_SamplerRequestHandleSingleInfo *prev;
172
173 /**
174 * Pointer to the id
175 */
176 struct GNUNET_PeerIdentity *id;
177
178 /**
179 * Head and tail for the DLL to store the tasks for single requests
180 */
181 struct GetPeerCls *gpc_head;
182 struct GetPeerCls *gpc_tail;
183
184 /**
185 * Sampler.
186 */
187 struct RPS_Sampler *sampler;
188
189 /**
190 * Callback to be called when all ids are available.
191 */
192 RPS_sampler_sinlge_info_ready_cb callback;
193
194 /**
195 * Closure given to the callback
196 */
197 void *cls;
198};
199
200
161///** 201///**
162// * Global sampler variable. 202// * Global sampler variable.
163// */ 203// */
@@ -266,10 +306,16 @@ sampler_mod_get_rand_peer (void *cls)
266 struct GNUNET_TIME_Relative last_request_diff; 306 struct GNUNET_TIME_Relative last_request_diff;
267 struct RPS_Sampler *sampler; 307 struct RPS_Sampler *sampler;
268 double prob_observed_n; 308 double prob_observed_n;
309 uint32_t num_observed;
269 310
270 gpc->get_peer_task = NULL; 311 gpc->get_peer_task = NULL;
271 gpc->notify_ctx = NULL; 312 gpc->notify_ctx = NULL;
272 sampler = gpc->req_handle->sampler; 313 GNUNET_assert ( (NULL != gpc->req_handle) ||
314 (NULL != gpc->req_single_info_handle) );
315 if (NULL != gpc->req_handle)
316 sampler = gpc->req_handle->sampler;
317 else
318 sampler = gpc->req_single_info_handle->sampler;
273 319
274 LOG (GNUNET_ERROR_TYPE_DEBUG, "Single peer was requested\n"); 320 LOG (GNUNET_ERROR_TYPE_DEBUG, "Single peer was requested\n");
275 321
@@ -335,10 +381,10 @@ sampler_mod_get_rand_peer (void *cls)
335 s_elem->num_peers, 381 s_elem->num_peers,
336 sampler->deficiency_factor); 382 sampler->deficiency_factor);
337 /* check if probability is above desired */ 383 /* check if probability is above desired */
338 if (prob_observed_n >= sampler->desired_probability) 384 if (prob_observed_n < sampler->desired_probability)
339 { 385 {
340 LOG (GNUNET_ERROR_TYPE_DEBUG, 386 LOG (GNUNET_ERROR_TYPE_DEBUG,
341 "Probability of having observed all peers (%d) too small ( < %d).\n", 387 "Probability of having observed all peers (%f) too small ( < %f).\n",
342 prob_observed_n, 388 prob_observed_n,
343 sampler->desired_probability); 389 sampler->desired_probability);
344 GNUNET_assert (NULL == gpc->notify_ctx); 390 GNUNET_assert (NULL == gpc->notify_ctx);
@@ -359,13 +405,23 @@ sampler_mod_get_rand_peer (void *cls)
359// s_elem->num_change, 405// s_elem->num_change,
360// GNUNET_NO); 406// GNUNET_NO);
361 407
408 num_observed = s_elem->num_peers;
362 RPS_sampler_elem_reinit (s_elem); 409 RPS_sampler_elem_reinit (s_elem);
363 s_elem->last_client_request = GNUNET_TIME_absolute_get (); 410 s_elem->last_client_request = GNUNET_TIME_absolute_get ();
364 411
365 GNUNET_CONTAINER_DLL_remove (gpc->req_handle->gpc_head, 412 if (NULL != gpc->req_handle)
366 gpc->req_handle->gpc_tail, 413 {
367 gpc); 414 GNUNET_CONTAINER_DLL_remove (gpc->req_handle->gpc_head,
368 gpc->cont (gpc->cont_cls, gpc->id); 415 gpc->req_handle->gpc_tail,
416 gpc);
417 }
418 else
419 {
420 GNUNET_CONTAINER_DLL_remove (gpc->req_single_info_handle->gpc_head,
421 gpc->req_single_info_handle->gpc_tail,
422 gpc);
423 }
424 gpc->cont (gpc->cont_cls, gpc->id, prob_observed_n, num_observed);
369 GNUNET_free (gpc); 425 GNUNET_free (gpc);
370} 426}
371 427
diff --git a/src/rps/rps-sampler_client.h b/src/rps/rps-sampler_client.h
index 1b425b754..680fabfda 100644
--- a/src/rps/rps-sampler_client.h
+++ b/src/rps/rps-sampler_client.h
@@ -40,6 +40,11 @@ struct RPS_Sampler;
40 */ 40 */
41struct RPS_SamplerRequestHandle; 41struct RPS_SamplerRequestHandle;
42 42
43/**
44 * Closure to _get_rand_peer_info()
45 */
46struct RPS_SamplerRequestHandleSingleInfo;
47
43 48
44/** 49/**
45 * Get the size of the sampler. 50 * Get the size of the sampler.
@@ -108,8 +113,6 @@ RPS_sampler_reinitialise_by_value (struct RPS_Sampler *sampler,
108 * @param sampler the sampler to get peers from. 113 * @param sampler the sampler to get peers from.
109 * @param cb callback that will be called once the ids are ready. 114 * @param cb callback that will be called once the ids are ready.
110 * @param cls closure given to @a cb 115 * @param cls closure given to @a cb
111 * @param for_client #GNUNET_YES if result is used for client,
112 * #GNUNET_NO if used internally
113 * @param num_peers the number of peers requested 116 * @param num_peers the number of peers requested
114 */ 117 */
115struct RPS_SamplerRequestHandle * 118struct RPS_SamplerRequestHandle *
@@ -118,6 +121,7 @@ RPS_sampler_get_n_rand_peers (struct RPS_Sampler *sampler,
118 RPS_sampler_n_rand_peers_ready_cb cb, 121 RPS_sampler_n_rand_peers_ready_cb cb,
119 void *cls); 122 void *cls);
120 123
124
121/** 125/**
122 * Cancle a request issued through #RPS_sampler_n_rand_peers_ready_cb. 126 * Cancle a request issued through #RPS_sampler_n_rand_peers_ready_cb.
123 * 127 *
diff --git a/src/rps/rps-sampler_common.c b/src/rps/rps-sampler_common.c
index f54de9014..adb69e1b5 100644
--- a/src/rps/rps-sampler_common.c
+++ b/src/rps/rps-sampler_common.c
@@ -116,6 +116,45 @@ struct RPS_SamplerRequestHandle
116 116
117 117
118/** 118/**
119 * Closure to _get_rand_peer_info()
120 */
121struct RPS_SamplerRequestHandleSingleInfo
122{
123 /**
124 * DLL
125 */
126 struct RPS_SamplerRequestHandleSingleInfo *next;
127 struct RPS_SamplerRequestHandleSingleInfo *prev;
128
129 /**
130 * Pointer to the id
131 */
132 struct GNUNET_PeerIdentity *id;
133
134 /**
135 * Head and tail for the DLL to store the tasks for single requests
136 */
137 struct GetPeerCls *gpc_head;
138 struct GetPeerCls *gpc_tail;
139
140 /**
141 * Sampler.
142 */
143 struct RPS_Sampler *sampler;
144
145 /**
146 * Callback to be called when all ids are available.
147 */
148 RPS_sampler_sinlge_info_ready_cb callback;
149
150 /**
151 * Closure given to the callback
152 */
153 void *cls;
154};
155
156
157/**
119 * @brief Update the current estimate of the network size stored at the sampler 158 * @brief Update the current estimate of the network size stored at the sampler
120 * 159 *
121 * Used for computing the condition when to return elements to the client 160 * Used for computing the condition when to return elements to the client
@@ -415,12 +454,20 @@ sampler_empty (struct RPS_Sampler *sampler)
415/** 454/**
416 * Callback to _get_rand_peer() used by _get_n_rand_peers(). 455 * Callback to _get_rand_peer() used by _get_n_rand_peers().
417 * 456 *
457 * Implements #RPS_sampler_rand_peer_ready_cont
458 *
418 * Checks whether all n peers are available. If they are, 459 * Checks whether all n peers are available. If they are,
419 * give those back. 460 * give those back.
461 * @param cls Closure
462 * @param id Peer ID
463 * @param probability The probability with which this sampler has seen all ids
464 * @param num_observed How many ids this sampler has observed
420 */ 465 */
421static void 466static void
422check_n_peers_ready (void *cls, 467check_n_peers_ready (void *cls,
423 const struct GNUNET_PeerIdentity *id) 468 const struct GNUNET_PeerIdentity *id,
469 double probability,
470 uint32_t num_observed)
424{ 471{
425 struct RPS_SamplerRequestHandle *req_handle = cls; 472 struct RPS_SamplerRequestHandle *req_handle = cls;
426 (void) id; 473 (void) id;
@@ -428,6 +475,8 @@ check_n_peers_ready (void *cls,
428 struct GNUNET_PeerIdentity *peers; 475 struct GNUNET_PeerIdentity *peers;
429 uint32_t num_peers; 476 uint32_t num_peers;
430 void *cb_cls; 477 void *cb_cls;
478 (void) probability;
479 (void) num_observed;
431 480
432 req_handle->cur_num_peers++; 481 req_handle->cur_num_peers++;
433 LOG (GNUNET_ERROR_TYPE_DEBUG, 482 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -460,6 +509,53 @@ check_n_peers_ready (void *cls,
460 509
461 510
462/** 511/**
512 * Callback to _get_rand_peer() used by _get_rand_peer_info().
513 *
514 * Implements #RPS_sampler_rand_peer_ready_cont
515 *
516 * @param cls Closure
517 * @param id Peer ID
518 * @param probability The probability with which this sampler has seen all ids
519 * @param num_observed How many ids this sampler has observed
520 */
521static void
522check_peer_info_ready (void *cls,
523 const struct GNUNET_PeerIdentity *id,
524 double probability,
525 uint32_t num_observed)
526{
527 struct RPS_SamplerRequestHandleSingleInfo *req_handle = cls;
528 (void) id;
529 RPS_sampler_sinlge_info_ready_cb tmp_cb;
530 struct GNUNET_PeerIdentity *peer;
531 void *cb_cls;
532 (void) probability;
533 (void) num_observed;
534
535 LOG (GNUNET_ERROR_TYPE_DEBUG,
536 "Got single peer with additional info\n");
537
538 GNUNET_assert (NULL != req_handle->callback);
539
540 LOG (GNUNET_ERROR_TYPE_DEBUG,
541 "returning single peer with info to the client\n");
542
543 /* Copy pointers and peers temporarily as they
544 * might be deleted from within the callback */
545 tmp_cb = req_handle->callback;
546 peer = GNUNET_new (struct GNUNET_PeerIdentity);
547 GNUNET_memcpy (peer,
548 req_handle->id,
549 sizeof (struct GNUNET_PeerIdentity));
550 cb_cls = req_handle->cls;
551 RPS_sampler_request_single_info_cancel (req_handle);
552 req_handle = NULL;
553 tmp_cb (peer, cb_cls, probability, num_observed);
554 GNUNET_free (peer);
555}
556
557
558/**
463 * Get n random peers out of the sampled peers. 559 * Get n random peers out of the sampled peers.
464 * 560 *
465 * We might want to reinitialise this sampler after giving the 561 * We might want to reinitialise this sampler after giving the
@@ -469,8 +565,6 @@ check_n_peers_ready (void *cls,
469 * @param sampler the sampler to get peers from. 565 * @param sampler the sampler to get peers from.
470 * @param cb callback that will be called once the ids are ready. 566 * @param cb callback that will be called once the ids are ready.
471 * @param cls closure given to @a cb 567 * @param cls closure given to @a cb
472 * @param for_client #GNUNET_YES if result is used for client,
473 * #GNUNET_NO if used internally
474 * @param num_peers the number of peers requested 568 * @param num_peers the number of peers requested
475 */ 569 */
476struct RPS_SamplerRequestHandle * 570struct RPS_SamplerRequestHandle *
@@ -506,6 +600,7 @@ RPS_sampler_get_n_rand_peers (struct RPS_Sampler *sampler,
506 { 600 {
507 gpc = GNUNET_new (struct GetPeerCls); 601 gpc = GNUNET_new (struct GetPeerCls);
508 gpc->req_handle = req_handle; 602 gpc->req_handle = req_handle;
603 gpc->req_single_info_handle = NULL;
509 gpc->cont = check_n_peers_ready; 604 gpc->cont = check_n_peers_ready;
510 gpc->cont_cls = req_handle; 605 gpc->cont_cls = req_handle;
511 gpc->id = &req_handle->ids[i]; 606 gpc->id = &req_handle->ids[i];
@@ -515,11 +610,56 @@ RPS_sampler_get_n_rand_peers (struct RPS_Sampler *sampler,
515 gpc); 610 gpc);
516 // maybe add a little delay 611 // maybe add a little delay
517 gpc->get_peer_task = GNUNET_SCHEDULER_add_now (sampler->get_peers, 612 gpc->get_peer_task = GNUNET_SCHEDULER_add_now (sampler->get_peers,
518 gpc); 613 gpc);
519 } 614 }
520 return req_handle; 615 return req_handle;
521} 616}
522 617
618
619/**
620 * Get one random peer with additional information.
621 *
622 * @param sampler the sampler to get peers from.
623 * @param cb callback that will be called once the ids are ready.
624 * @param cls closure given to @a cb
625 */
626struct RPS_SamplerRequestHandleSingleInfo *
627RPS_sampler_get_rand_peer_info (struct RPS_Sampler *sampler,
628 RPS_sampler_sinlge_info_ready_cb cb,
629 void *cls)
630{
631 struct RPS_SamplerRequestHandleSingleInfo *req_handle;
632 struct GetPeerCls *gpc;
633
634 GNUNET_assert (0 != sampler->sampler_size);
635
636 // TODO check if we have too much (distinct) sampled peers
637 req_handle = GNUNET_new (struct RPS_SamplerRequestHandleSingleInfo);
638 req_handle->id = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
639 req_handle->sampler = sampler;
640 req_handle->callback = cb;
641 req_handle->cls = cls;
642 GNUNET_CONTAINER_DLL_insert (sampler->req_handle_single_head,
643 sampler->req_handle_single_tail,
644 req_handle);
645
646 gpc = GNUNET_new (struct GetPeerCls);
647 gpc->req_handle = NULL;
648 gpc->req_single_info_handle = req_handle;
649 gpc->cont = check_peer_info_ready;
650 gpc->cont_cls = req_handle;
651 gpc->id = req_handle->id;
652
653 GNUNET_CONTAINER_DLL_insert (req_handle->gpc_head,
654 req_handle->gpc_tail,
655 gpc);
656 // maybe add a little delay
657 gpc->get_peer_task = GNUNET_SCHEDULER_add_now (sampler->get_peers,
658 gpc);
659 return req_handle;
660}
661
662
523/** 663/**
524 * Cancle a request issued through #RPS_sampler_n_rand_peers_ready_cb. 664 * Cancle a request issued through #RPS_sampler_n_rand_peers_ready_cb.
525 * 665 *
@@ -559,6 +699,45 @@ RPS_sampler_request_cancel (struct RPS_SamplerRequestHandle *req_handle)
559 699
560 700
561/** 701/**
702 * Cancle a request issued through #RPS_sampler_sinlge_info_ready_cb.
703 *
704 * @param req_handle the handle to the request
705 */
706void
707RPS_sampler_request_single_info_cancel (
708 struct RPS_SamplerRequestHandleSingleInfo *req_single_info_handle)
709{
710 struct GetPeerCls *i;
711
712 while (NULL != (i = req_single_info_handle->gpc_head) )
713 {
714 GNUNET_CONTAINER_DLL_remove (req_single_info_handle->gpc_head,
715 req_single_info_handle->gpc_tail,
716 i);
717 if (NULL != i->get_peer_task)
718 {
719 GNUNET_SCHEDULER_cancel (i->get_peer_task);
720 }
721 if (NULL != i->notify_ctx)
722 {
723 GNUNET_CONTAINER_DLL_remove (req_single_info_handle->sampler->notify_ctx_head,
724 req_single_info_handle->sampler->notify_ctx_tail,
725 i->notify_ctx);
726 GNUNET_free (i->notify_ctx);
727 i->notify_ctx = NULL;
728 }
729 GNUNET_free (i);
730 }
731 GNUNET_free (req_single_info_handle->id);
732 req_single_info_handle->id = NULL;
733 GNUNET_CONTAINER_DLL_remove (req_single_info_handle->sampler->req_handle_single_head,
734 req_single_info_handle->sampler->req_handle_single_tail,
735 req_single_info_handle);
736 GNUNET_free (req_single_info_handle);
737}
738
739
740/**
562 * Cleans the sampler. 741 * Cleans the sampler.
563 */ 742 */
564 void 743 void
diff --git a/src/rps/rps-sampler_common.h b/src/rps/rps-sampler_common.h
index 1abe43720..321efaf1e 100644
--- a/src/rps/rps-sampler_common.h
+++ b/src/rps/rps-sampler_common.h
@@ -44,10 +44,14 @@
44 * 44 *
45 * @param cls the closure given alongside this function. 45 * @param cls the closure given alongside this function.
46 * @param id the PeerID that was returned 46 * @param id the PeerID that was returned
47 * @param probability The probability with which this sampler has seen all ids
48 * @param num_observed How many ids this sampler has observed
47 */ 49 */
48typedef void 50typedef void
49(*RPS_sampler_rand_peer_ready_cont) (void *cls, 51(*RPS_sampler_rand_peer_ready_cont) (void *cls,
50 const struct GNUNET_PeerIdentity *id); 52 const struct GNUNET_PeerIdentity *id,
53 double probability,
54 uint32_t num_observed);
51 55
52 56
53/** 57/**
@@ -72,6 +76,22 @@ typedef void
72 76
73 77
74/** 78/**
79 * Callback that is called from _get_n_rand_peers() when the PeerIDs are ready.
80 *
81 * @param cls the closure given alongside this function.
82 * @param probability Probability with which all IDs have been observed
83 * @param num_observed Number of observed IDs
84 * @param ids the PeerIDs that were returned
85 * to be freed
86 */
87 typedef void
88(*RPS_sampler_sinlge_info_ready_cb) (const struct GNUNET_PeerIdentity *ids,
89 void *cls,
90 double probability,
91 uint32_t num_observed);
92
93
94/**
75 * @brief Callback called each time a new peer was put into the sampler 95 * @brief Callback called each time a new peer was put into the sampler
76 * 96 *
77 * @param cls A possibly given closure 97 * @param cls A possibly given closure
@@ -97,6 +117,11 @@ struct GetPeerCls
97 struct RPS_SamplerRequestHandle *req_handle; 117 struct RPS_SamplerRequestHandle *req_handle;
98 118
99 /** 119 /**
120 * The #RPS_SamplerRequestHandleSingleInfo this single request belongs to.
121 */
122 struct RPS_SamplerRequestHandleSingleInfo *req_single_info_handle;
123
124 /**
100 * The task for this function. 125 * The task for this function.
101 */ 126 */
102 struct GNUNET_SCHEDULER_Task *get_peer_task; 127 struct GNUNET_SCHEDULER_Task *get_peer_task;
@@ -177,6 +202,12 @@ struct RPS_Sampler
177 struct RPS_SamplerRequestHandle *req_handle_head; 202 struct RPS_SamplerRequestHandle *req_handle_head;
178 struct RPS_SamplerRequestHandle *req_handle_tail; 203 struct RPS_SamplerRequestHandle *req_handle_tail;
179 204
205 /**
206 * Head and tail for the DLL to store the #RPS_SamplerRequestHandleSingleInfo
207 */
208 struct RPS_SamplerRequestHandleSingleInfo *req_handle_single_head;
209 struct RPS_SamplerRequestHandleSingleInfo *req_handle_single_tail;
210
180 struct SamplerNotifyUpdateCTX *notify_ctx_head; 211 struct SamplerNotifyUpdateCTX *notify_ctx_head;
181 struct SamplerNotifyUpdateCTX *notify_ctx_tail; 212 struct SamplerNotifyUpdateCTX *notify_ctx_tail;
182}; 213};
@@ -306,6 +337,19 @@ RPS_sampler_get_n_rand_peers (struct RPS_Sampler *sampler,
306 337
307 338
308/** 339/**
340 * Get one random peer with additional information.
341 *
342 * @param sampler the sampler to get peers from.
343 * @param cb callback that will be called once the ids are ready.
344 * @param cls closure given to @a cb
345 */
346struct RPS_SamplerRequestHandleSingleInfo *
347RPS_sampler_get_rand_peer_info (struct RPS_Sampler *sampler,
348 RPS_sampler_sinlge_info_ready_cb cb,
349 void *cls);
350
351
352/**
309 * Counts how many Samplers currently hold a given PeerID. 353 * Counts how many Samplers currently hold a given PeerID.
310 * 354 *
311 * @param sampler the sampler to count ids in. 355 * @param sampler the sampler to count ids in.
@@ -328,6 +372,16 @@ RPS_sampler_request_cancel (struct RPS_SamplerRequestHandle *req_handle);
328 372
329 373
330/** 374/**
375 * Cancle a request issued through #RPS_sampler_n_rand_peers_ready_cb.
376 *
377 * @param req_handle the handle to the request
378 */
379void
380RPS_sampler_request_single_info_cancel (
381 struct RPS_SamplerRequestHandleSingleInfo *req_single_info_handle);
382
383
384/**
331 * Cleans the sampler. 385 * Cleans the sampler.
332 */ 386 */
333 void 387 void
diff --git a/src/rps/rps-test_util.h b/src/rps/rps-test_util.h
index 6b5f568d7..d5a2db9de 100644
--- a/src/rps/rps-test_util.h
+++ b/src/rps/rps-test_util.h
@@ -68,12 +68,15 @@ close_all_files ();
68 if (NULL == file_name) break; \ 68 if (NULL == file_name) break; \
69 size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\ 69 size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\
70 if (0 > size)\ 70 if (0 > size)\
71 {\
71 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\ 72 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\
72 "Failed to create tmp_buf\n");\ 73 "Failed to create tmp_buf\n");\
73 else\ 74 break;\
74 GNUNET_DISK_file_write (get_file_handle (file_name),\ 75 }\
75 tmp_buf,\ 76 (void) strncat(tmp_buf,"\n",512);\
76 strnlen (tmp_buf, 512));\ 77 GNUNET_DISK_file_write (get_file_handle (file_name),\
78 tmp_buf,\
79 strnlen (tmp_buf, 512));\
77 } while (0); 80 } while (0);
78 81
79 82
@@ -82,12 +85,15 @@ close_all_files ();
82 memset (tmp_buf, 0, len);\ 85 memset (tmp_buf, 0, len);\
83 size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\ 86 size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\
84 if (0 > size)\ 87 if (0 > size)\
88 {\
85 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\ 89 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\
86 "Failed to create tmp_buf\n");\ 90 "Failed to create tmp_buf\n");\
87 else\ 91 break;\
88 GNUNET_DISK_file_write (get_file_handle (file_name),\ 92 }\
89 tmp_buf,\ 93 (void) strncat(tmp_buf,"\n",len);\
90 strnlen (tmp_buf, 512));\ 94 GNUNET_DISK_file_write (get_file_handle (file_name),\
95 tmp_buf,\
96 strnlen (tmp_buf, len));\
91 } while (0); 97 } while (0);
92#else /* TO_FILE */ 98#else /* TO_FILE */
93# define to_file(file_name, ...) 99# define to_file(file_name, ...)
diff --git a/src/rps/rps_api.c b/src/rps/rps_api.c
index 7a3adfa94..9e405fdef 100644
--- a/src/rps/rps_api.c
+++ b/src/rps/rps_api.c
@@ -128,6 +128,16 @@ struct GNUNET_RPS_Handle
128 struct GNUNET_RPS_Request_Handle *rh_tail; 128 struct GNUNET_RPS_Request_Handle *rh_tail;
129 129
130 /** 130 /**
131 * @brief Pointer to the head element in DLL of single request handles
132 */
133 struct GNUNET_RPS_Request_Handle_Single_Info *rhs_head;
134
135 /**
136 * @brief Pointer to the tail element in DLL of single request handles
137 */
138 struct GNUNET_RPS_Request_Handle_Single_Info *rhs_tail;
139
140 /**
131 * @brief The desired probability with which we want to have observed all 141 * @brief The desired probability with which we want to have observed all
132 * peers. 142 * peers.
133 */ 143 */
@@ -197,6 +207,54 @@ struct GNUNET_RPS_Request_Handle
197 207
198 208
199/** 209/**
210 * Handler for a single request from a client.
211 */
212struct GNUNET_RPS_Request_Handle_Single_Info
213{
214 /**
215 * The client issuing the request.
216 */
217 struct GNUNET_RPS_Handle *rps_handle;
218
219 /**
220 * @brief The Sampler for the client request
221 */
222 struct RPS_Sampler *sampler;
223
224 /**
225 * @brief Request handle of the request to the sampler - needed to cancel the request
226 */
227 struct RPS_SamplerRequestHandleSingleInfo *sampler_rh;
228
229 /**
230 * @brief Request handle of the request of the biased stream of peers -
231 * needed to cancel the request
232 */
233 struct GNUNET_RPS_StreamRequestHandle *srh;
234
235 /**
236 * The callback to be called when we receive an answer.
237 */
238 GNUNET_RPS_NotifyReadySingleInfoCB ready_cb;
239
240 /**
241 * The closure for the callback.
242 */
243 void *ready_cb_cls;
244
245 /**
246 * @brief Pointer to next element in DLL
247 */
248 struct GNUNET_RPS_Request_Handle_Single_Info *next;
249
250 /**
251 * @brief Pointer to previous element in DLL
252 */
253 struct GNUNET_RPS_Request_Handle_Single_Info *prev;
254};
255
256
257/**
200 * Struct used to pack the callback, its closure (provided by the caller) 258 * Struct used to pack the callback, its closure (provided by the caller)
201 * and the connection handler to the service to pass it to a callback function. 259 * and the connection handler to the service to pass it to a callback function.
202 */ 260 */
@@ -309,6 +367,34 @@ peers_ready_cb (const struct GNUNET_PeerIdentity *peers,
309 367
310 368
311/** 369/**
370 * @brief Called once the sampler has collected the requested peer.
371 *
372 * Calls the callback provided by the client with the corresponding cls.
373 *
374 * @param peers The array of @a num_peers that has been returned.
375 * @param num_peers The number of peers that have been returned
376 * @param cls The #GNUNET_RPS_Request_Handle
377 * @param probability Probability with which all IDs have been observed
378 * @param num_observed Number of observed IDs
379 */
380static void
381peer_info_ready_cb (const struct GNUNET_PeerIdentity *peers,
382 void *cls,
383 double probability,
384 uint32_t num_observed)
385{
386 struct GNUNET_RPS_Request_Handle_Single_Info *rh = cls;
387
388 rh->sampler_rh = NULL;
389 rh->ready_cb (rh->ready_cb_cls,
390 peers,
391 probability,
392 num_observed);
393 GNUNET_RPS_request_single_info_cancel (rh);
394}
395
396
397/**
312 * @brief Callback to collect the peers from the biased stream and put those 398 * @brief Callback to collect the peers from the biased stream and put those
313 * into the sampler. 399 * into the sampler.
314 * 400 *
@@ -333,6 +419,33 @@ collect_peers_cb (void *cls,
333} 419}
334 420
335 421
422/**
423 * @brief Callback to collect the peers from the biased stream and put those
424 * into the sampler.
425 *
426 * This version is for the modified #GNUNET_RPS_Request_Handle_Single_Info
427 *
428 * @param cls The #GNUNET_RPS_Request_Handle
429 * @param num_peers The number of peer that have been returned
430 * @param peers The array of @a num_peers that have been returned
431 */
432static void
433collect_peers_info_cb (void *cls,
434 uint64_t num_peers,
435 const struct GNUNET_PeerIdentity *peers)
436{
437 struct GNUNET_RPS_Request_Handle_Single_Info *rhs = cls;
438
439 LOG (GNUNET_ERROR_TYPE_DEBUG,
440 "Service sent %" PRIu64 " peers from stream\n",
441 num_peers);
442 for (uint64_t i = 0; i < num_peers; i++)
443 {
444 RPS_sampler_update (rhs->sampler, &peers[i]);
445 }
446}
447
448
336/* Get internals for debugging/profiling purposes */ 449/* Get internals for debugging/profiling purposes */
337 450
338/** 451/**
@@ -632,15 +745,15 @@ mq_error_handler (void *cls,
632 */ 745 */
633static void 746static void
634hash_from_share_val (const char *share_val, 747hash_from_share_val (const char *share_val,
635 struct GNUNET_HashCode *hash) 748 struct GNUNET_HashCode *hash)
636{ 749{
637 GNUNET_CRYPTO_kdf (hash, 750 GNUNET_CRYPTO_kdf (hash,
638 sizeof (struct GNUNET_HashCode), 751 sizeof (struct GNUNET_HashCode),
639 "rps", 752 "rps",
640 strlen ("rps"), 753 strlen ("rps"),
641 share_val, 754 share_val,
642 strlen (share_val), 755 strlen (share_val),
643 NULL, 0); 756 NULL, 0);
644} 757}
645 758
646 759
@@ -672,6 +785,13 @@ nse_cb (void *cls,
672 RPS_sampler_update_with_nw_size (rh_iter->sampler, 785 RPS_sampler_update_with_nw_size (rh_iter->sampler,
673 GNUNET_NSE_log_estimate_to_n (logestimate)); 786 GNUNET_NSE_log_estimate_to_n (logestimate));
674 } 787 }
788 for (struct GNUNET_RPS_Request_Handle_Single_Info *rhs_iter = h->rhs_head;
789 NULL != rhs_iter && NULL != rhs_iter->next;
790 rhs_iter = rhs_iter->next)
791 {
792 RPS_sampler_update_with_nw_size (rhs_iter->sampler,
793 GNUNET_NSE_log_estimate_to_n (logestimate));
794 }
675} 795}
676 796
677 797
@@ -857,6 +977,48 @@ GNUNET_RPS_request_peers (struct GNUNET_RPS_Handle *rps_handle,
857 977
858 978
859/** 979/**
980 * Request one random peer, getting additional information.
981 *
982 * @param rps_handle handle to the rps service
983 * @param ready_cb the callback called when the peers are available
984 * @param cls closure given to the callback
985 * @return a handle to cancel this request
986 */
987struct GNUNET_RPS_Request_Handle_Single_Info *
988GNUNET_RPS_request_peer_info (struct GNUNET_RPS_Handle *rps_handle,
989 GNUNET_RPS_NotifyReadySingleInfoCB ready_cb,
990 void *cls)
991{
992 struct GNUNET_RPS_Request_Handle_Single_Info *rhs;
993 uint32_t num_req_peers = 1;
994
995 LOG (GNUNET_ERROR_TYPE_INFO,
996 "Client requested peer with additional info\n");
997 rhs = GNUNET_new (struct GNUNET_RPS_Request_Handle_Single_Info);
998 rhs->rps_handle = rps_handle;
999 rhs->sampler = RPS_sampler_mod_init (num_req_peers,
1000 GNUNET_TIME_UNIT_SECONDS); // TODO remove this time-stuff
1001 RPS_sampler_set_desired_probability (rhs->sampler,
1002 rps_handle->desired_probability);
1003 RPS_sampler_set_deficiency_factor (rhs->sampler,
1004 rps_handle->deficiency_factor);
1005 rhs->sampler_rh = RPS_sampler_get_rand_peer_info (rhs->sampler,
1006 peer_info_ready_cb,
1007 rhs);
1008 rhs->srh = GNUNET_RPS_stream_request (rps_handle,
1009 collect_peers_info_cb,
1010 rhs); /* cls */
1011 rhs->ready_cb = ready_cb;
1012 rhs->ready_cb_cls = cls;
1013 GNUNET_CONTAINER_DLL_insert (rps_handle->rhs_head,
1014 rps_handle->rhs_tail,
1015 rhs);
1016
1017 return rhs;
1018}
1019
1020
1021/**
860 * Seed rps service with peerIDs. 1022 * Seed rps service with peerIDs.
861 * 1023 *
862 * @param h handle to the rps service 1024 * @param h handle to the rps service
@@ -1047,6 +1209,37 @@ GNUNET_RPS_request_cancel (struct GNUNET_RPS_Request_Handle *rh)
1047 1209
1048 1210
1049/** 1211/**
1212 * Cancle an issued single info request.
1213 *
1214 * @param rhs request handle of request to cancle
1215 */
1216void
1217GNUNET_RPS_request_single_info_cancel (
1218 struct GNUNET_RPS_Request_Handle_Single_Info *rhs)
1219{
1220 struct GNUNET_RPS_Handle *h;
1221
1222 h = rhs->rps_handle;
1223 GNUNET_assert (NULL != rhs);
1224 GNUNET_assert (NULL != rhs->srh);
1225 GNUNET_assert (h == rhs->srh->rps_handle);
1226 GNUNET_RPS_stream_cancel (rhs->srh);
1227 rhs->srh = NULL;
1228 if (NULL == h->stream_requests_head) cancel_stream(h);
1229 if (NULL != rhs->sampler_rh)
1230 {
1231 RPS_sampler_request_single_info_cancel (rhs->sampler_rh);
1232 }
1233 RPS_sampler_destroy (rhs->sampler);
1234 rhs->sampler = NULL;
1235 GNUNET_CONTAINER_DLL_remove (h->rhs_head,
1236 h->rhs_tail,
1237 rhs);
1238 GNUNET_free (rhs);
1239}
1240
1241
1242/**
1050 * Disconnect from the rps service 1243 * Disconnect from the rps service
1051 * 1244 *
1052 * @param h the handle to the rps service 1245 * @param h the handle to the rps service
@@ -1079,6 +1272,17 @@ GNUNET_RPS_disconnect (struct GNUNET_RPS_Handle *h)
1079 GNUNET_RPS_request_cancel (rh_iter); 1272 GNUNET_RPS_request_cancel (rh_iter);
1080 } 1273 }
1081 } 1274 }
1275 if (NULL != h->rhs_head)
1276 {
1277 LOG (GNUNET_ERROR_TYPE_WARNING,
1278 "Not all requests were cancelled!\n");
1279 for (struct GNUNET_RPS_Request_Handle_Single_Info *rhs_iter = h->rhs_head;
1280 h->rhs_head != NULL;
1281 rhs_iter = h->rhs_head)
1282 {
1283 GNUNET_RPS_request_single_info_cancel (rhs_iter);
1284 }
1285 }
1082 if (NULL != srh_callback_peers) 1286 if (NULL != srh_callback_peers)
1083 { 1287 {
1084 GNUNET_free (srh_callback_peers); 1288 GNUNET_free (srh_callback_peers);
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 2865460fd..f83fa669c 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -285,6 +285,7 @@ gnunet_communicator_tcp_LDADD = \
285gnunet_communicator_udp_SOURCES = \ 285gnunet_communicator_udp_SOURCES = \
286 gnunet-communicator-udp.c 286 gnunet-communicator-udp.c
287gnunet_communicator_udp_LDADD = \ 287gnunet_communicator_udp_LDADD = \
288 libgnunettransportapplication.la \
288 libgnunettransportcommunicator.la \ 289 libgnunettransportcommunicator.la \
289 $(top_builddir)/src/nat/libgnunetnatnew.la \ 290 $(top_builddir)/src/nat/libgnunetnatnew.la \
290 $(top_builddir)/src/nt/libgnunetnt.la \ 291 $(top_builddir)/src/nt/libgnunetnt.la \
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c
index fa8eb6acb..f101d2d75 100644
--- a/src/transport/gnunet-communicator-udp.c
+++ b/src/transport/gnunet-communicator-udp.c
@@ -35,7 +35,7 @@
35 * where is the API for that!?!) 35 * where is the API for that!?!)
36 * - support DNS names in BINDTO option (#5528) 36 * - support DNS names in BINDTO option (#5528)
37 * - support NAT connection reversal method (#5529) 37 * - support NAT connection reversal method (#5529)
38 * - support other UDP-specific NAT traversal methods (#) 38 * - support other UDP-specific NAT traversal methods (#)
39 */ 39 */
40#include "platform.h" 40#include "platform.h"
41#include "gnunet_util_lib.h" 41#include "gnunet_util_lib.h"
@@ -45,26 +45,27 @@
45#include "gnunet_nt_lib.h" 45#include "gnunet_nt_lib.h"
46#include "gnunet_nat_service.h" 46#include "gnunet_nat_service.h"
47#include "gnunet_statistics_service.h" 47#include "gnunet_statistics_service.h"
48#include "gnunet_transport_application_service.h"
48#include "gnunet_transport_communication_service.h" 49#include "gnunet_transport_communication_service.h"
49 50
50/** 51/**
51 * How often do we rekey based on time (at least) 52 * How often do we rekey based on time (at least)
52 */ 53 */
53#define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS 54#define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
54 55
55/** 56/**
56 * How long do we wait until we must have received the initial KX? 57 * How long do we wait until we must have received the initial KX?
57 */ 58 */
58#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES 59#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
59 60
60/** 61/**
61 * How often do we broadcast our presence on the LAN? 62 * How often do we broadcast our presence on the LAN?
62 */ 63 */
63#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES 64#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
64 65
65/** 66/**
66 * How often do we scan for changes to our network interfaces? 67 * How often do we scan for changes to our network interfaces?
67 */ 68 */
68#define INTERFACE_SCAN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 69#define INTERFACE_SCAN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
69 70
70/** 71/**
@@ -88,7 +89,7 @@
88 * #KCN_TARGET. 89 * #KCN_TARGET.
89 * Should be large enough that we don't generate ACKs all 90 * Should be large enough that we don't generate ACKs all
90 * the time and still have enough time for the ACK to 91 * the time and still have enough time for the ACK to
91 * arrive before the sender runs out. So really this 92 * arrive before the sender runs out. So really this
92 * should ideally be based on the RTT. 93 * should ideally be based on the RTT.
93 */ 94 */
94#define KCN_THRESHOLD 92 95#define KCN_THRESHOLD 92
@@ -113,8 +114,8 @@
113#define MAX_SQN_DELTA 160 114#define MAX_SQN_DELTA 160
114 115
115/** 116/**
116 * How many shared master secrets do we keep around 117 * How many shared master secrets do we keep around
117 * at most per sender? Should be large enough so 118 * at most per sender? Should be large enough so
118 * that we generally have a chance of sending an ACK 119 * that we generally have a chance of sending an ACK
119 * before the sender already rotated out the master 120 * before the sender already rotated out the master
120 * secret. Generally values around #KCN_TARGET make 121 * secret. Generally values around #KCN_TARGET make
@@ -126,7 +127,7 @@
126/** 127/**
127 * How often do we rekey based on number of bytes transmitted? 128 * How often do we rekey based on number of bytes transmitted?
128 * (additionally randomized). 129 * (additionally randomized).
129 */ 130 */
130#define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU) 131#define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
131 132
132/** 133/**
@@ -157,23 +158,23 @@ struct UdpHandshakeSignature
157 158
158 /** 159 /**
159 * Identity of the inititor of the UDP connection (UDP client). 160 * Identity of the inititor of the UDP connection (UDP client).
160 */ 161 */
161 struct GNUNET_PeerIdentity sender; 162 struct GNUNET_PeerIdentity sender;
162 163
163 /** 164 /**
164 * Presumed identity of the target of the UDP connection (UDP server) 165 * Presumed identity of the target of the UDP connection (UDP server)
165 */ 166 */
166 struct GNUNET_PeerIdentity receiver; 167 struct GNUNET_PeerIdentity receiver;
167 168
168 /** 169 /**
169 * Ephemeral key used by the @e sender. 170 * Ephemeral key used by the @e sender.
170 */ 171 */
171 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral; 172 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
172 173
173 /** 174 /**
174 * Monotonic time of @e sender, to possibly help detect replay attacks 175 * Monotonic time of @e sender, to possibly help detect replay attacks
175 * (if receiver persists times by sender). 176 * (if receiver persists times by sender).
176 */ 177 */
177 struct GNUNET_TIME_AbsoluteNBO monotonic_time; 178 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
178}; 179};
179 180
@@ -187,13 +188,13 @@ struct InitialKX
187 188
188 /** 189 /**
189 * Ephemeral key for KX. 190 * Ephemeral key for KX.
190 */ 191 */
191 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral; 192 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
192 193
193 /** 194 /**
194 * HMAC for the following encrypted message, using GCM. HMAC uses 195 * HMAC for the following encrypted message, using GCM. HMAC uses
195 * key derived from the handshake with sequence number zero. 196 * key derived from the handshake with sequence number zero.
196 */ 197 */
197 char gcm_tag[GCM_TAG_SIZE]; 198 char gcm_tag[GCM_TAG_SIZE];
198 199
199}; 200};
@@ -218,7 +219,7 @@ struct UDPConfirmation
218 /** 219 /**
219 * Monotonic time of @e sender, to possibly help detect replay attacks 220 * Monotonic time of @e sender, to possibly help detect replay attacks
220 * (if receiver persists times by sender). 221 * (if receiver persists times by sender).
221 */ 222 */
222 struct GNUNET_TIME_AbsoluteNBO monotonic_time; 223 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
223 224
224 /* followed by messages */ 225 /* followed by messages */
@@ -230,24 +231,24 @@ struct UDPConfirmation
230/** 231/**
231 * UDP key acknowledgement. May be sent via backchannel. Allows the 232 * UDP key acknowledgement. May be sent via backchannel. Allows the
232 * sender to use `struct UDPBox` with the acknowledge key henceforth. 233 * sender to use `struct UDPBox` with the acknowledge key henceforth.
233 */ 234 */
234struct UDPAck 235struct UDPAck
235{ 236{
236 237
237 /** 238 /**
238 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK. 239 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
239 */ 240 */
240 struct GNUNET_MessageHeader header; 241 struct GNUNET_MessageHeader header;
241 242
242 /** 243 /**
243 * Sequence acknowledgement limit. Specifies current maximum sequence 244 * Sequence acknowledgement limit. Specifies current maximum sequence
244 * number supported by receiver. 245 * number supported by receiver.
245 */ 246 */
246 uint32_t sequence_max GNUNET_PACKED; 247 uint32_t sequence_max GNUNET_PACKED;
247 248
248 /** 249 /**
249 * CMAC of the base key being acknowledged. 250 * CMAC of the base key being acknowledged.
250 */ 251 */
251 struct GNUNET_HashCode cmac; 252 struct GNUNET_HashCode cmac;
252 253
253}; 254};
@@ -257,7 +258,7 @@ struct UDPAck
257 * Signature we use to verify that the broadcast was really made by 258 * Signature we use to verify that the broadcast was really made by
258 * the peer that claims to have made it. Basically, affirms that the 259 * the peer that claims to have made it. Basically, affirms that the
259 * peer is really using this IP address (albeit possibly not in _our_ 260 * peer is really using this IP address (albeit possibly not in _our_
260 * LAN). Makes it difficult for peers in the LAN to claim to 261 * LAN). Makes it difficult for peers in the LAN to claim to
261 * be just any global peer -- an attacker must have at least 262 * be just any global peer -- an attacker must have at least
262 * shared a LAN with the peer they're pretending to be here. 263 * shared a LAN with the peer they're pretending to be here.
263 */ 264 */
@@ -270,12 +271,12 @@ struct UdpBroadcastSignature
270 271
271 /** 272 /**
272 * Identity of the inititor of the UDP broadcast. 273 * Identity of the inititor of the UDP broadcast.
273 */ 274 */
274 struct GNUNET_PeerIdentity sender; 275 struct GNUNET_PeerIdentity sender;
275 276
276 /** 277 /**
277 * Hash of the sender's UDP address. 278 * Hash of the sender's UDP address.
278 */ 279 */
279 struct GNUNET_HashCode h_address; 280 struct GNUNET_HashCode h_address;
280}; 281};
281 282
@@ -298,22 +299,22 @@ struct UDPBroadcast
298 * Sender's signature of type 299 * Sender's signature of type
299 * #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST 300 * #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST
300 */ 301 */
301 struct GNUNET_CRYPTO_EddsaSignature sender_sig; 302 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
302 303
303}; 304};
304 305
305 306
306/** 307/**
307 * UDP message box. Always sent encrypted, only allowed after 308 * UDP message box. Always sent encrypted, only allowed after
308 * the receiver sent a `struct UDPAck` for the base key! 309 * the receiver sent a `struct UDPAck` for the base key!
309 */ 310 */
310struct UDPBox 311struct UDPBox
311{ 312{
312 313
313 /** 314 /**
314 * Key and IV identification code. KDF applied to an acknowledged 315 * Key and IV identification code. KDF applied to an acknowledged
315 * base key and a sequence number. Sequence numbers must be used 316 * base key and a sequence number. Sequence numbers must be used
316 * monotonically increasing up to the maximum specified in 317 * monotonically increasing up to the maximum specified in
317 * `struct UDPAck`. Without further `struct UDPAck`s, the sender 318 * `struct UDPAck`. Without further `struct UDPAck`s, the sender
318 * must fall back to sending handshakes! 319 * must fall back to sending handshakes!
319 */ 320 */
@@ -325,9 +326,9 @@ struct UDPBox
325 * extends until the end of the UDP payload. If the @e hmac is 326 * extends until the end of the UDP payload. If the @e hmac is
326 * wrong, the receiver should check if the message might be a 327 * wrong, the receiver should check if the message might be a
327 * `struct UdpHandshakeSignature`. 328 * `struct UdpHandshakeSignature`.
328 */ 329 */
329 char gcm_tag[GCM_TAG_SIZE]; 330 char gcm_tag[GCM_TAG_SIZE];
330 331
331}; 332};
332 333
333 334
@@ -350,7 +351,7 @@ struct KeyCacheEntry
350 * Kept in a DLL. 351 * Kept in a DLL.
351 */ 352 */
352 struct KeyCacheEntry *next; 353 struct KeyCacheEntry *next;
353 354
354 /** 355 /**
355 * Kept in a DLL. 356 * Kept in a DLL.
356 */ 357 */
@@ -359,7 +360,7 @@ struct KeyCacheEntry
359 /** 360 /**
360 * Key and IV identification code. KDF applied to an acknowledged 361 * Key and IV identification code. KDF applied to an acknowledged
361 * base key and a sequence number. Sequence numbers must be used 362 * base key and a sequence number. Sequence numbers must be used
362 * monotonically increasing up to the maximum specified in 363 * monotonically increasing up to the maximum specified in
363 * `struct UDPAck`. Without further `struct UDPAck`s, the sender 364 * `struct UDPAck`. Without further `struct UDPAck`s, the sender
364 * must fall back to sending handshakes! 365 * must fall back to sending handshakes!
365 */ 366 */
@@ -372,7 +373,7 @@ struct KeyCacheEntry
372 373
373 /** 374 /**
374 * Sequence number used to derive this entry from master key. 375 * Sequence number used to derive this entry from master key.
375 */ 376 */
376 uint32_t sequence_number; 377 uint32_t sequence_number;
377}; 378};
378 379
@@ -408,7 +409,7 @@ struct SharedSecret
408 * Kept in a DLL, sorted by sequence number. Only if we are decrypting. 409 * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
409 */ 410 */
410 struct KeyCacheEntry *kce_head; 411 struct KeyCacheEntry *kce_head;
411 412
412 /** 413 /**
413 * Kept in a DLL, sorted by sequence number. Only if we are decrypting. 414 * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
414 */ 415 */
@@ -423,21 +424,21 @@ struct SharedSecret
423 * Receiver we use this shared secret with, or NULL. 424 * Receiver we use this shared secret with, or NULL.
424 */ 425 */
425 struct ReceiverAddress *receiver; 426 struct ReceiverAddress *receiver;
426 427
427 /** 428 /**
428 * Master shared secret. 429 * Master shared secret.
429 */ 430 */
430 struct GNUNET_HashCode master; 431 struct GNUNET_HashCode master;
431 432
432 /** 433 /**
433 * CMAC is used to identify @e master in ACKs. 434 * CMAC is used to identify @e master in ACKs.
434 */ 435 */
435 struct GNUNET_HashCode cmac; 436 struct GNUNET_HashCode cmac;
436 437
437 /** 438 /**
438 * Up to which sequence number did we use this @e master already? 439 * Up to which sequence number did we use this @e master already?
439 * (for encrypting only) 440 * (for encrypting only)
440 */ 441 */
441 uint32_t sequence_used; 442 uint32_t sequence_used;
442 443
443 /** 444 /**
@@ -449,7 +450,7 @@ struct SharedSecret
449 450
450 /** 451 /**
451 * Number of active KCN entries. 452 * Number of active KCN entries.
452 */ 453 */
453 unsigned int active_kce_count; 454 unsigned int active_kce_count;
454}; 455};
455 456
@@ -464,11 +465,11 @@ struct SenderAddress
464 /** 465 /**
465 * To whom are we talking to. 466 * To whom are we talking to.
466 */ 467 */
467 struct GNUNET_PeerIdentity target; 468 struct GNUNET_PeerIdentity target;
468 469
469 /** 470 /**
470 * Entry in sender expiration heap. 471 * Entry in sender expiration heap.
471 */ 472 */
472 struct GNUNET_CONTAINER_HeapNode *hn; 473 struct GNUNET_CONTAINER_HeapNode *hn;
473 474
474 /** 475 /**
@@ -480,12 +481,12 @@ struct SenderAddress
480 * Shared secrets we used with @e target, last used is tail. 481 * Shared secrets we used with @e target, last used is tail.
481 */ 482 */
482 struct SharedSecret *ss_tail; 483 struct SharedSecret *ss_tail;
483 484
484 /** 485 /**
485 * Address of the other peer. 486 * Address of the other peer.
486 */ 487 */
487 struct sockaddr *address; 488 struct sockaddr *address;
488 489
489 /** 490 /**
490 * Length of the address. 491 * Length of the address.
491 */ 492 */
@@ -498,14 +499,14 @@ struct SenderAddress
498 499
499 /** 500 /**
500 * Length of the DLL at @a ss_head. 501 * Length of the DLL at @a ss_head.
501 */ 502 */
502 unsigned int num_secrets; 503 unsigned int num_secrets;
503 504
504 /** 505 /**
505 * Which network type does this queue use? 506 * Which network type does this queue use?
506 */ 507 */
507 enum GNUNET_NetworkType nt; 508 enum GNUNET_NetworkType nt;
508 509
509}; 510};
510 511
511 512
@@ -519,8 +520,8 @@ struct ReceiverAddress
519 /** 520 /**
520 * To whom are we talking to. 521 * To whom are we talking to.
521 */ 522 */
522 struct GNUNET_PeerIdentity target; 523 struct GNUNET_PeerIdentity target;
523 524
524 /** 525 /**
525 * Shared secrets we received from @e target, first used is head. 526 * Shared secrets we received from @e target, first used is head.
526 */ 527 */
@@ -534,14 +535,14 @@ struct ReceiverAddress
534 /** 535 /**
535 * Address of the receiver in the human-readable format 536 * Address of the receiver in the human-readable format
536 * with the #COMMUNICATOR_ADDRESS_PREFIX. 537 * with the #COMMUNICATOR_ADDRESS_PREFIX.
537 */ 538 */
538 char *foreign_addr; 539 char *foreign_addr;
539 540
540 /** 541 /**
541 * Address of the other peer. 542 * Address of the other peer.
542 */ 543 */
543 struct sockaddr *address; 544 struct sockaddr *address;
544 545
545 /** 546 /**
546 * Length of the address. 547 * Length of the address.
547 */ 548 */
@@ -549,7 +550,7 @@ struct ReceiverAddress
549 550
550 /** 551 /**
551 * Entry in sender expiration heap. 552 * Entry in sender expiration heap.
552 */ 553 */
553 struct GNUNET_CONTAINER_HeapNode *hn; 554 struct GNUNET_CONTAINER_HeapNode *hn;
554 555
555 /** 556 /**
@@ -571,23 +572,23 @@ struct ReceiverAddress
571 * MTU we allowed transport for this receiver right now. 572 * MTU we allowed transport for this receiver right now.
572 */ 573 */
573 size_t mtu; 574 size_t mtu;
574 575
575 /** 576 /**
576 * Length of the DLL at @a ss_head. 577 * Length of the DLL at @a ss_head.
577 */ 578 */
578 unsigned int num_secrets; 579 unsigned int num_secrets;
579 580
580 /** 581 /**
581 * Number of BOX keys from ACKs we have currently 582 * Number of BOX keys from ACKs we have currently
582 * available for this receiver. 583 * available for this receiver.
583 */ 584 */
584 unsigned int acks_available; 585 unsigned int acks_available;
585 586
586 /** 587 /**
587 * Which network type does this queue use? 588 * Which network type does this queue use?
588 */ 589 */
589 enum GNUNET_NetworkType nt; 590 enum GNUNET_NetworkType nt;
590 591
591}; 592};
592 593
593 594
@@ -611,12 +612,12 @@ struct BroadcastInterface
611 * Task for this broadcast interface. 612 * Task for this broadcast interface.
612 */ 613 */
613 struct GNUNET_SCHEDULER_Task *broadcast_task; 614 struct GNUNET_SCHEDULER_Task *broadcast_task;
614 615
615 /** 616 /**
616 * Sender's address of the interface. 617 * Sender's address of the interface.
617 */ 618 */
618 struct sockaddr *sa; 619 struct sockaddr *sa;
619 620
620 /** 621 /**
621 * Broadcast address to use on the interface. 622 * Broadcast address to use on the interface.
622 */ 623 */
@@ -624,18 +625,18 @@ struct BroadcastInterface
624 625
625 /** 626 /**
626 * Message we broadcast on this interface. 627 * Message we broadcast on this interface.
627 */ 628 */
628 struct UDPBroadcast bcm; 629 struct UDPBroadcast bcm;
629 630
630 /** 631 /**
631 * If this is an IPv6 interface, this is the request 632 * If this is an IPv6 interface, this is the request
632 * we use to join/leave the group. 633 * we use to join/leave the group.
633 */ 634 */
634 struct ipv6_mreq mcreq; 635 struct ipv6_mreq mcreq;
635 636
636 /** 637 /**
637 * Number of bytes in @e sa. 638 * Number of bytes in @e sa.
638 */ 639 */
639 socklen_t salen; 640 socklen_t salen;
640 641
641 /** 642 /**
@@ -710,9 +711,9 @@ static struct BroadcastInterface *bi_tail;
710 */ 711 */
711static struct GNUNET_NETWORK_Handle *udp_sock; 712static struct GNUNET_NETWORK_Handle *udp_sock;
712 713
713/** 714/**
714 * #GNUNET_YES if #udp_sock supports IPv6. 715 * #GNUNET_YES if #udp_sock supports IPv6.
715 */ 716 */
716static int have_v6_socket; 717static int have_v6_socket;
717 718
718/** 719/**
@@ -731,6 +732,11 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
731static const struct GNUNET_CONFIGURATION_Handle *cfg; 732static const struct GNUNET_CONFIGURATION_Handle *cfg;
732 733
733/** 734/**
735 * Our handle to report addresses for validation to TRANSPORT.
736 */
737static struct GNUNET_TRANSPORT_ApplicationHandle *ah;
738
739/**
734 * Network scanner to determine network types. 740 * Network scanner to determine network types.
735 */ 741 */
736static struct GNUNET_NT_InterfaceScanner *is; 742static struct GNUNET_NT_InterfaceScanner *is;
@@ -742,7 +748,7 @@ static struct GNUNET_NAT_Handle *nat;
742 748
743/** 749/**
744 * Port number to which we are actually bound. 750 * Port number to which we are actually bound.
745 */ 751 */
746static uint16_t my_port; 752static uint16_t my_port;
747 753
748 754
@@ -788,7 +794,7 @@ static void
788receiver_destroy (struct ReceiverAddress *receiver) 794receiver_destroy (struct ReceiverAddress *receiver)
789{ 795{
790 struct GNUNET_MQ_Handle *mq; 796 struct GNUNET_MQ_Handle *mq;
791 797
792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 798 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
793 "Disconnecting receiver for peer `%s'\n", 799 "Disconnecting receiver for peer `%s'\n",
794 GNUNET_i2s (&receiver->target)); 800 GNUNET_i2s (&receiver->target));
@@ -822,7 +828,7 @@ receiver_destroy (struct ReceiverAddress *receiver)
822 * Free memory used by key cache entry. 828 * Free memory used by key cache entry.
823 * 829 *
824 * @param kce the key cache entry 830 * @param kce the key cache entry
825 */ 831 */
826static void 832static void
827kce_destroy (struct KeyCacheEntry *kce) 833kce_destroy (struct KeyCacheEntry *kce)
828{ 834{
@@ -1048,7 +1054,7 @@ check_timeouts (void *cls)
1048 struct GNUNET_TIME_Relative delay; 1054 struct GNUNET_TIME_Relative delay;
1049 struct ReceiverAddress *receiver; 1055 struct ReceiverAddress *receiver;
1050 struct SenderAddress *sender; 1056 struct SenderAddress *sender;
1051 1057
1052 (void) cls; 1058 (void) cls;
1053 timeout_task = NULL; 1059 timeout_task = NULL;
1054 rt = GNUNET_TIME_UNIT_FOREVER_REL; 1060 rt = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1072,9 +1078,9 @@ check_timeouts (void *cls)
1072 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 1078 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1073 timeout_task = GNUNET_SCHEDULER_add_delayed (delay, 1079 timeout_task = GNUNET_SCHEDULER_add_delayed (delay,
1074 &check_timeouts, 1080 &check_timeouts,
1075 NULL); 1081 NULL);
1076} 1082}
1077 1083
1078 1084
1079/** 1085/**
1080 * Calcualte cmac from master in @a ss. 1086 * Calcualte cmac from master in @a ss.
@@ -1100,12 +1106,12 @@ calculate_cmac (struct SharedSecret *ss)
1100 1106
1101/** 1107/**
1102 * We received @a plaintext_len bytes of @a plaintext from a @a sender. 1108 * We received @a plaintext_len bytes of @a plaintext from a @a sender.
1103 * Pass it on to CORE. 1109 * Pass it on to CORE.
1104 * 1110 *
1105 * @param queue the queue that received the plaintext 1111 * @param queue the queue that received the plaintext
1106 * @param plaintext the plaintext that was received 1112 * @param plaintext the plaintext that was received
1107 * @param plaintext_len number of bytes of plaintext received 1113 * @param plaintext_len number of bytes of plaintext received
1108 */ 1114 */
1109static void 1115static void
1110pass_plaintext_to_core (struct SenderAddress *sender, 1116pass_plaintext_to_core (struct SenderAddress *sender,
1111 const void *plaintext, 1117 const void *plaintext,
@@ -1171,7 +1177,7 @@ setup_cipher (const struct GNUNET_HashCode *msec,
1171 1177
1172 1178
1173/** 1179/**
1174 * Try to decrypt @a buf using shared secret @a ss and key/iv 1180 * Try to decrypt @a buf using shared secret @a ss and key/iv
1175 * derived using @a serial. 1181 * derived using @a serial.
1176 * 1182 *
1177 * @param ss shared secret 1183 * @param ss shared secret
@@ -1274,7 +1280,7 @@ setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral,
1274 * recalculated and a fresh queue is initialized. 1280 * recalculated and a fresh queue is initialized.
1275 * 1281 *
1276 * @param receiver receiver to setup MQ for 1282 * @param receiver receiver to setup MQ for
1277 */ 1283 */
1278static void 1284static void
1279setup_receiver_mq (struct ReceiverAddress *receiver); 1285setup_receiver_mq (struct ReceiverAddress *receiver);
1280 1286
@@ -1307,9 +1313,9 @@ handle_ack (void *cls,
1307 sizeof (struct GNUNET_HashCode))) 1313 sizeof (struct GNUNET_HashCode)))
1308 { 1314 {
1309 uint32_t allowed; 1315 uint32_t allowed;
1310 1316
1311 allowed = ntohl (ack->sequence_max); 1317 allowed = ntohl (ack->sequence_max);
1312 1318
1313 if (allowed > ss->sequence_allowed) 1319 if (allowed > ss->sequence_allowed)
1314 { 1320 {
1315 receiver->acks_available += (allowed - ss->sequence_allowed); 1321 receiver->acks_available += (allowed - ss->sequence_allowed);
@@ -1342,7 +1348,7 @@ handle_ack (void *cls,
1342 * @param sender peer to process inbound plaintext for 1348 * @param sender peer to process inbound plaintext for
1343 * @param buf buffer we received 1349 * @param buf buffer we received
1344 * @param buf_size number of bytes in @a buf 1350 * @param buf_size number of bytes in @a buf
1345 */ 1351 */
1346static void 1352static void
1347try_handle_plaintext (struct SenderAddress *sender, 1353try_handle_plaintext (struct SenderAddress *sender,
1348 const void *buf, 1354 const void *buf,
@@ -1413,9 +1419,9 @@ consider_ss_ack (struct SharedSecret *ss)
1413 ack.sequence_max = htonl (ss->sequence_allowed); 1419 ack.sequence_max = htonl (ss->sequence_allowed);
1414 ack.cmac = ss->cmac; 1420 ack.cmac = ss->cmac;
1415 GNUNET_TRANSPORT_communicator_notify (ch, 1421 GNUNET_TRANSPORT_communicator_notify (ch,
1416 &ss->sender->target, 1422 &ss->sender->target,
1417 COMMUNICATOR_ADDRESS_PREFIX, 1423 COMMUNICATOR_ADDRESS_PREFIX,
1418 &ack.header); 1424 &ack.header);
1419 } 1425 }
1420} 1426}
1421 1427
@@ -1426,7 +1432,7 @@ consider_ss_ack (struct SharedSecret *ss)
1426 * @param box the data we received 1432 * @param box the data we received
1427 * @param box_len number of bytes in @a box 1433 * @param box_len number of bytes in @a box
1428 * @param kce key index to decrypt @a box 1434 * @param kce key index to decrypt @a box
1429 */ 1435 */
1430static void 1436static void
1431decrypt_box (const struct UDPBox *box, 1437decrypt_box (const struct UDPBox *box,
1432 size_t box_len, 1438 size_t box_len,
@@ -1519,7 +1525,7 @@ find_sender_by_address (void *cls,
1519 * if one does not yet exist for @a address. 1525 * if one does not yet exist for @a address.
1520 * 1526 *
1521 * @param target peer to generate address for 1527 * @param target peer to generate address for
1522 * @param address target address 1528 * @param address target address
1523 * @param address_len number of bytes in @a address 1529 * @param address_len number of bytes in @a address
1524 * @return data structure to keep track of key material for 1530 * @return data structure to keep track of key material for
1525 * decrypting data from @a target 1531 * decrypting data from @a target
@@ -1582,10 +1588,10 @@ setup_sender (const struct GNUNET_PeerIdentity *target,
1582 */ 1588 */
1583static int 1589static int
1584verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, 1590verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1585 const struct UDPConfirmation *uc) 1591 const struct UDPConfirmation *uc)
1586{ 1592{
1587 struct UdpHandshakeSignature uhs; 1593 struct UdpHandshakeSignature uhs;
1588 1594
1589 uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE); 1595 uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE);
1590 uhs.purpose.size = htonl (sizeof (uhs)); 1596 uhs.purpose.size = htonl (sizeof (uhs));
1591 uhs.sender = uc->sender; 1597 uhs.sender = uc->sender;
@@ -1593,14 +1599,51 @@ verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1593 uhs.ephemeral = *ephemeral; 1599 uhs.ephemeral = *ephemeral;
1594 uhs.monotonic_time = uc->monotonic_time; 1600 uhs.monotonic_time = uc->monotonic_time;
1595 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE, 1601 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE,
1596 &uhs.purpose, 1602 &uhs.purpose,
1597 &uc->sender_sig, 1603 &uc->sender_sig,
1598 &uc->sender.public_key); 1604 &uc->sender.public_key);
1605}
1606
1607
1608/**
1609 * Converts @a address to the address string format used by this
1610 * communicator in HELLOs.
1611 *
1612 * @param address the address to convert, must be AF_INET or AF_INET6.
1613 * @param address_len number of bytes in @a address
1614 * @return string representation of @a address
1615 */
1616static char *
1617sockaddr_to_udpaddr_string (const struct sockaddr *address,
1618 socklen_t address_len)
1619{
1620 char *ret;
1621
1622 switch (address->sa_family)
1623 {
1624 case AF_INET:
1625 GNUNET_asprintf (&ret,
1626 "%s-%s",
1627 COMMUNICATOR_ADDRESS_PREFIX,
1628 GNUNET_a2s (address,
1629 address_len));
1630 break;
1631 case AF_INET6:
1632 GNUNET_asprintf (&ret,
1633 "%s-%s",
1634 COMMUNICATOR_ADDRESS_PREFIX,
1635 GNUNET_a2s (address,
1636 address_len));
1637 break;
1638 default:
1639 GNUNET_assert (0);
1640 }
1641 return ret;
1599} 1642}
1600 1643
1601 1644
1602/** 1645/**
1603 * Socket read task. 1646 * Socket read task.
1604 * 1647 *
1605 * @param cls NULL 1648 * @param cls NULL
1606 */ 1649 */
@@ -1615,18 +1658,18 @@ sock_read (void *cls)
1615 (void) cls; 1658 (void) cls;
1616 read_task 1659 read_task
1617 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 1660 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1618 udp_sock, 1661 udp_sock,
1619 &sock_read, 1662 &sock_read,
1620 NULL); 1663 NULL);
1621 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock, 1664 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
1622 buf, 1665 buf,
1623 sizeof (buf), 1666 sizeof (buf),
1624 (struct sockaddr *) &sa, 1667 (struct sockaddr *) &sa,
1625 &salen); 1668 &salen);
1626 if (-1 == rcvd) 1669 if (-1 == rcvd)
1627 { 1670 {
1628 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, 1671 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1629 "recv"); 1672 "recv");
1630 return; 1673 return;
1631 } 1674 }
1632 1675
@@ -1638,12 +1681,12 @@ sock_read (void *cls)
1638 1681
1639 box = (const struct UDPBox *) buf; 1682 box = (const struct UDPBox *) buf;
1640 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, 1683 kce = GNUNET_CONTAINER_multishortmap_get (key_cache,
1641 &box->kid); 1684 &box->kid);
1642 if (NULL != kce) 1685 if (NULL != kce)
1643 { 1686 {
1644 decrypt_box (box, 1687 decrypt_box (box,
1645 (size_t) rcvd, 1688 (size_t) rcvd,
1646 kce); 1689 kce);
1647 return; 1690 return;
1648 } 1691 }
1649 } 1692 }
@@ -1659,25 +1702,41 @@ sock_read (void *cls)
1659 uhs.purpose.size = htonl (sizeof (uhs)); 1702 uhs.purpose.size = htonl (sizeof (uhs));
1660 uhs.sender = ub->sender; 1703 uhs.sender = ub->sender;
1661 GNUNET_CRYPTO_hash (&sa, 1704 GNUNET_CRYPTO_hash (&sa,
1662 salen, 1705 salen,
1663 &uhs.h_address); 1706 &uhs.h_address);
1664 if (GNUNET_OK == 1707 if (GNUNET_OK ==
1665 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST, 1708 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST,
1666 &uhs.purpose, 1709 &uhs.purpose,
1667 &ub->sender_sig, 1710 &ub->sender_sig,
1668 &ub->sender.public_key)) 1711 &ub->sender.public_key))
1669 { 1712 {
1713 char *addr_s;
1714 struct GNUNET_TIME_Absolute expiration;
1715 enum GNUNET_NetworkType nt;
1716
1717 addr_s = sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa,
1718 salen);
1670 GNUNET_STATISTICS_update (stats, 1719 GNUNET_STATISTICS_update (stats,
1671 "# broadcasts received", 1720 "# broadcasts received",
1672 1, 1721 1,
1673 GNUNET_NO); 1722 GNUNET_NO);
1674 // FIXME #5551: we effectively just got a HELLO! 1723 /* expire at the broadcast frequency, as then we'll get the next one anyway */
1675 // trigger verification NOW! 1724 expiration = GNUNET_TIME_relative_to_absolute (BROADCAST_FREQUENCY);
1725 /* use our own mechanism to determine network type */
1726 nt = GNUNET_NT_scanner_get_type (is,
1727 (const struct sockaddr *) &sa,
1728 salen);
1729 GNUNET_TRANSPORT_application_validate (ah,
1730 &ub->sender,
1731 expiration,
1732 nt,
1733 addr_s);
1734 GNUNET_free (addr_s);
1676 return; 1735 return;
1677 } 1736 }
1678 /* continue with KX, mostly for statistics... */ 1737 /* continue with KX, mostly for statistics... */
1679 } 1738 }
1680 1739
1681 1740
1682 /* finally, test if it is a KX */ 1741 /* finally, test if it is a KX */
1683 if (rcvd < sizeof (struct UDPConfirmation) + sizeof (struct InitialKX)) 1742 if (rcvd < sizeof (struct UDPConfirmation) + sizeof (struct InitialKX))
@@ -1769,7 +1828,7 @@ udp_address_to_sockaddr (const char *bindto,
1769 char dummy[2]; 1828 char dummy[2];
1770 char *colon; 1829 char *colon;
1771 char *cp; 1830 char *cp;
1772 1831
1773 if (1 == SSCANF (bindto, 1832 if (1 == SSCANF (bindto,
1774 "%u%1s", 1833 "%u%1s",
1775 &port, 1834 &port,
@@ -1791,7 +1850,7 @@ udp_address_to_sockaddr (const char *bindto,
1791 "DISABLE_V6")) ) 1850 "DISABLE_V6")) )
1792 { 1851 {
1793 struct sockaddr_in *i4; 1852 struct sockaddr_in *i4;
1794 1853
1795 i4 = GNUNET_malloc (sizeof (struct sockaddr_in)); 1854 i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1796 i4->sin_family = AF_INET; 1855 i4->sin_family = AF_INET;
1797 i4->sin_port = htons ((uint16_t) port); 1856 i4->sin_port = htons ((uint16_t) port);
@@ -1801,7 +1860,7 @@ udp_address_to_sockaddr (const char *bindto,
1801 else 1860 else
1802 { 1861 {
1803 struct sockaddr_in6 *i6; 1862 struct sockaddr_in6 *i6;
1804 1863
1805 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6)); 1864 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1806 i6->sin6_family = AF_INET6; 1865 i6->sin6_family = AF_INET6;
1807 i6->sin6_port = htons ((uint16_t) port); 1866 i6->sin6_port = htons ((uint16_t) port);
@@ -1915,7 +1974,7 @@ do_pad (gcry_cipher_hd_t out_cipher,
1915 .size = htons (sizeof (pad)), 1974 .size = htons (sizeof (pad)),
1916 .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD) 1975 .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD)
1917 }; 1976 };
1918 1977
1919 memcpy (pad, 1978 memcpy (pad,
1920 &hdr, 1979 &hdr,
1921 sizeof (hdr)); 1980 sizeof (hdr));
@@ -1953,7 +2012,7 @@ mq_send (struct GNUNET_MQ_Handle *mq,
1953 return; 2012 return;
1954 } 2013 }
1955 reschedule_receiver_timeout (receiver); 2014 reschedule_receiver_timeout (receiver);
1956 2015
1957 if (0 == receiver->acks_available) 2016 if (0 == receiver->acks_available)
1958 { 2017 {
1959 /* use KX encryption method */ 2018 /* use KX encryption method */
@@ -2159,12 +2218,12 @@ mq_error (void *cls,
2159 * recalculated and a fresh queue is initialized. 2218 * recalculated and a fresh queue is initialized.
2160 * 2219 *
2161 * @param receiver receiver to setup MQ for 2220 * @param receiver receiver to setup MQ for
2162 */ 2221 */
2163static void 2222static void
2164setup_receiver_mq (struct ReceiverAddress *receiver) 2223setup_receiver_mq (struct ReceiverAddress *receiver)
2165{ 2224{
2166 size_t base_mtu; 2225 size_t base_mtu;
2167 2226
2168 if (NULL != receiver->qh) 2227 if (NULL != receiver->qh)
2169 { 2228 {
2170 GNUNET_TRANSPORT_communicator_mq_del (receiver->qh); 2229 GNUNET_TRANSPORT_communicator_mq_del (receiver->qh);
@@ -2226,58 +2285,40 @@ setup_receiver_mq (struct ReceiverAddress *receiver)
2226 2285
2227/** 2286/**
2228 * Setup a receiver for transmission. Setup the MQ processing and 2287 * Setup a receiver for transmission. Setup the MQ processing and
2229 * inform transport that the queue is ready. 2288 * inform transport that the queue is ready.
2230 * 2289 *
2231 * @param 2290 * @param
2232 */ 2291 */
2233static struct ReceiverAddress * 2292static struct ReceiverAddress *
2234receiver_setup (const struct GNUNET_PeerIdentity *target, 2293receiver_setup (const struct GNUNET_PeerIdentity *target,
2235 const struct sockaddr *address, 2294 const struct sockaddr *address,
2236 socklen_t address_len) 2295 socklen_t address_len)
2237{ 2296{
2238 struct ReceiverAddress *receiver; 2297 struct ReceiverAddress *receiver;
2239 2298
2240 receiver = GNUNET_new (struct ReceiverAddress); 2299 receiver = GNUNET_new (struct ReceiverAddress);
2241 receiver->address = GNUNET_memdup (address, 2300 receiver->address = GNUNET_memdup (address,
2242 address_len); 2301 address_len);
2243 receiver->address_len = address_len; 2302 receiver->address_len = address_len;
2244 receiver->target = *target; 2303 receiver->target = *target;
2245 receiver->nt = GNUNET_NT_scanner_get_type (is, 2304 receiver->nt = GNUNET_NT_scanner_get_type (is,
2246 address, 2305 address,
2247 address_len); 2306 address_len);
2248 (void) GNUNET_CONTAINER_multipeermap_put (receivers, 2307 (void) GNUNET_CONTAINER_multipeermap_put (receivers,
2249 &receiver->target, 2308 &receiver->target,
2250 receiver, 2309 receiver,
2251 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 2310 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2252 receiver->timeout 2311 receiver->timeout
2253 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 2312 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2254 receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap, 2313 receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap,
2255 receiver, 2314 receiver,
2256 receiver->timeout.abs_value_us); 2315 receiver->timeout.abs_value_us);
2257 GNUNET_STATISTICS_set (stats, 2316 GNUNET_STATISTICS_set (stats,
2258 "# receivers active", 2317 "# receivers active",
2259 GNUNET_CONTAINER_multipeermap_size (receivers), 2318 GNUNET_CONTAINER_multipeermap_size (receivers),
2260 GNUNET_NO); 2319 GNUNET_NO);
2261 switch (address->sa_family) 2320 receiver->foreign_addr = sockaddr_to_udpaddr_string (receiver->address,
2262 { 2321 receiver->address_len);
2263 case AF_INET:
2264 GNUNET_asprintf (&receiver->foreign_addr,
2265 "%s-%s",
2266 COMMUNICATOR_ADDRESS_PREFIX,
2267 GNUNET_a2s (receiver->address,
2268 receiver->address_len));
2269 break;
2270 case AF_INET6:
2271 GNUNET_asprintf (&receiver->foreign_addr,
2272 "%s-%s",
2273 COMMUNICATOR_ADDRESS_PREFIX,
2274 GNUNET_a2s (receiver->address,
2275 receiver->address_len));
2276 break;
2277 default:
2278 GNUNET_assert (0);
2279 }
2280
2281 setup_receiver_mq (receiver); 2322 setup_receiver_mq (receiver);
2282 2323
2283 if (NULL == timeout_task) 2324 if (NULL == timeout_task)
@@ -2313,7 +2354,7 @@ mq_init (void *cls,
2313 const char *path; 2354 const char *path;
2314 struct sockaddr *in; 2355 struct sockaddr *in;
2315 socklen_t in_len; 2356 socklen_t in_len;
2316 2357
2317 if (0 != strncmp (address, 2358 if (0 != strncmp (address,
2318 COMMUNICATOR_ADDRESS_PREFIX "-", 2359 COMMUNICATOR_ADDRESS_PREFIX "-",
2319 strlen (COMMUNICATOR_ADDRESS_PREFIX "-"))) 2360 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
@@ -2323,12 +2364,12 @@ mq_init (void *cls,
2323 } 2364 }
2324 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")]; 2365 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2325 in = udp_address_to_sockaddr (path, 2366 in = udp_address_to_sockaddr (path,
2326 &in_len); 2367 &in_len);
2327 receiver = receiver_setup (peer, 2368 receiver = receiver_setup (peer,
2328 in, 2369 in,
2329 in_len); 2370 in_len);
2330 (void) receiver; 2371 (void) receiver;
2331 return GNUNET_OK; 2372 return GNUNET_OK;
2332} 2373}
2333 2374
2334 2375
@@ -2423,6 +2464,11 @@ do_shutdown (void *cls)
2423 GNUNET_TRANSPORT_communicator_disconnect (ch); 2464 GNUNET_TRANSPORT_communicator_disconnect (ch);
2424 ch = NULL; 2465 ch = NULL;
2425 } 2466 }
2467 if (NULL != ah)
2468 {
2469 GNUNET_TRANSPORT_application_done (ah);
2470 ah = NULL;
2471 }
2426 if (NULL != stats) 2472 if (NULL != stats)
2427 { 2473 {
2428 GNUNET_STATISTICS_destroy (stats, 2474 GNUNET_STATISTICS_destroy (stats,
@@ -2457,7 +2503,7 @@ enc_notify_cb (void *cls,
2457 const struct GNUNET_MessageHeader *msg) 2503 const struct GNUNET_MessageHeader *msg)
2458{ 2504{
2459 const struct UDPAck *ack; 2505 const struct UDPAck *ack;
2460 2506
2461 (void) cls; 2507 (void) cls;
2462 if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) || 2508 if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) ||
2463 (ntohs (msg->size) != sizeof (struct UDPAck)) ) 2509 (ntohs (msg->size) != sizeof (struct UDPAck)) )
@@ -2480,7 +2526,7 @@ enc_notify_cb (void *cls,
2480 * @param cls closure 2526 * @param cls closure
2481 * @param app_ctx[in,out] location where the app can store stuff 2527 * @param app_ctx[in,out] location where the app can store stuff
2482 * on add and retrieve it on remove 2528 * on add and retrieve it on remove
2483 * @param add_remove #GNUNET_YES to add a new public IP address, 2529 * @param add_remove #GNUNET_YES to add a new public IP address,
2484 * #GNUNET_NO to remove a previous (now invalid) one 2530 * #GNUNET_NO to remove a previous (now invalid) one
2485 * @param ac address class the address belongs to 2531 * @param ac address class the address belongs to
2486 * @param addr either the previous or the new public IP address 2532 * @param addr either the previous or the new public IP address
@@ -2502,13 +2548,13 @@ nat_address_cb (void *cls,
2502 enum GNUNET_NetworkType nt; 2548 enum GNUNET_NetworkType nt;
2503 2549
2504 GNUNET_asprintf (&my_addr, 2550 GNUNET_asprintf (&my_addr,
2505 "%s-%s", 2551 "%s-%s",
2506 COMMUNICATOR_ADDRESS_PREFIX, 2552 COMMUNICATOR_ADDRESS_PREFIX,
2507 GNUNET_a2s (addr, 2553 GNUNET_a2s (addr,
2508 addrlen)); 2554 addrlen));
2509 nt = GNUNET_NT_scanner_get_type (is, 2555 nt = GNUNET_NT_scanner_get_type (is,
2510 addr, 2556 addr,
2511 addrlen); 2557 addrlen);
2512 ai = GNUNET_TRANSPORT_communicator_address_add (ch, 2558 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2513 my_addr, 2559 my_addr,
2514 nt, 2560 nt,
@@ -2543,14 +2589,14 @@ ifc_broadcast (void *cls)
2543 = GNUNET_SCHEDULER_add_delayed (INTERFACE_SCAN_FREQUENCY, 2589 = GNUNET_SCHEDULER_add_delayed (INTERFACE_SCAN_FREQUENCY,
2544 &ifc_broadcast, 2590 &ifc_broadcast,
2545 bi); 2591 bi);
2546 2592
2547 switch (bi->sa->sa_family) { 2593 switch (bi->sa->sa_family) {
2548 case AF_INET: 2594 case AF_INET:
2549 { 2595 {
2550 static int yes = 1; 2596 static int yes = 1;
2551 static int no = 0; 2597 static int no = 0;
2552 ssize_t sent; 2598 ssize_t sent;
2553 2599
2554 if (GNUNET_OK != 2600 if (GNUNET_OK !=
2555 GNUNET_NETWORK_socket_setsockopt (udp_sock, 2601 GNUNET_NETWORK_socket_setsockopt (udp_sock,
2556 SOL_SOCKET, 2602 SOL_SOCKET,
@@ -2660,7 +2706,7 @@ iface_proc (void *cls,
2660 if ( (AF_INET6 == addr->sa_family) && 2706 if ( (AF_INET6 == addr->sa_family) &&
2661 (GNUNET_YES != have_v6_socket) ) 2707 (GNUNET_YES != have_v6_socket) )
2662 return GNUNET_OK; /* not using IPv6 */ 2708 return GNUNET_OK; /* not using IPv6 */
2663 2709
2664 bi = GNUNET_new (struct BroadcastInterface); 2710 bi = GNUNET_new (struct BroadcastInterface);
2665 bi->sa = GNUNET_memdup (addr, 2711 bi->sa = GNUNET_memdup (addr,
2666 addrlen); 2712 addrlen);
@@ -2696,7 +2742,7 @@ iface_proc (void *cls,
2696 inet_pton (AF_INET6, 2742 inet_pton (AF_INET6,
2697 "FF05::13B", 2743 "FF05::13B",
2698 &bi->mcreq.ipv6mr_multiaddr)); 2744 &bi->mcreq.ipv6mr_multiaddr));
2699 2745
2700 /* http://tools.ietf.org/html/rfc2553#section-5.2: 2746 /* http://tools.ietf.org/html/rfc2553#section-5.2:
2701 * 2747 *
2702 * IPV6_JOIN_GROUP 2748 * IPV6_JOIN_GROUP
@@ -2736,7 +2782,7 @@ static void
2736do_broadcast (void *cls) 2782do_broadcast (void *cls)
2737{ 2783{
2738 struct BroadcastInterface *bin; 2784 struct BroadcastInterface *bin;
2739 2785
2740 (void) cls; 2786 (void) cls;
2741 for (struct BroadcastInterface *bi = bi_head; 2787 for (struct BroadcastInterface *bi = bi_head;
2742 NULL != bi; 2788 NULL != bi;
@@ -2778,7 +2824,7 @@ run (void *cls,
2778 socklen_t in_len; 2824 socklen_t in_len;
2779 struct sockaddr_storage in_sto; 2825 struct sockaddr_storage in_sto;
2780 socklen_t sto_len; 2826 socklen_t sto_len;
2781 2827
2782 (void) cls; 2828 (void) cls;
2783 cfg = c; 2829 cfg = c;
2784 if (GNUNET_OK != 2830 if (GNUNET_OK !=
@@ -2794,7 +2840,7 @@ run (void *cls,
2794 } 2840 }
2795 2841
2796 in = udp_address_to_sockaddr (bindto, 2842 in = udp_address_to_sockaddr (bindto,
2797 &in_len); 2843 &in_len);
2798 if (NULL == in) 2844 if (NULL == in)
2799 { 2845 {
2800 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2846 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -2804,8 +2850,8 @@ run (void *cls,
2804 return; 2850 return;
2805 } 2851 }
2806 udp_sock = GNUNET_NETWORK_socket_create (in->sa_family, 2852 udp_sock = GNUNET_NETWORK_socket_create (in->sa_family,
2807 SOCK_DGRAM, 2853 SOCK_DGRAM,
2808 IPPROTO_UDP); 2854 IPPROTO_UDP);
2809 if (NULL == udp_sock) 2855 if (NULL == udp_sock)
2810 { 2856 {
2811 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 2857 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
@@ -2819,7 +2865,7 @@ run (void *cls,
2819 if (GNUNET_OK != 2865 if (GNUNET_OK !=
2820 GNUNET_NETWORK_socket_bind (udp_sock, 2866 GNUNET_NETWORK_socket_bind (udp_sock,
2821 in, 2867 in,
2822 in_len)) 2868 in_len))
2823 { 2869 {
2824 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 2870 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2825 "bind", 2871 "bind",
@@ -2834,12 +2880,12 @@ run (void *cls,
2834 thus, get the real IN-address from the socket */ 2880 thus, get the real IN-address from the socket */
2835 sto_len = sizeof (in_sto); 2881 sto_len = sizeof (in_sto);
2836 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock), 2882 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
2837 (struct sockaddr *) &in_sto, 2883 (struct sockaddr *) &in_sto,
2838 &sto_len)) 2884 &sto_len))
2839 { 2885 {
2840 memcpy (&in_sto, 2886 memcpy (&in_sto,
2841 in, 2887 in,
2842 in_len); 2888 in_len);
2843 sto_len = in_len; 2889 sto_len = in_len;
2844 } 2890 }
2845 GNUNET_free (in); 2891 GNUNET_free (in);
@@ -2847,9 +2893,9 @@ run (void *cls,
2847 in = (struct sockaddr *) &in_sto; 2893 in = (struct sockaddr *) &in_sto;
2848 in_len = sto_len; 2894 in_len = sto_len;
2849 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2850 "Bound to `%s'\n", 2896 "Bound to `%s'\n",
2851 GNUNET_a2s ((const struct sockaddr *) &in_sto, 2897 GNUNET_a2s ((const struct sockaddr *) &in_sto,
2852 sto_len)); 2898 sto_len));
2853 switch (in->sa_family) 2899 switch (in->sa_family)
2854 { 2900 {
2855 case AF_INET: 2901 case AF_INET:
@@ -2863,17 +2909,17 @@ run (void *cls,
2863 my_port = 0; 2909 my_port = 0;
2864 } 2910 }
2865 stats = GNUNET_STATISTICS_create ("C-UDP", 2911 stats = GNUNET_STATISTICS_create ("C-UDP",
2866 cfg); 2912 cfg);
2867 senders = GNUNET_CONTAINER_multipeermap_create (32, 2913 senders = GNUNET_CONTAINER_multipeermap_create (32,
2868 GNUNET_YES); 2914 GNUNET_YES);
2869 receivers = GNUNET_CONTAINER_multipeermap_create (32, 2915 receivers = GNUNET_CONTAINER_multipeermap_create (32,
2870 GNUNET_YES); 2916 GNUNET_YES);
2871 senders_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 2917 senders_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2872 receivers_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 2918 receivers_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2873 key_cache = GNUNET_CONTAINER_multishortmap_create (1024, 2919 key_cache = GNUNET_CONTAINER_multishortmap_create (1024,
2874 GNUNET_YES); 2920 GNUNET_YES);
2875 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 2921 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
2876 NULL); 2922 NULL);
2877 is = GNUNET_NT_scanner_init (); 2923 is = GNUNET_NT_scanner_init ();
2878 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); 2924 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2879 if (NULL == my_private_key) 2925 if (NULL == my_private_key)
@@ -2887,15 +2933,15 @@ run (void *cls,
2887 &my_identity.public_key); 2933 &my_identity.public_key);
2888 /* start reading */ 2934 /* start reading */
2889 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2935 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2890 udp_sock, 2936 udp_sock,
2891 &sock_read, 2937 &sock_read,
2892 NULL); 2938 NULL);
2893 ch = GNUNET_TRANSPORT_communicator_connect (cfg, 2939 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2894 COMMUNICATOR_CONFIG_SECTION, 2940 COMMUNICATOR_CONFIG_SECTION,
2895 COMMUNICATOR_ADDRESS_PREFIX, 2941 COMMUNICATOR_ADDRESS_PREFIX,
2896 GNUNET_TRANSPORT_CC_UNRELIABLE, 2942 GNUNET_TRANSPORT_CC_UNRELIABLE,
2897 &mq_init, 2943 &mq_init,
2898 NULL, 2944 NULL,
2899 &enc_notify_cb, 2945 &enc_notify_cb,
2900 NULL); 2946 NULL);
2901 if (NULL == ch) 2947 if (NULL == ch)
@@ -2904,24 +2950,31 @@ run (void *cls,
2904 GNUNET_SCHEDULER_shutdown (); 2950 GNUNET_SCHEDULER_shutdown ();
2905 return; 2951 return;
2906 } 2952 }
2953 ah = GNUNET_TRANSPORT_application_init (cfg);
2954 if (NULL == ah)
2955 {
2956 GNUNET_break (0);
2957 GNUNET_SCHEDULER_shutdown ();
2958 return;
2959 }
2907 /* start broadcasting */ 2960 /* start broadcasting */
2908 if (GNUNET_YES != 2961 if (GNUNET_YES !=
2909 GNUNET_CONFIGURATION_get_value_yesno (cfg, 2962 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2910 COMMUNICATOR_CONFIG_SECTION, 2963 COMMUNICATOR_CONFIG_SECTION,
2911 "DISABLE_BROADCAST")) 2964 "DISABLE_BROADCAST"))
2912 { 2965 {
2913 broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast, 2966 broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast,
2914 NULL); 2967 NULL);
2915 } 2968 }
2916 nat = GNUNET_NAT_register (cfg, 2969 nat = GNUNET_NAT_register (cfg,
2917 COMMUNICATOR_CONFIG_SECTION, 2970 COMMUNICATOR_CONFIG_SECTION,
2918 IPPROTO_UDP, 2971 IPPROTO_UDP,
2919 1 /* one address */, 2972 1 /* one address */,
2920 (const struct sockaddr **) &in, 2973 (const struct sockaddr **) &in,
2921 &in_len, 2974 &in_len,
2922 &nat_address_cb, 2975 &nat_address_cb,
2923 NULL /* FIXME: support reversal: #5529 */, 2976 NULL /* FIXME: support reversal: #5529 */,
2924 NULL /* closure */); 2977 NULL /* closure */);
2925} 2978}
2926 2979
2927 2980
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 6494a5dfd..4d4ac509a 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -35,19 +35,13 @@
35 * Implement next: 35 * Implement next:
36 * - address validation: what is our plan here? 36 * - address validation: what is our plan here?
37 * #1 Peerstore only gets 'validated' addresses 37 * #1 Peerstore only gets 'validated' addresses
38 * #2 transport needs another API to "trigger" validation! 38 * #2 transport should use validation to also establish
39 * API may be used by core/application or communicators;
40 * => use yet another lib/MQ/connection?
41 * #3 transport should use validation to also establish
42 * effective flow control (for uni-directional transports!) 39 * effective flow control (for uni-directional transports!)
43 * #4 UDP broadcasting logic must be extended to use the new API 40 * #3 only validated addresses are selected for scheduling; that
44 * #5 only validated addresses are selected for scheduling; that
45 * also ensures we know the RTT 41 * also ensures we know the RTT
46 * #6 to ensure flow control and RTT are OK, we always do the 42 * #4 to ensure flow control and RTT are OK, we always do the
47 * 'validation', even if address comes from PEERSTORE 43 * 'validation', even if address comes from PEERSTORE
48 * #7
49 * - ACK handling / retransmission 44 * - ACK handling / retransmission
50 * - address verification
51 * - track RTT, distance, loss, etc. 45 * - track RTT, distance, loss, etc.
52 * - DV data structures: 46 * - DV data structures:
53 * + learning 47 * + learning
@@ -56,10 +50,6 @@
56 * - routing of messages (using DV data structures!) 50 * - routing of messages (using DV data structures!)
57 * - handling of DV-boxed messages that need to be forwarded 51 * - handling of DV-boxed messages that need to be forwarded
58 * - backchannel message encryption & decryption 52 * - backchannel message encryption & decryption
59 * -
60 *
61 * Easy:
62 * - figure out how to call XXX_suggestion_cb!
63 * 53 *
64 * Later: 54 * Later:
65 * - change transport-core API to provide proper flow control in both 55 * - change transport-core API to provide proper flow control in both
@@ -1680,8 +1670,6 @@ notify_monitors (const struct GNUNET_PeerIdentity *peer,
1680 enum GNUNET_NetworkType nt, 1670 enum GNUNET_NetworkType nt,
1681 const struct MonitorEvent *me) 1671 const struct MonitorEvent *me)
1682{ 1672{
1683 static struct GNUNET_PeerIdentity zero;
1684
1685 for (struct TransportClient *tc = clients_head; 1673 for (struct TransportClient *tc = clients_head;
1686 NULL != tc; 1674 NULL != tc;
1687 tc = tc->next) 1675 tc = tc->next)
@@ -1690,12 +1678,9 @@ notify_monitors (const struct GNUNET_PeerIdentity *peer,
1690 continue; 1678 continue;
1691 if (tc->details.monitor.one_shot) 1679 if (tc->details.monitor.one_shot)
1692 continue; 1680 continue;
1693 if ( (0 != memcmp (&tc->details.monitor.peer, 1681 if ( (0 != GNUNET_is_zero (&tc->details.monitor.peer)) &&
1694 &zero, 1682 (0 != GNUNET_memcmp (&tc->details.monitor.peer,
1695 sizeof (zero))) && 1683 peer)) )
1696 (0 != memcmp (&tc->details.monitor.peer,
1697 peer,
1698 sizeof (*peer))) )
1699 continue; 1684 continue;
1700 notify_monitor (tc, 1685 notify_monitor (tc,
1701 peer, 1686 peer,
@@ -2220,9 +2205,8 @@ handle_client_start (void *cls,
2220 options = ntohl (start->options); 2205 options = ntohl (start->options);
2221 if ( (0 != (1 & options)) && 2206 if ( (0 != (1 & options)) &&
2222 (0 != 2207 (0 !=
2223 memcmp (&start->self, 2208 GNUNET_memcmp (&start->self,
2224 &GST_my_identity, 2209 &GST_my_identity)) )
2225 sizeof (struct GNUNET_PeerIdentity)) ) )
2226 { 2210 {
2227 /* client thinks this is a different peer, reject */ 2211 /* client thinks this is a different peer, reject */
2228 GNUNET_break (0); 2212 GNUNET_break (0);
@@ -2612,8 +2596,8 @@ expire_ephemerals (void *cls)
2612 continue; 2596 continue;
2613 } 2597 }
2614 ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity, 2598 ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
2615 &expire_ephemerals, 2599 &expire_ephemerals,
2616 NULL); 2600 NULL);
2617 return; 2601 return;
2618 } 2602 }
2619} 2603}
@@ -2640,7 +2624,7 @@ lookup_ephemeral (const struct GNUNET_PeerIdentity *pid,
2640 struct EphemeralConfirmation ec; 2624 struct EphemeralConfirmation ec;
2641 2625
2642 ece = GNUNET_CONTAINER_multipeermap_get (ephemeral_map, 2626 ece = GNUNET_CONTAINER_multipeermap_get (ephemeral_map,
2643 pid); 2627 pid);
2644 if ( (NULL != ece) && 2628 if ( (NULL != ece) &&
2645 (0 == GNUNET_TIME_absolute_get_remaining (ece->ephemeral_validity).rel_value_us) ) 2629 (0 == GNUNET_TIME_absolute_get_remaining (ece->ephemeral_validity).rel_value_us) )
2646 { 2630 {
@@ -2652,27 +2636,27 @@ lookup_ephemeral (const struct GNUNET_PeerIdentity *pid,
2652 ece = GNUNET_new (struct EphemeralCacheEntry); 2636 ece = GNUNET_new (struct EphemeralCacheEntry);
2653 ece->target = *pid; 2637 ece->target = *pid;
2654 ece->ephemeral_validity = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get_monotonic (GST_cfg), 2638 ece->ephemeral_validity = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get_monotonic (GST_cfg),
2655 EPHEMERAL_VALIDITY); 2639 EPHEMERAL_VALIDITY);
2656 GNUNET_assert (GNUNET_OK == 2640 GNUNET_assert (GNUNET_OK ==
2657 GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key)); 2641 GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key));
2658 GNUNET_CRYPTO_ecdhe_key_get_public (&ece->private_key, 2642 GNUNET_CRYPTO_ecdhe_key_get_public (&ece->private_key,
2659 &ece->ephemeral_key); 2643 &ece->ephemeral_key);
2660 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL); 2644 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
2661 ec.purpose.size = htonl (sizeof (ec)); 2645 ec.purpose.size = htonl (sizeof (ec));
2662 ec.target = *pid; 2646 ec.target = *pid;
2663 ec.ephemeral_key = ece->ephemeral_key; 2647 ec.ephemeral_key = ece->ephemeral_key;
2664 GNUNET_assert (GNUNET_OK == 2648 GNUNET_assert (GNUNET_OK ==
2665 GNUNET_CRYPTO_eddsa_sign (GST_my_private_key, 2649 GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
2666 &ec.purpose, 2650 &ec.purpose,
2667 &ece->sender_sig)); 2651 &ece->sender_sig));
2668 ece->hn = GNUNET_CONTAINER_heap_insert (ephemeral_heap, 2652 ece->hn = GNUNET_CONTAINER_heap_insert (ephemeral_heap,
2669 ece, 2653 ece,
2670 ece->ephemeral_validity.abs_value_us); 2654 ece->ephemeral_validity.abs_value_us);
2671 GNUNET_assert (GNUNET_OK == 2655 GNUNET_assert (GNUNET_OK ==
2672 GNUNET_CONTAINER_multipeermap_put (ephemeral_map, 2656 GNUNET_CONTAINER_multipeermap_put (ephemeral_map,
2673 &ece->target, 2657 &ece->target,
2674 ece, 2658 ece,
2675 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 2659 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2676 if (NULL == ephemeral_task) 2660 if (NULL == ephemeral_task)
2677 ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity, 2661 ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
2678 &expire_ephemerals, 2662 &expire_ephemerals,
@@ -2726,34 +2710,34 @@ handle_communicator_backchannel (void *cls,
2726 enc->header.size = htons (sizeof (*enc) + msize); 2710 enc->header.size = htons (sizeof (*enc) + msize);
2727 enc->target = cb->pid; 2711 enc->target = cb->pid;
2728 lookup_ephemeral (&cb->pid, 2712 lookup_ephemeral (&cb->pid,
2729 &private_key, 2713 &private_key,
2730 &enc->ephemeral_key, 2714 &enc->ephemeral_key,
2731 &ppay.sender_sig, 2715 &ppay.sender_sig,
2732 &ephemeral_validity); 2716 &ephemeral_validity);
2733 // FIXME: setup 'iv' 2717 // FIXME: setup 'iv'
2734#if FIXME 2718#if FIXME
2735 dh_key_derive (&private_key, 2719 dh_key_derive (&private_key,
2736 &cb->pid, 2720 &cb->pid,
2737 &enc->iv, 2721 &enc->iv,
2738 &key); 2722 &key);
2739#endif 2723#endif
2740 ppay.ephemeral_validity = GNUNET_TIME_absolute_hton (ephemeral_validity); 2724 ppay.ephemeral_validity = GNUNET_TIME_absolute_hton (ephemeral_validity);
2741 ppay.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (GST_cfg)); 2725 ppay.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (GST_cfg));
2742 mpos = (char *) &enc[1]; 2726 mpos = (char *) &enc[1];
2743#if FIXME 2727#if FIXME
2744 encrypt (key, 2728 encrypt (key,
2745 &ppay, 2729 &ppay,
2746 &mpos, 2730 &mpos,
2747 sizeof (ppay)); 2731 sizeof (ppay));
2748 encrypt (key, 2732 encrypt (key,
2749 &cb[1], 2733 &cb[1],
2750 &mpos, 2734 &mpos,
2751 ntohs (cb->header.size) - sizeof (*cb)); 2735 ntohs (cb->header.size) - sizeof (*cb));
2752 hmac (key, 2736 hmac (key,
2753 &enc->hmac); 2737 &enc->hmac);
2754#endif 2738#endif
2755 route_message (&cb->pid, 2739 route_message (&cb->pid,
2756 &enc->header); 2740 &enc->header);
2757 GNUNET_SERVICE_client_continue (tc->client); 2741 GNUNET_SERVICE_client_continue (tc->client);
2758} 2742}
2759 2743
@@ -2802,14 +2786,14 @@ peerstore_store_cb (void *cls,
2802 ale->sc = NULL; 2786 ale->sc = NULL;
2803 if (GNUNET_YES != success) 2787 if (GNUNET_YES != success)
2804 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2788 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2805 "Failed to store our own address `%s' in peerstore!\n", 2789 "Failed to store our own address `%s' in peerstore!\n",
2806 ale->address); 2790 ale->address);
2807 /* refresh period is 1/4 of expiration time, that should be plenty 2791 /* refresh period is 1/4 of expiration time, that should be plenty
2808 without being excessive. */ 2792 without being excessive. */
2809 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (ale->expiration, 2793 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (ale->expiration,
2810 4ULL), 2794 4ULL),
2811 &store_pi, 2795 &store_pi,
2812 ale); 2796 ale);
2813} 2797}
2814 2798
2815 2799
@@ -2829,30 +2813,30 @@ store_pi (void *cls)
2829 ale->st = NULL; 2813 ale->st = NULL;
2830 expiration = GNUNET_TIME_relative_to_absolute (ale->expiration); 2814 expiration = GNUNET_TIME_relative_to_absolute (ale->expiration);
2831 GNUNET_HELLO_sign_address (ale->address, 2815 GNUNET_HELLO_sign_address (ale->address,
2832 ale->nt, 2816 ale->nt,
2833 expiration, 2817 expiration,
2834 GST_my_private_key, 2818 GST_my_private_key,
2835 &addr, 2819 &addr,
2836 &addr_len); 2820 &addr_len);
2837 ale->sc = GNUNET_PEERSTORE_store (peerstore, 2821 ale->sc = GNUNET_PEERSTORE_store (peerstore,
2838 "transport", 2822 "transport",
2839 &GST_my_identity, 2823 &GST_my_identity,
2840 GNUNET_HELLO_PEERSTORE_KEY, 2824 GNUNET_HELLO_PEERSTORE_KEY,
2841 addr, 2825 addr,
2842 addr_len, 2826 addr_len,
2843 expiration, 2827 expiration,
2844 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, 2828 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
2845 &peerstore_store_cb, 2829 &peerstore_store_cb,
2846 ale); 2830 ale);
2847 GNUNET_free (addr); 2831 GNUNET_free (addr);
2848 if (NULL == ale->sc) 2832 if (NULL == ale->sc)
2849 { 2833 {
2850 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2834 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2851 "Failed to store our address `%s' with peerstore\n", 2835 "Failed to store our address `%s' with peerstore\n",
2852 ale->address); 2836 ale->address);
2853 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 2837 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
2854 &store_pi, 2838 &store_pi,
2855 ale); 2839 ale);
2856 } 2840 }
2857} 2841}
2858 2842
@@ -2885,7 +2869,7 @@ handle_add_address (void *cls,
2885 tc->details.communicator.addr_tail, 2869 tc->details.communicator.addr_tail,
2886 ale); 2870 ale);
2887 ale->st = GNUNET_SCHEDULER_add_now (&store_pi, 2871 ale->st = GNUNET_SCHEDULER_add_now (&store_pi,
2888 ale); 2872 ale);
2889 GNUNET_SERVICE_client_continue (tc->client); 2873 GNUNET_SERVICE_client_continue (tc->client);
2890} 2874}
2891 2875
@@ -2956,7 +2940,7 @@ struct CommunicatorMessageContext
2956 */ 2940 */
2957static void 2941static void
2958demultiplex_with_cmc (struct CommunicatorMessageContext *cmc, 2942demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
2959 const struct GNUNET_MessageHeader *msg); 2943 const struct GNUNET_MessageHeader *msg);
2960 2944
2961 2945
2962/** 2946/**
@@ -2974,12 +2958,12 @@ finish_cmc_handling (struct CommunicatorMessageContext *cmc)
2974 struct GNUNET_TRANSPORT_IncomingMessageAck *ack; 2958 struct GNUNET_TRANSPORT_IncomingMessageAck *ack;
2975 2959
2976 env = GNUNET_MQ_msg (ack, 2960 env = GNUNET_MQ_msg (ack,
2977 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK); 2961 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK);
2978 ack->reserved = htonl (0); 2962 ack->reserved = htonl (0);
2979 ack->fc_id = cmc->im.fc_id; 2963 ack->fc_id = cmc->im.fc_id;
2980 ack->sender = cmc->im.sender; 2964 ack->sender = cmc->im.sender;
2981 GNUNET_MQ_send (cmc->tc->mq, 2965 GNUNET_MQ_send (cmc->tc->mq,
2982 env); 2966 env);
2983 } 2967 }
2984 GNUNET_SERVICE_client_continue (cmc->tc->client); 2968 GNUNET_SERVICE_client_continue (cmc->tc->client);
2985 GNUNET_free (cmc); 2969 GNUNET_free (cmc);
@@ -2995,7 +2979,7 @@ finish_cmc_handling (struct CommunicatorMessageContext *cmc)
2995 */ 2979 */
2996static void 2980static void
2997handle_raw_message (void *cls, 2981handle_raw_message (void *cls,
2998 const struct GNUNET_MessageHeader *mh) 2982 const struct GNUNET_MessageHeader *mh)
2999{ 2983{
3000 struct CommunicatorMessageContext *cmc = cls; 2984 struct CommunicatorMessageContext *cmc = cls;
3001 uint16_t size = ntohs (mh->size); 2985 uint16_t size = ntohs (mh->size);
@@ -3021,14 +3005,14 @@ handle_raw_message (void *cls,
3021 if (CT_CORE != tc->type) 3005 if (CT_CORE != tc->type)
3022 continue; 3006 continue;
3023 env = GNUNET_MQ_msg_extra (im, 3007 env = GNUNET_MQ_msg_extra (im,
3024 size, 3008 size,
3025 GNUNET_MESSAGE_TYPE_TRANSPORT_RECV); 3009 GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
3026 im->peer = cmc->im.sender; 3010 im->peer = cmc->im.sender;
3027 memcpy (&im[1], 3011 memcpy (&im[1],
3028 mh, 3012 mh,
3029 size); 3013 size);
3030 GNUNET_MQ_send (tc->mq, 3014 GNUNET_MQ_send (tc->mq,
3031 env); 3015 env);
3032 } 3016 }
3033 /* FIXME: consider doing this _only_ once the message 3017 /* FIXME: consider doing this _only_ once the message
3034 was drained from the CORE MQs to extend flow control to CORE! 3018 was drained from the CORE MQs to extend flow control to CORE!
@@ -3046,7 +3030,7 @@ handle_raw_message (void *cls,
3046 */ 3030 */
3047static int 3031static int
3048check_fragment_box (void *cls, 3032check_fragment_box (void *cls,
3049 const struct TransportFragmentBox *fb) 3033 const struct TransportFragmentBox *fb)
3050{ 3034{
3051 uint16_t size = ntohs (fb->header.size); 3035 uint16_t size = ntohs (fb->header.size);
3052 uint16_t bsize = size - sizeof (*fb); 3036 uint16_t bsize = size - sizeof (*fb);
@@ -3124,7 +3108,7 @@ handle_fragment_box (void *cls,
3124 int ack_now; 3108 int ack_now;
3125 3109
3126 n = GNUNET_CONTAINER_multipeermap_get (neighbours, 3110 n = GNUNET_CONTAINER_multipeermap_get (neighbours,
3127 &cmc->im.sender); 3111 &cmc->im.sender);
3128 if (NULL == n) 3112 if (NULL == n)
3129 { 3113 {
3130 struct GNUNET_SERVICE_Client *client = cmc->tc->client; 3114 struct GNUNET_SERVICE_Client *client = cmc->tc->client;
@@ -3137,15 +3121,15 @@ handle_fragment_box (void *cls,
3137 if (NULL == n->reassembly_map) 3121 if (NULL == n->reassembly_map)
3138 { 3122 {
3139 n->reassembly_map = GNUNET_CONTAINER_multishortmap_create (8, 3123 n->reassembly_map = GNUNET_CONTAINER_multishortmap_create (8,
3140 GNUNET_YES); 3124 GNUNET_YES);
3141 n->reassembly_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 3125 n->reassembly_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3142 n->reassembly_timeout_task = GNUNET_SCHEDULER_add_delayed (REASSEMBLY_EXPIRATION, 3126 n->reassembly_timeout_task = GNUNET_SCHEDULER_add_delayed (REASSEMBLY_EXPIRATION,
3143 &reassembly_cleanup_task, 3127 &reassembly_cleanup_task,
3144 n); 3128 n);
3145 } 3129 }
3146 msize = ntohs (fb->msg_size); 3130 msize = ntohs (fb->msg_size);
3147 rc = GNUNET_CONTAINER_multishortmap_get (n->reassembly_map, 3131 rc = GNUNET_CONTAINER_multishortmap_get (n->reassembly_map,
3148 &fb->msg_uuid); 3132 &fb->msg_uuid);
3149 if (NULL == rc) 3133 if (NULL == rc)
3150 { 3134 {
3151 rc = GNUNET_malloc (sizeof (*rc) + 3135 rc = GNUNET_malloc (sizeof (*rc) +
@@ -3157,13 +3141,13 @@ handle_fragment_box (void *cls,
3157 rc->reassembly_timeout = GNUNET_TIME_relative_to_absolute (REASSEMBLY_EXPIRATION); 3141 rc->reassembly_timeout = GNUNET_TIME_relative_to_absolute (REASSEMBLY_EXPIRATION);
3158 rc->last_frag = GNUNET_TIME_absolute_get (); 3142 rc->last_frag = GNUNET_TIME_absolute_get ();
3159 rc->hn = GNUNET_CONTAINER_heap_insert (n->reassembly_heap, 3143 rc->hn = GNUNET_CONTAINER_heap_insert (n->reassembly_heap,
3160 rc, 3144 rc,
3161 rc->reassembly_timeout.abs_value_us); 3145 rc->reassembly_timeout.abs_value_us);
3162 GNUNET_assert (GNUNET_OK == 3146 GNUNET_assert (GNUNET_OK ==
3163 GNUNET_CONTAINER_multishortmap_put (n->reassembly_map, 3147 GNUNET_CONTAINER_multishortmap_put (n->reassembly_map,
3164 &rc->msg_uuid, 3148 &rc->msg_uuid,
3165 rc, 3149 rc,
3166 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 3150 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3167 target = (char *) &rc[1]; 3151 target = (char *) &rc[1];
3168 rc->bitfield = (uint8_t *) (target + rc->msg_size); 3152 rc->bitfield = (uint8_t *) (target + rc->msg_size);
3169 rc->msg_missing = rc->msg_size; 3153 rc->msg_missing = rc->msg_size;
@@ -3183,8 +3167,8 @@ handle_fragment_box (void *cls,
3183 fsize = ntohs (fb->header.size) - sizeof (*fb); 3167 fsize = ntohs (fb->header.size) - sizeof (*fb);
3184 frag_off = ntohs (fb->frag_off); 3168 frag_off = ntohs (fb->frag_off);
3185 memcpy (&target[frag_off], 3169 memcpy (&target[frag_off],
3186 &fb[1], 3170 &fb[1],
3187 fsize); 3171 fsize);
3188 /* update bitfield and msg_missing */ 3172 /* update bitfield and msg_missing */
3189 for (unsigned int i=frag_off;i<frag_off+fsize;i++) 3173 for (unsigned int i=frag_off;i<frag_off+fsize;i++)
3190 { 3174 {
@@ -3199,10 +3183,10 @@ handle_fragment_box (void *cls,
3199 frag_uuid = ntohl (fb->frag_uuid); 3183 frag_uuid = ntohl (fb->frag_uuid);
3200 cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag); 3184 cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag);
3201 cdelay = GNUNET_TIME_relative_multiply (cdelay, 3185 cdelay = GNUNET_TIME_relative_multiply (cdelay,
3202 rc->num_acks); 3186 rc->num_acks);
3203 rc->last_frag = GNUNET_TIME_absolute_get (); 3187 rc->last_frag = GNUNET_TIME_absolute_get ();
3204 rc->avg_ack_delay = GNUNET_TIME_relative_add (rc->avg_ack_delay, 3188 rc->avg_ack_delay = GNUNET_TIME_relative_add (rc->avg_ack_delay,
3205 cdelay); 3189 cdelay);
3206 ack_now = GNUNET_NO; 3190 ack_now = GNUNET_NO;
3207 if (0 == rc->num_acks) 3191 if (0 == rc->num_acks)
3208 { 3192 {
@@ -3266,7 +3250,7 @@ handle_fragment_box (void *cls,
3266 /* successful reassembly */ 3250 /* successful reassembly */
3267 send_fragment_ack (rc); 3251 send_fragment_ack (rc);
3268 demultiplex_with_cmc (cmc, 3252 demultiplex_with_cmc (cmc,
3269 msg); 3253 msg);
3270 /* FIXME: really free here? Might be bad if fragments are still 3254 /* FIXME: really free here? Might be bad if fragments are still
3271 en-route and we forget that we finished this reassembly immediately! 3255 en-route and we forget that we finished this reassembly immediately!
3272 -> keep around until timeout? 3256 -> keep around until timeout?
@@ -3304,7 +3288,7 @@ handle_fragment_ack (void *cls,
3304 */ 3288 */
3305static int 3289static int
3306check_reliability_box (void *cls, 3290check_reliability_box (void *cls,
3307 const struct TransportReliabilityBox *rb) 3291 const struct TransportReliabilityBox *rb)
3308{ 3292{
3309 GNUNET_MQ_check_boxed_message (rb); 3293 GNUNET_MQ_check_boxed_message (rb);
3310 return GNUNET_YES; 3294 return GNUNET_YES;
@@ -3319,7 +3303,7 @@ check_reliability_box (void *cls,
3319 */ 3303 */
3320static void 3304static void
3321handle_reliability_box (void *cls, 3305handle_reliability_box (void *cls,
3322 const struct TransportReliabilityBox *rb) 3306 const struct TransportReliabilityBox *rb)
3323{ 3307{
3324 struct CommunicatorMessageContext *cmc = cls; 3308 struct CommunicatorMessageContext *cmc = cls;
3325 const struct GNUNET_MessageHeader *inbox = (const struct GNUNET_MessageHeader *) &rb[1]; 3309 const struct GNUNET_MessageHeader *inbox = (const struct GNUNET_MessageHeader *) &rb[1];
@@ -3331,10 +3315,10 @@ handle_reliability_box (void *cls,
3331 /* FIXME: implement cummulative ACKs and ack_countdown, 3315 /* FIXME: implement cummulative ACKs and ack_countdown,
3332 then setting the avg_ack_delay field below: */ 3316 then setting the avg_ack_delay field below: */
3333 ack = GNUNET_malloc (sizeof (*ack) + 3317 ack = GNUNET_malloc (sizeof (*ack) +
3334 sizeof (struct GNUNET_ShortHashCode)); 3318 sizeof (struct GNUNET_ShortHashCode));
3335 ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK); 3319 ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK);
3336 ack->header.size = htons (sizeof (*ack) + 3320 ack->header.size = htons (sizeof (*ack) +
3337 sizeof (struct GNUNET_ShortHashCode)); 3321 sizeof (struct GNUNET_ShortHashCode));
3338 memcpy (&ack[1], 3322 memcpy (&ack[1],
3339 &rb->msg_uuid, 3323 &rb->msg_uuid,
3340 sizeof (struct GNUNET_ShortHashCode)); 3324 sizeof (struct GNUNET_ShortHashCode));
@@ -3399,13 +3383,12 @@ handle_backchannel_encapsulation (void *cls,
3399{ 3383{
3400 struct CommunicatorMessageContext *cmc = cls; 3384 struct CommunicatorMessageContext *cmc = cls;
3401 3385
3402 if (0 != memcmp (&be->target, 3386 if (0 != GNUNET_memcmp (&be->target,
3403 &GST_my_identity, 3387 &GST_my_identity))
3404 sizeof (struct GNUNET_PeerIdentity)))
3405 { 3388 {
3406 /* not for me, try to route to target */ 3389 /* not for me, try to route to target */
3407 route_message (&be->target, 3390 route_message (&be->target,
3408 GNUNET_copy_message (&be->header)); 3391 GNUNET_copy_message (&be->header));
3409 finish_cmc_handling (cmc); 3392 finish_cmc_handling (cmc);
3410 return; 3393 return;
3411 } 3394 }
@@ -3440,16 +3423,14 @@ check_dv_learn (void *cls,
3440 } 3423 }
3441 for (unsigned int i=0;i<num_hops;i++) 3424 for (unsigned int i=0;i<num_hops;i++)
3442 { 3425 {
3443 if (0 == memcmp (&dvl->initiator, 3426 if (0 == GNUNET_memcmp (&dvl->initiator,
3444 &hops[i], 3427 &hops[i]))
3445 sizeof (struct GNUNET_PeerIdentity)))
3446 { 3428 {
3447 GNUNET_break_op (0); 3429 GNUNET_break_op (0);
3448 return GNUNET_SYSERR; 3430 return GNUNET_SYSERR;
3449 } 3431 }
3450 if (0 == memcmp (&GST_my_identity, 3432 if (0 == GNUNET_memcmp (&GST_my_identity,
3451 &hops[i], 3433 &hops[i]))
3452 sizeof (struct GNUNET_PeerIdentity)))
3453 { 3434 {
3454 GNUNET_break_op (0); 3435 GNUNET_break_op (0);
3455 return GNUNET_SYSERR; 3436 return GNUNET_SYSERR;
@@ -4249,9 +4230,8 @@ handle_del_queue_message (void *cls,
4249 struct Neighbour *neighbour = queue->neighbour; 4230 struct Neighbour *neighbour = queue->neighbour;
4250 4231
4251 if ( (dqm->qid != queue->qid) || 4232 if ( (dqm->qid != queue->qid) ||
4252 (0 != memcmp (&dqm->receiver, 4233 (0 != GNUNET_memcmp (&dqm->receiver,
4253 &neighbour->pid, 4234 &neighbour->pid)) )
4254 sizeof (struct GNUNET_PeerIdentity))) )
4255 continue; 4235 continue;
4256 free_queue (queue); 4236 free_queue (queue);
4257 GNUNET_SERVICE_client_continue (tc->client); 4237 GNUNET_SERVICE_client_continue (tc->client);
@@ -4288,9 +4268,8 @@ handle_send_message_ack (void *cls,
4288 NULL != queue; 4268 NULL != queue;
4289 queue = queue->next_client) 4269 queue = queue->next_client)
4290 { 4270 {
4291 if (0 != memcmp (&queue->neighbour->pid, 4271 if (0 != GNUNET_memcmp (&queue->neighbour->pid,
4292 &sma->receiver, 4272 &sma->receiver))
4293 sizeof (struct GNUNET_PeerIdentity)))
4294 continue; 4273 continue;
4295 for (struct QueueEntry *qep = queue->queue_head; 4274 for (struct QueueEntry *qep = queue->queue_head;
4296 NULL != qep; 4275 NULL != qep;
@@ -4490,10 +4469,10 @@ suggest_to_connect (const struct GNUNET_PeerIdentity *pid,
4490 cqm->request_id = htonl (idgen++); 4469 cqm->request_id = htonl (idgen++);
4491 cqm->receiver = *pid; 4470 cqm->receiver = *pid;
4492 memcpy (&cqm[1], 4471 memcpy (&cqm[1],
4493 address, 4472 address,
4494 alen); 4473 alen);
4495 GNUNET_MQ_send (tc->mq, 4474 GNUNET_MQ_send (tc->mq,
4496 env); 4475 env);
4497} 4476}
4498 4477
4499 4478
@@ -4642,7 +4621,7 @@ handle_suggest (void *cls,
4642 pr->wc = GNUNET_PEERSTORE_watch (peerstore, 4621 pr->wc = GNUNET_PEERSTORE_watch (peerstore,
4643 "transport", 4622 "transport",
4644 &pr->pid, 4623 &pr->pid,
4645 "hello", 4624 GNUNET_HELLO_PEERSTORE_KEY,
4646 &handle_hello, 4625 &handle_hello,
4647 pr); 4626 pr);
4648 GNUNET_SERVICE_client_continue (tc->client); 4627 GNUNET_SERVICE_client_continue (tc->client);
@@ -4738,6 +4717,38 @@ handle_address_consider_verify (void *cls,
4738 4717
4739 4718
4740/** 4719/**
4720 * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION
4721 * messages.
4722 *
4723 * @param cls a `struct TransportClient *`
4724 * @param m message to verify
4725 * @return #GNUNET_OK on success
4726 */
4727static int
4728check_request_hello_validation (void *cls,
4729 const struct RequestHelloValidationMessage *m)
4730{
4731 GNUNET_MQ_check_zero_termination (m);
4732 return GNUNET_OK;
4733}
4734
4735
4736/**
4737 * A client encountered an address of another peer. Consider validating it,
4738 * and if validation succeeds, persist it to PEERSTORE.
4739 *
4740 * @param cls a `struct TransportClient *`
4741 * @param m message to verify
4742 */
4743static void
4744handle_request_hello_validation (void *cls,
4745 const struct RequestHelloValidationMessage *m)
4746{
4747 // FIXME: implement validation!
4748}
4749
4750
4751/**
4741 * Free neighbour entry. 4752 * Free neighbour entry.
4742 * 4753 *
4743 * @param cls NULL 4754 * @param cls NULL
@@ -4927,6 +4938,10 @@ GNUNET_SERVICE_MAIN
4927 GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL, 4938 GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL,
4928 struct ExpressPreferenceMessage, 4939 struct ExpressPreferenceMessage,
4929 NULL), 4940 NULL),
4941 GNUNET_MQ_hd_var_size (request_hello_validation,
4942 GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION,
4943 struct RequestHelloValidationMessage,
4944 NULL),
4930 /* communication with core */ 4945 /* communication with core */
4931 GNUNET_MQ_hd_fixed_size (client_start, 4946 GNUNET_MQ_hd_fixed_size (client_start,
4932 GNUNET_MESSAGE_TYPE_TRANSPORT_START, 4947 GNUNET_MESSAGE_TYPE_TRANSPORT_START,
diff --git a/src/transport/transport.h b/src/transport/transport.h
index b231ea8ae..fe1044383 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -1139,6 +1139,37 @@ struct ExpressPreferenceMessage
1139}; 1139};
1140 1140
1141 1141
1142/**
1143 * We got an address of another peer, TRANSPORT service
1144 * should validate it. There is no response.
1145 */
1146struct RequestHelloValidationMessage
1147{
1148
1149 /**
1150 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION.
1151 */
1152 struct GNUNET_MessageHeader header;
1153
1154 /**
1155 * What type of network does the other peer claim this is?
1156 * A `enum GNUNET_NetworkType` in NBO.
1157 */
1158 uint32_t nt GNUNET_PACKED;
1159
1160 /**
1161 * Peer to the address is presumably for.
1162 */
1163 struct GNUNET_PeerIdentity peer;
1164
1165 /**
1166 * When does the address expire?
1167 */
1168 struct GNUNET_TIME_AbsoluteNBO expiration;
1169
1170 /* followed by 0-terminated address to validate */
1171};
1172
1142#endif 1173#endif
1143 1174
1144GNUNET_NETWORK_STRUCT_END 1175GNUNET_NETWORK_STRUCT_END
diff --git a/src/transport/transport_api2_application.c b/src/transport/transport_api2_application.c
index 325438e11..414a21fe4 100644
--- a/src/transport/transport_api2_application.c
+++ b/src/transport/transport_api2_application.c
@@ -363,4 +363,56 @@ GNUNET_TRANSPORT_application_suggest_cancel (struct GNUNET_TRANSPORT_Application
363} 363}
364 364
365 365
366
367/**
368 * An application (or a communicator) has received a HELLO (or other address
369 * data of another peer) and wants TRANSPORT to validate that the address is
370 * correct. The result is NOT returned, in fact TRANSPORT may do nothing
371 * (i.e. if it has too many active validations or recently tried this one
372 * already). If the @a addr validates, TRANSPORT will persist the address
373 * with PEERSTORE.
374 *
375 * @param ch handle
376 * @param peer identity of the peer we have an address for
377 * @param expiration when does @a addr expire; used by TRANSPORT to know when
378 * to definitively give up attempting to validate
379 * @param nt network type of @a addr (as claimed by the other peer);
380 * used by TRANSPORT to avoid trying @a addr's that really cannot work
381 * due to network type missmatches
382 * @param addr address to validate
383 */
384void
385GNUNET_TRANSPORT_application_validate (struct GNUNET_TRANSPORT_ApplicationHandle *ch,
386 const struct GNUNET_PeerIdentity *peer,
387 struct GNUNET_TIME_Absolute expiration,
388 enum GNUNET_NetworkType nt,
389 const char *addr)
390{
391 struct GNUNET_MQ_Envelope *ev;
392 struct RequestHelloValidationMessage *m;
393 size_t alen;
394
395 if (NULL == ch->mq)
396 {
397 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
398 "Address validation for %s:%s skipped as transport is not connected\n",
399 GNUNET_i2s (peer),
400 addr);
401 return;
402 }
403 alen = strlen (addr) + 1;
404 ev = GNUNET_MQ_msg_extra (m,
405 alen,
406 GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION);
407 m->peer = *peer;
408 m->expiration = GNUNET_TIME_absolute_hton (expiration);
409 m->nt = htonl ((uint32_t) nt);
410 memcpy (&m[1],
411 addr,
412 alen);
413 GNUNET_MQ_send (ch->mq,
414 ev);
415}
416
417
366/* end of transport_api2_application.c */ 418/* end of transport_api2_application.c */
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 60f0b2e8b..de30cab3a 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -1462,11 +1462,17 @@ GNUNET_a2s (const struct sockaddr *addr,
1462 if (addrlen != sizeof (struct sockaddr_in)) 1462 if (addrlen != sizeof (struct sockaddr_in))
1463 return "<invalid v4 address>"; 1463 return "<invalid v4 address>";
1464 v4 = (const struct sockaddr_in *) addr; 1464 v4 = (const struct sockaddr_in *) addr;
1465 inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN); 1465 inet_ntop (AF_INET,
1466 &v4->sin_addr,
1467 buf,
1468 INET_ADDRSTRLEN);
1466 if (0 == ntohs (v4->sin_port)) 1469 if (0 == ntohs (v4->sin_port))
1467 return buf; 1470 return buf;
1468 strcat (buf, ":"); 1471 strcat (buf, ":");
1469 GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v4->sin_port)); 1472 GNUNET_snprintf (b2,
1473 sizeof (b2),
1474 "%u",
1475 ntohs (v4->sin_port));
1470 strcat (buf, b2); 1476 strcat (buf, b2);
1471 return buf; 1477 return buf;
1472 case AF_INET6: 1478 case AF_INET6:
@@ -1474,12 +1480,19 @@ GNUNET_a2s (const struct sockaddr *addr,
1474 return "<invalid v4 address>"; 1480 return "<invalid v4 address>";
1475 v6 = (const struct sockaddr_in6 *) addr; 1481 v6 = (const struct sockaddr_in6 *) addr;
1476 buf[0] = '['; 1482 buf[0] = '[';
1477 inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN); 1483 inet_ntop (AF_INET6,
1484 &v6->sin6_addr,
1485 &buf[1],
1486 INET6_ADDRSTRLEN);
1478 if (0 == ntohs (v6->sin6_port)) 1487 if (0 == ntohs (v6->sin6_port))
1479 return &buf[1]; 1488 return &buf[1];
1480 strcat (buf, "]:"); 1489 strcat (buf, "]:");
1481 GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v6->sin6_port)); 1490 GNUNET_snprintf (b2,
1482 strcat (buf, b2); 1491 sizeof (b2),
1492 "%u",
1493 ntohs (v6->sin6_port));
1494 strcat (buf,
1495 b2);
1483 return buf; 1496 return buf;
1484 case AF_UNIX: 1497 case AF_UNIX:
1485 if (addrlen <= sizeof (sa_family_t)) 1498 if (addrlen <= sizeof (sa_family_t))