aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/plugin_transport_udp.c816
-rw-r--r--src/transport/plugin_transport_udp.h107
-rw-r--r--src/transport/plugin_transport_unix.c22
3 files changed, 630 insertions, 315 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 08a532aed..37f93f6a7 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -63,16 +63,6 @@
63 */ 63 */
64#define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128 64#define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128
65 65
66/**
67 * Running pretty printers: head
68 */
69static struct PrettyPrinterContext *ppc_dll_head;
70
71/**
72 * Running pretty printers: tail
73 */
74static struct PrettyPrinterContext *ppc_dll_tail;
75
76 66
77/** 67/**
78 * Closure for #append_port(). 68 * Closure for #append_port().
@@ -90,9 +80,9 @@ struct PrettyPrinterContext
90 struct PrettyPrinterContext *prev; 80 struct PrettyPrinterContext *prev;
91 81
92 /** 82 /**
93 * Timeout task 83 * Our plugin.
94 */ 84 */
95 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 85 struct Plugin *plugin;
96 86
97 /** 87 /**
98 * Resolver handle 88 * Resolver handle
@@ -105,28 +95,36 @@ struct PrettyPrinterContext
105 GNUNET_TRANSPORT_AddressStringCallback asc; 95 GNUNET_TRANSPORT_AddressStringCallback asc;
106 96
107 /** 97 /**
108 * Clsoure for 'asc'. 98 * Clsoure for @e asc.
109 */ 99 */
110 void *asc_cls; 100 void *asc_cls;
111 101
112 /** 102 /**
113 * Port to add after the IP address. 103 * Timeout task
114 */ 104 */
115 uint16_t port; 105 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
116 106
117 /** 107 /**
118 * IPv6 address 108 * IPv6 address
119 */ 109 */
120
121 int ipv6; 110 int ipv6;
122 111
123 /** 112 /**
124 * Options 113 * Options
125 */ 114 */
126 uint32_t options; 115 uint32_t options;
116
117 /**
118 * Port to add after the IP address.
119 */
120 uint16_t port;
121
127}; 122};
128 123
129 124
125/**
126 * Session with another peer.
127 */
130struct Session 128struct Session
131{ 129{
132 /** 130 /**
@@ -160,6 +158,11 @@ struct Session
160 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 158 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
161 159
162 /** 160 /**
161 * When does this session time out?
162 */
163 struct GNUNET_TIME_Absolute timeout;
164
165 /**
163 * expected delay for ACKs 166 * expected delay for ACKs
164 */ 167 */
165 struct GNUNET_TIME_Relative last_expected_ack_delay; 168 struct GNUNET_TIME_Relative last_expected_ack_delay;
@@ -169,11 +172,30 @@ struct Session
169 */ 172 */
170 struct GNUNET_TIME_Relative last_expected_msg_delay; 173 struct GNUNET_TIME_Relative last_expected_msg_delay;
171 174
175 /**
176 * Address metrics (as set by the "update_address_metrics" by
177 * the environment).
178 */
172 struct GNUNET_ATS_Information ats; 179 struct GNUNET_ATS_Information ats;
173 180
181 /**
182 * Our own address.
183 */
174 struct GNUNET_HELLO_Address *address; 184 struct GNUNET_HELLO_Address *address;
175 185
176 /** 186 /**
187 * Number of bytes waiting for transmission to this peer.
188 * FIXME: not updated yet!
189 */
190 unsigned long long bytes_in_queue;
191
192 /**
193 * Number of messages waiting for transmission to this peer.
194 * FIXME: not updated yet!
195 */
196 unsigned int msgs_in_queue;
197
198 /**
177 * Reference counter to indicate that this session is 199 * Reference counter to indicate that this session is
178 * currently being used and must not be destroyed; 200 * currently being used and must not be destroyed;
179 * setting @e in_destroy will destroy it as soon as 201 * setting @e in_destroy will destroy it as soon as
@@ -190,15 +212,24 @@ struct Session
190 int in_destroy; 212 int in_destroy;
191}; 213};
192 214
215
193/** 216/**
194 * Closure for #session_cmp_it(). 217 * Closure for #session_cmp_it().
195 */ 218 */
196struct SessionCompareContext 219struct SessionCompareContext
197{ 220{
221 /**
222 * Set to session matching the address.
223 */
198 struct Session *res; 224 struct Session *res;
225
226 /**
227 * Address we are looking for.
228 */
199 const struct GNUNET_HELLO_Address *address; 229 const struct GNUNET_HELLO_Address *address;
200}; 230};
201 231
232
202/** 233/**
203 * Closure for #process_inbound_tokenized_messages(). 234 * Closure for #process_inbound_tokenized_messages().
204 */ 235 */
@@ -241,6 +272,9 @@ struct FindReceiveContext
241 */ 272 */
242 const struct sockaddr *addr; 273 const struct sockaddr *addr;
243 274
275 /**
276 *
277 */
244 struct Session *session; 278 struct Session *session;
245 279
246 /** 280 /**
@@ -279,11 +313,12 @@ struct DefragContext
279 struct GNUNET_CONTAINER_HeapNode *hnode; 313 struct GNUNET_CONTAINER_HeapNode *hnode;
280 314
281 /** 315 /**
282 * Length of 'src_addr' 316 * Length of @e src_addr.
283 */ 317 */
284 size_t addr_len; 318 size_t addr_len;
285}; 319};
286 320
321
287/** 322/**
288 * Context to send fragmented messages 323 * Context to send fragmented messages
289 */ 324 */
@@ -339,6 +374,9 @@ struct UDP_FragmentationContext
339 */ 374 */
340 size_t on_wire_size; 375 size_t on_wire_size;
341 376
377 /**
378 * FIXME.
379 */
342 unsigned int fragments_used; 380 unsigned int fragments_used;
343 381
344}; 382};
@@ -377,6 +415,9 @@ enum UDP_MessageType
377}; 415};
378 416
379 417
418/**
419 * Information we track for each message in the queue.
420 */
380struct UDP_MessageWrapper 421struct UDP_MessageWrapper
381{ 422{
382 /** 423 /**
@@ -397,24 +438,26 @@ struct UDP_MessageWrapper
397 struct UDP_MessageWrapper *next; 438 struct UDP_MessageWrapper *next;
398 439
399 /** 440 /**
400 * Message type 441 * Message with size msg_size including UDP specific overhead
401 */ 442 */
402 enum UDP_MessageType msg_type; 443 char *msg_buf;
403 444
404 /** 445 /**
405 * Message with size msg_size including UDP specific overhead 446 * Function to call upon completion of the transmission.
406 */ 447 */
407 char *msg_buf; 448 GNUNET_TRANSPORT_TransmitContinuation cont;
408 449
409 /** 450 /**
410 * Size of UDP message to send including UDP specific overhead 451 * Closure for @e cont.
411 */ 452 */
412 size_t msg_size; 453 void *cont_cls;
413 454
414 /** 455 /**
415 * Payload size of original message 456 * Fragmentation context
457 * frag_ctx == NULL if transport <= MTU
458 * frag_ctx != NULL if transport > MTU
416 */ 459 */
417 size_t payload_size; 460 struct UDP_FragmentationContext *frag_ctx;
418 461
419 /** 462 /**
420 * Message timeout 463 * Message timeout
@@ -422,21 +465,20 @@ struct UDP_MessageWrapper
422 struct GNUNET_TIME_Absolute timeout; 465 struct GNUNET_TIME_Absolute timeout;
423 466
424 /** 467 /**
425 * Function to call upon completion of the transmission. 468 * Size of UDP message to send including UDP specific overhead
426 */ 469 */
427 GNUNET_TRANSPORT_TransmitContinuation cont; 470 size_t msg_size;
428 471
429 /** 472 /**
430 * Closure for @e cont. 473 * Payload size of original message
431 */ 474 */
432 void *cont_cls; 475 size_t payload_size;
433 476
434 /** 477 /**
435 * Fragmentation context 478 * Message type
436 * frag_ctx == NULL if transport <= MTU
437 * frag_ctx != NULL if transport > MTU
438 */ 479 */
439 struct UDP_FragmentationContext *frag_ctx; 480 enum UDP_MessageType msg_type;
481
440}; 482};
441 483
442 484
@@ -462,15 +504,38 @@ struct UDP_ACK_Message
462 504
463}; 505};
464 506
465/**
466 * Address options
467 */
468static uint32_t myoptions;
469 507
470/** 508/**
471 * Encapsulation of all of the state of the plugin. 509 * If a session monitor is attached, notify it about the new
510 * session state.
511 *
512 * @param plugin our plugin
513 * @param session session that changed state
514 * @param state new state of the session
472 */ 515 */
473struct Plugin * plugin; 516static void
517notify_session_monitor (struct Plugin *plugin,
518 struct Session *session,
519 enum GNUNET_TRANSPORT_SessionState state)
520{
521 struct GNUNET_TRANSPORT_SessionInfo info;
522
523 if (NULL == plugin->sic)
524 return;
525 memset (&info, 0, sizeof (info));
526 info.state = state;
527 info.is_inbound = GNUNET_SYSERR; /* hard to say */
528 info.num_msg_pending = session->msgs_in_queue;
529 info.num_bytes_pending = session->bytes_in_queue;
530 /* info.receive_delay remains zero as this is not supported by UDP
531 (cannot selectively not receive from 'some' peer while continuing
532 to receive from others) */
533 info.session_timeout = session->timeout;
534 info.address = session->address;
535 plugin->sic (plugin->sic_cls,
536 session,
537 &info);
538}
474 539
475 540
476/** 541/**
@@ -482,7 +547,9 @@ struct Plugin * plugin;
482 * @param tc the scheduling context (for rescheduling this function again) 547 * @param tc the scheduling context (for rescheduling this function again)
483 */ 548 */
484static void 549static void
485udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 550udp_plugin_select (void *cls,
551 const struct GNUNET_SCHEDULER_TaskContext *tc);
552
486 553
487/** 554/**
488 * We have been notified that our readset has something to read. We don't 555 * We have been notified that our readset has something to read. We don't
@@ -493,7 +560,9 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
493 * @param tc the scheduling context (for rescheduling this function again) 560 * @param tc the scheduling context (for rescheduling this function again)
494 */ 561 */
495static void 562static void
496udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 563udp_plugin_select_v6 (void *cls,
564 const struct GNUNET_SCHEDULER_TaskContext *tc);
565
497 566
498/** 567/**
499 * (re)schedule select tasks for this plugin. 568 * (re)schedule select tasks for this plugin.
@@ -720,13 +789,15 @@ udp_string_to_address (void *cls,
720/** 789/**
721 * Append our port and forward the result. 790 * Append our port and forward the result.
722 * 791 *
723 * @param cls a 'struct PrettyPrinterContext' 792 * @param cls a `struct PrettyPrinterContext *`
724 * @param hostname result from DNS resolver 793 * @param hostname result from DNS resolver
725 */ 794 */
726static void 795static void
727append_port (void *cls, const char *hostname) 796append_port (void *cls,
797 const char *hostname)
728{ 798{
729 struct PrettyPrinterContext *ppc = cls; 799 struct PrettyPrinterContext *ppc = cls;
800 struct Plugin *plugin = ppc->plugin;
730 char *ret; 801 char *ret;
731 802
732 if (NULL == hostname) 803 if (NULL == hostname)
@@ -735,8 +806,8 @@ append_port (void *cls, const char *hostname)
735 ppc->asc (ppc->asc_cls, 806 ppc->asc (ppc->asc_cls,
736 NULL, 807 NULL,
737 GNUNET_OK); 808 GNUNET_OK);
738 GNUNET_CONTAINER_DLL_remove (ppc_dll_head, 809 GNUNET_CONTAINER_DLL_remove (plugin->ppc_dll_head,
739 ppc_dll_tail, 810 plugin->ppc_dll_tail,
740 ppc); 811 ppc);
741 ppc->resolver_handle = NULL; 812 ppc->resolver_handle = NULL;
742 GNUNET_free (ppc); 813 GNUNET_free (ppc);
@@ -767,7 +838,7 @@ append_port (void *cls, const char *hostname)
767 * Convert the transports address to a nice, human-readable 838 * Convert the transports address to a nice, human-readable
768 * format. 839 * format.
769 * 840 *
770 * @param cls closure 841 * @param cls closure with the `struct Plugin *`
771 * @param type name of the transport that generated the address 842 * @param type name of the transport that generated the address
772 * @param addr one of the addresses of the host, NULL for the last address 843 * @param addr one of the addresses of the host, NULL for the last address
773 * the specific address format depends on the transport 844 * the specific address format depends on the transport
@@ -787,6 +858,7 @@ udp_plugin_address_pretty_printer (void *cls,
787 GNUNET_TRANSPORT_AddressStringCallback asc, 858 GNUNET_TRANSPORT_AddressStringCallback asc,
788 void *asc_cls) 859 void *asc_cls)
789{ 860{
861 struct Plugin *plugin = cls;
790 struct PrettyPrinterContext *ppc; 862 struct PrettyPrinterContext *ppc;
791 const void *sb; 863 const void *sb;
792 size_t sbs; 864 size_t sbs;
@@ -836,6 +908,7 @@ udp_plugin_address_pretty_printer (void *cls,
836 return; 908 return;
837 } 909 }
838 ppc = GNUNET_new (struct PrettyPrinterContext); 910 ppc = GNUNET_new (struct PrettyPrinterContext);
911 ppc->plugin = plugin;
839 ppc->asc = asc; 912 ppc->asc = asc;
840 ppc->asc_cls = asc_cls; 913 ppc->asc_cls = asc_cls;
841 ppc->port = port; 914 ppc->port = port;
@@ -844,8 +917,8 @@ udp_plugin_address_pretty_printer (void *cls,
844 ppc->ipv6 = GNUNET_YES; 917 ppc->ipv6 = GNUNET_YES;
845 else 918 else
846 ppc->ipv6 = GNUNET_NO; 919 ppc->ipv6 = GNUNET_NO;
847 GNUNET_CONTAINER_DLL_insert (ppc_dll_head, 920 GNUNET_CONTAINER_DLL_insert (plugin->ppc_dll_head,
848 ppc_dll_tail, 921 plugin->ppc_dll_tail,
849 ppc); 922 ppc);
850 ppc->resolver_handle 923 ppc->resolver_handle
851 = GNUNET_RESOLVER_hostname_get (sb, 924 = GNUNET_RESOLVER_hostname_get (sb,
@@ -856,10 +929,15 @@ udp_plugin_address_pretty_printer (void *cls,
856} 929}
857 930
858 931
932/**
933 * FIXME.
934 */
859static void 935static void
860call_continuation (struct UDP_MessageWrapper *udpw, 936call_continuation (struct UDP_MessageWrapper *udpw,
861 int result) 937 int result)
862{ 938{
939 struct Session *session = udpw->session;
940 struct Plugin *plugin = session->plugin;
863 size_t overhead; 941 size_t overhead;
864 942
865 LOG (GNUNET_ERROR_TYPE_DEBUG, 943 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1017,7 +1095,8 @@ call_continuation (struct UDP_MessageWrapper *udpw,
1017 * @return #GNUNET_OK if port is either open_port or adv_port 1095 * @return #GNUNET_OK if port is either open_port or adv_port
1018 */ 1096 */
1019static int 1097static int
1020check_port (struct Plugin *plugin, uint16_t in_port) 1098check_port (struct Plugin *plugin,
1099 uint16_t in_port)
1021{ 1100{
1022 if ((in_port == plugin->port) || (in_port == plugin->aport)) 1101 if ((in_port == plugin->port) || (in_port == plugin->aport))
1023 return GNUNET_OK; 1102 return GNUNET_OK;
@@ -1039,10 +1118,11 @@ check_port (struct Plugin *plugin, uint16_t in_port)
1039 * @param addrlen length of @a addr 1118 * @param addrlen length of @a addr
1040 * @return #GNUNET_OK if this is a plausible address for this peer 1119 * @return #GNUNET_OK if this is a plausible address for this peer
1041 * and transport, #GNUNET_SYSERR if not 1120 * and transport, #GNUNET_SYSERR if not
1042 *
1043 */ 1121 */
1044static int 1122static int
1045udp_plugin_check_address (void *cls, const void *addr, size_t addrlen) 1123udp_plugin_check_address (void *cls,
1124 const void *addr,
1125 size_t addrlen)
1046{ 1126{
1047 struct Plugin *plugin = cls; 1127 struct Plugin *plugin = cls;
1048 struct IPv4UdpAddress *v4; 1128 struct IPv4UdpAddress *v4;
@@ -1074,9 +1154,10 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
1074 } 1154 }
1075 if (GNUNET_OK != check_port (plugin, ntohs (v6->u6_port))) 1155 if (GNUNET_OK != check_port (plugin, ntohs (v6->u6_port)))
1076 return GNUNET_SYSERR; 1156 return GNUNET_SYSERR;
1077 if (GNUNET_OK 1157 if (GNUNET_OK !=
1078 != GNUNET_NAT_test_address (plugin->nat, &v6->ipv6_addr, 1158 GNUNET_NAT_test_address (plugin->nat,
1079 sizeof(struct in6_addr))) 1159 &v6->ipv6_addr,
1160 sizeof(struct in6_addr)))
1080 return GNUNET_SYSERR; 1161 return GNUNET_SYSERR;
1081 } 1162 }
1082 return GNUNET_OK; 1163 return GNUNET_OK;
@@ -1101,21 +1182,26 @@ free_session (struct Session *s)
1101} 1182}
1102 1183
1103 1184
1185/**
1186 * FIXME.
1187 */
1104static void 1188static void
1105dequeue (struct Plugin *plugin, 1189dequeue (struct Plugin *plugin,
1106 struct UDP_MessageWrapper * udpw) 1190 struct UDP_MessageWrapper *udpw)
1107{ 1191{
1108 if (plugin->bytes_in_buffer < udpw->msg_size) 1192 if (plugin->bytes_in_buffer < udpw->msg_size)
1109 GNUNET_break(0); 1193 GNUNET_break(0);
1110 else 1194 else
1111 { 1195 {
1112 GNUNET_STATISTICS_update (plugin->env->stats, 1196 GNUNET_STATISTICS_update (plugin->env->stats,
1113 "# UDP, total, bytes in buffers", -(long long) udpw->msg_size, 1197 "# UDP, total, bytes in buffers",
1114 GNUNET_NO); 1198 -(long long) udpw->msg_size,
1199 GNUNET_NO);
1115 plugin->bytes_in_buffer -= udpw->msg_size; 1200 plugin->bytes_in_buffer -= udpw->msg_size;
1116 } 1201 }
1117 GNUNET_STATISTICS_update (plugin->env->stats, "# UDP, total, msgs in buffers", 1202 GNUNET_STATISTICS_update (plugin->env->stats,
1118 -1, GNUNET_NO); 1203 "# UDP, total, msgs in buffers",
1204 -1, GNUNET_NO);
1119 if (udpw->session->address->address_length == sizeof(struct IPv4UdpAddress)) 1205 if (udpw->session->address->address_length == sizeof(struct IPv4UdpAddress))
1120 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, 1206 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head,
1121 plugin->ipv4_queue_tail, udpw); 1207 plugin->ipv4_queue_tail, udpw);
@@ -1127,18 +1213,23 @@ dequeue (struct Plugin *plugin,
1127} 1213}
1128 1214
1129 1215
1216/**
1217 * FIXME.
1218 */
1130static void 1219static void
1131fragmented_message_done (struct UDP_FragmentationContext *fc, 1220fragmented_message_done (struct UDP_FragmentationContext *fc,
1132 int result) 1221 int result)
1133{ 1222{
1223 struct Plugin *plugin = fc->plugin;
1224 struct Session *s = fc->session;
1134 struct UDP_MessageWrapper *udpw; 1225 struct UDP_MessageWrapper *udpw;
1135 struct UDP_MessageWrapper *tmp; 1226 struct UDP_MessageWrapper *tmp;
1136 struct UDP_MessageWrapper dummy; 1227 struct UDP_MessageWrapper dummy;
1137 struct Session *s = fc->session;
1138 1228
1139 LOG(GNUNET_ERROR_TYPE_DEBUG, 1229 LOG (GNUNET_ERROR_TYPE_DEBUG,
1140 "%p : Fragmented message removed with result %s\n", fc, 1230 "%p : Fragmented message removed with result %s\n",
1141 (result == GNUNET_SYSERR) ? "FAIL" : "SUCCESS"); 1231 fc,
1232 (result == GNUNET_SYSERR) ? "FAIL" : "SUCCESS");
1142 1233
1143 /* Call continuation for fragmented message */ 1234 /* Call continuation for fragmented message */
1144 memset (&dummy, 0, sizeof(dummy)); 1235 memset (&dummy, 0, sizeof(dummy));
@@ -1190,6 +1281,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc,
1190 GNUNET_free(fc); 1281 GNUNET_free(fc);
1191} 1282}
1192 1283
1284
1193/** 1285/**
1194 * Scan the heap for a receive context with the given address. 1286 * Scan the heap for a receive context with the given address.
1195 * 1287 *
@@ -1201,8 +1293,10 @@ fragmented_message_done (struct UDP_FragmentationContext *fc,
1201 * #GNUNET_NO if not. 1293 * #GNUNET_NO if not.
1202 */ 1294 */
1203static int 1295static int
1204find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node, 1296find_receive_context (void *cls,
1205 void *element, GNUNET_CONTAINER_HeapCostType cost) 1297 struct GNUNET_CONTAINER_HeapNode *node,
1298 void *element,
1299 GNUNET_CONTAINER_HeapCostType cost)
1206{ 1300{
1207 struct FindReceiveContext *frc = cls; 1301 struct FindReceiveContext *frc = cls;
1208 struct DefragContext *e = element; 1302 struct DefragContext *e = element;
@@ -1227,7 +1321,8 @@ find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
1227 * @return #GNUNET_OK on success 1321 * @return #GNUNET_OK on success
1228 */ 1322 */
1229static int 1323static int
1230udp_disconnect_session (void *cls, struct Session *s) 1324udp_disconnect_session (void *cls,
1325 struct Session *s)
1231{ 1326{
1232 struct Plugin *plugin = cls; 1327 struct Plugin *plugin = cls;
1233 struct UDP_MessageWrapper *udpw; 1328 struct UDP_MessageWrapper *udpw;
@@ -1257,14 +1352,16 @@ udp_disconnect_session (void *cls, struct Session *s)
1257 if (NULL != plugin->defrag_ctxs) 1352 if (NULL != plugin->defrag_ctxs)
1258 { 1353 {
1259 GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs, 1354 GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs,
1260 &find_receive_context, &frc); 1355 &find_receive_context,
1356 &frc);
1261 if (NULL != frc.rc) 1357 if (NULL != frc.rc)
1262 { 1358 {
1263 struct DefragContext *d_ctx = frc.rc; 1359 struct DefragContext *d_ctx = frc.rc;
1264 GNUNET_CONTAINER_heap_remove_node (d_ctx->hnode); 1360
1265 GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag); 1361 GNUNET_CONTAINER_heap_remove_node (d_ctx->hnode);
1266 GNUNET_free (d_ctx); 1362 GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag);
1267 } 1363 GNUNET_free (d_ctx);
1364 }
1268 } 1365 }
1269 1366
1270 next = plugin->ipv4_queue_head; 1367 next = plugin->ipv4_queue_head;
@@ -1289,24 +1386,33 @@ udp_disconnect_session (void *cls, struct Session *s)
1289 GNUNET_free(udpw); 1386 GNUNET_free(udpw);
1290 } 1387 }
1291 } 1388 }
1292 plugin->env->session_end (plugin->env->cls, s->address, s); 1389 plugin->env->session_end (plugin->env->cls,
1390 s->address,
1391 s);
1293 1392
1294 if (NULL != s->frag_ctx) 1393 if (NULL != s->frag_ctx)
1295 { 1394 {
1296 if (NULL != s->frag_ctx->cont) 1395 if (NULL != s->frag_ctx->cont)
1297 { 1396 {
1298 s->frag_ctx->cont (s->frag_ctx->cont_cls, &s->target, GNUNET_SYSERR, 1397 s->frag_ctx->cont (s->frag_ctx->cont_cls,
1299 s->frag_ctx->payload_size, s->frag_ctx->on_wire_size); 1398 &s->target,
1300 LOG(GNUNET_ERROR_TYPE_DEBUG, 1399 GNUNET_SYSERR,
1301 "Calling continuation for fragemented message to `%s' with result SYSERR\n", 1400 s->frag_ctx->payload_size,
1302 GNUNET_i2s (&s->target)); 1401 s->frag_ctx->on_wire_size);
1402 LOG (GNUNET_ERROR_TYPE_DEBUG,
1403 "Calling continuation for fragemented message to `%s' with result SYSERR\n",
1404 GNUNET_i2s (&s->target));
1303 } 1405 }
1304 } 1406 }
1305 1407
1306 GNUNET_assert( 1408 GNUNET_assert(GNUNET_YES ==
1307 GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, &s->target, s)); 1409 GNUNET_CONTAINER_multipeermap_remove (plugin->sessions,
1308 GNUNET_STATISTICS_set (plugin->env->stats, "# UDP sessions active", 1410 &s->target,
1309 GNUNET_CONTAINER_multipeermap_size (plugin->sessions), GNUNET_NO); 1411 s));
1412 GNUNET_STATISTICS_set (plugin->env->stats,
1413 "# UDP sessions active",
1414 GNUNET_CONTAINER_multipeermap_size (plugin->sessions),
1415 GNUNET_NO);
1310 if (s->rc > 0) 1416 if (s->rc > 0)
1311 s->in_destroy = GNUNET_YES; 1417 s->in_destroy = GNUNET_YES;
1312 else 1418 else
@@ -1371,8 +1477,10 @@ udp_disconnect (void *cls,
1371 "Disconnecting from peer `%s'\n", 1477 "Disconnecting from peer `%s'\n",
1372 GNUNET_i2s (target)); 1478 GNUNET_i2s (target));
1373 /* Clean up sessions */ 1479 /* Clean up sessions */
1374 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, target, 1480 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions,
1375 &disconnect_and_free_it, plugin); 1481 target,
1482 &disconnect_and_free_it,
1483 plugin);
1376} 1484}
1377 1485
1378 1486
@@ -1387,8 +1495,23 @@ session_timeout (void *cls,
1387 const struct GNUNET_SCHEDULER_TaskContext *tc) 1495 const struct GNUNET_SCHEDULER_TaskContext *tc)
1388{ 1496{
1389 struct Session *s = cls; 1497 struct Session *s = cls;
1498 struct Plugin *plugin = s->plugin;
1499 struct GNUNET_TIME_Relative left;
1390 1500
1391 s->timeout_task = GNUNET_SCHEDULER_NO_TASK; 1501 s->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1502 left = GNUNET_TIME_absolute_get_remaining (s->timeout);
1503 if (left.rel_value_us > 0)
1504 {
1505 /* not actually our turn yet, but let's at least update
1506 the monitor, it may think we're about to die ... */
1507 notify_session_monitor (s->plugin,
1508 s,
1509 GNUNET_TRANSPORT_SS_UP);
1510 s->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
1511 &session_timeout,
1512 s);
1513 return;
1514 }
1392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1393 "Session %p was idle for %s, disconnecting\n", 1516 "Session %p was idle for %s, disconnecting\n",
1394 s, 1517 s,
@@ -1410,13 +1533,13 @@ reschedule_session_timeout (struct Session *s)
1410 if (GNUNET_YES == s->in_destroy) 1533 if (GNUNET_YES == s->in_destroy)
1411 return; 1534 return;
1412 GNUNET_assert(GNUNET_SCHEDULER_NO_TASK != s->timeout_task); 1535 GNUNET_assert(GNUNET_SCHEDULER_NO_TASK != s->timeout_task);
1413 GNUNET_SCHEDULER_cancel (s->timeout_task); 1536 s->timeout = GNUNET_TIME_relative_to_absolute (UDP_SESSION_TIME_OUT);
1414 s->timeout_task = GNUNET_SCHEDULER_add_delayed (UDP_SESSION_TIME_OUT,
1415 &session_timeout, s);
1416 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Timeout restarted for session %p\n", s);
1417} 1537}
1418 1538
1419 1539
1540/**
1541 * FIXME.
1542 */
1420static struct Session * 1543static struct Session *
1421create_session (struct Plugin *plugin, 1544create_session (struct Plugin *plugin,
1422 const struct GNUNET_HELLO_Address *address) 1545 const struct GNUNET_HELLO_Address *address)
@@ -1437,6 +1560,30 @@ create_session (struct Plugin *plugin,
1437} 1560}
1438 1561
1439 1562
1563
1564/**
1565 * Function obtain the network type for a session
1566 *
1567 * @param cls closure ('struct Plugin*')
1568 * @param session the session
1569 * @return the network type
1570 */
1571static enum GNUNET_ATS_Network_Type
1572udp_get_network (void *cls,
1573 struct Session *session)
1574{
1575 return ntohl (session->ats.value);
1576}
1577
1578
1579/**
1580 * Find a session with a matching address.
1581 *
1582 * @param cls the `struct SessionCompareContext *`
1583 * @param key peer identity (unused)
1584 * @param value the `struct Session *`
1585 * @return #GNUNET_NO if we found the session, #GNUNET_OK if not
1586 */
1440static int 1587static int
1441session_cmp_it (void *cls, 1588session_cmp_it (void *cls,
1442 const struct GNUNET_PeerIdentity *key, 1589 const struct GNUNET_PeerIdentity *key,
@@ -1448,9 +1595,12 @@ session_cmp_it (void *cls,
1448 1595
1449 LOG (GNUNET_ERROR_TYPE_DEBUG, 1596 LOG (GNUNET_ERROR_TYPE_DEBUG,
1450 "Comparing address %s <-> %s\n", 1597 "Comparing address %s <-> %s\n",
1451 udp_address_to_string (NULL, address->address, address->address_length), 1598 udp_address_to_string (NULL,
1452 udp_address_to_string (NULL, s->address->address, s->address->address_length)); 1599 address->address,
1453 1600 address->address_length),
1601 udp_address_to_string (NULL,
1602 s->address->address,
1603 s->address->address_length));
1454 if (0 == GNUNET_HELLO_address_cmp(s->address, cctx->address)) 1604 if (0 == GNUNET_HELLO_address_cmp(s->address, cctx->address))
1455 { 1605 {
1456 cctx->res = s; 1606 cctx->res = s;
@@ -1461,21 +1611,6 @@ session_cmp_it (void *cls,
1461 1611
1462 1612
1463/** 1613/**
1464 * Function obtain the network type for a session
1465 *
1466 * @param cls closure ('struct Plugin*')
1467 * @param session the session
1468 * @return the network type
1469 */
1470static enum GNUNET_ATS_Network_Type
1471udp_get_network (void *cls,
1472 struct Session *session)
1473{
1474 return ntohl (session->ats.value);
1475}
1476
1477
1478/**
1479 * Creates a new outbound session the transport service will use to 1614 * Creates a new outbound session the transport service will use to
1480 * send data to the peer 1615 * send data to the peer
1481 * 1616 *
@@ -1488,13 +1623,11 @@ udp_plugin_lookup_session (void *cls,
1488 const struct GNUNET_HELLO_Address *address) 1623 const struct GNUNET_HELLO_Address *address)
1489{ 1624{
1490 struct Plugin * plugin = cls; 1625 struct Plugin * plugin = cls;
1491 struct IPv6UdpAddress * udp_a6; 1626 struct IPv6UdpAddress *udp_a6;
1492 struct IPv4UdpAddress * udp_a4; 1627 struct IPv4UdpAddress *udp_a4;
1493 1628 struct SessionCompareContext cctx;
1494 GNUNET_assert(plugin != NULL);
1495 GNUNET_assert(address != NULL);
1496 1629
1497 if ( (address->address == NULL )|| 1630 if ( (NULL == address->address) ||
1498 ((address->address_length != sizeof (struct IPv4UdpAddress)) && 1631 ((address->address_length != sizeof (struct IPv4UdpAddress)) &&
1499 (address->address_length != sizeof (struct IPv6UdpAddress)))) 1632 (address->address_length != sizeof (struct IPv6UdpAddress))))
1500 { 1633 {
@@ -1525,13 +1658,12 @@ udp_plugin_lookup_session (void *cls,
1525 } 1658 }
1526 1659
1527 /* check if session already exists */ 1660 /* check if session already exists */
1528 struct SessionCompareContext cctx;
1529 cctx.address = address; 1661 cctx.address = address;
1530 cctx.res = NULL; 1662 cctx.res = NULL;
1531 LOG(GNUNET_ERROR_TYPE_DEBUG, 1663 LOG (GNUNET_ERROR_TYPE_DEBUG,
1532 "Looking for existing session for peer `%s' `%s' \n", 1664 "Looking for existing session for peer `%s' `%s' \n",
1533 GNUNET_i2s (&address->peer), 1665 GNUNET_i2s (&address->peer),
1534 udp_address_to_string(NULL, address->address, address->address_length)); 1666 udp_address_to_string(NULL, address->address, address->address_length));
1535 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, &address->peer, 1667 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, &address->peer,
1536 session_cmp_it, &cctx); 1668 session_cmp_it, &cctx);
1537 if (cctx.res != NULL ) 1669 if (cctx.res != NULL )
@@ -1545,10 +1677,100 @@ udp_plugin_lookup_session (void *cls,
1545} 1677}
1546 1678
1547 1679
1680/**
1681 * Context to lookup a session based on a IP address
1682 */
1683struct LookupContext
1684{
1685 /**
1686 * The result
1687 */
1688 struct Session *res;
1689
1690 /**
1691 * The socket address
1692 */
1693 const struct sockaddr *address;
1694
1695 /**
1696 * The socket address length
1697 */
1698 size_t addr_len;
1699
1700 /**
1701 * Is a fragmentation context required for the session
1702 */
1703 int must_have_frag_ctx;
1704};
1705
1706
1707/**
1708 * Find a session with a matching address.
1709 * FIXME: very similar code to #udp_plugin_lookup_session() above.
1710 * Unify?
1711 *
1712 * @param cls the `struct LookupContext *`
1713 * @param key peer identity (unused)
1714 * @param value the `struct Session *`
1715 * @return #GNUNET_NO if we found the session, #GNUNET_OK if not
1716 */
1717static int
1718lookup_session_by_sockaddr_it (void *cls,
1719 const struct GNUNET_PeerIdentity *key,
1720 void *value)
1721{
1722 struct LookupContext *l_ctx = cls;
1723 struct Session *s = value;
1724 struct IPv4UdpAddress u4;
1725 struct IPv6UdpAddress u6;
1726 void *arg;
1727 size_t args;
1728
1729 /* convert address */
1730 switch (l_ctx->address->sa_family)
1731 {
1732 case AF_INET:
1733 GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in));
1734 memset (&u4, 0, sizeof(u4));
1735 u6.options = htonl (0);
1736 u4.ipv4_addr = ((struct sockaddr_in *) l_ctx->address)->sin_addr.s_addr;
1737 u4.u4_port = ((struct sockaddr_in *) l_ctx->address)->sin_port;
1738 arg = &u4;
1739 args = sizeof(u4);
1740 break;
1741 case AF_INET6:
1742 GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in6));
1743 memset (&u6, 0, sizeof(u6));
1744 u6.options = htonl (0);
1745 u6.ipv6_addr = ((struct sockaddr_in6 *) l_ctx->address)->sin6_addr;
1746 u6.u6_port = ((struct sockaddr_in6 *) l_ctx->address)->sin6_port;
1747 arg = &u6;
1748 args = sizeof(u6);
1749 break;
1750 default:
1751 GNUNET_break(0);
1752 return GNUNET_YES;
1753 }
1754 if ( (GNUNET_YES == l_ctx->must_have_frag_ctx) &&
1755 (NULL == s->frag_ctx))
1756 return GNUNET_YES;
1757
1758 /* Does not compare peer identities but addresses */
1759 if ((args == s->address->address_length) &&
1760 (0 == memcmp (arg, s->address->address, args)))
1761 {
1762 l_ctx->res = s;
1763 return GNUNET_NO;
1764 }
1765 return GNUNET_YES;
1766}
1767
1768
1548static struct Session * 1769static struct Session *
1549udp_plugin_create_session (void *cls, 1770udp_plugin_create_session (void *cls,
1550 const struct GNUNET_HELLO_Address *address) 1771 const struct GNUNET_HELLO_Address *address)
1551{ 1772{
1773 struct Plugin *plugin = cls;
1552 struct Session *s; 1774 struct Session *s;
1553 struct IPv4UdpAddress *udp_v4; 1775 struct IPv4UdpAddress *udp_v4;
1554 struct IPv6UdpAddress *udp_v6; 1776 struct IPv6UdpAddress *udp_v6;
@@ -1566,7 +1788,8 @@ udp_plugin_create_session (void *cls,
1566 v4.sin_port = udp_v4->u4_port; 1788 v4.sin_port = udp_v4->u4_port;
1567 v4.sin_addr.s_addr = udp_v4->ipv4_addr; 1789 v4.sin_addr.s_addr = udp_v4->ipv4_addr;
1568 s->ats = plugin->env->get_address_type (plugin->env->cls, 1790 s->ats = plugin->env->get_address_type (plugin->env->cls,
1569 (const struct sockaddr *) &v4, sizeof (v4)); 1791 (const struct sockaddr *) &v4,
1792 sizeof (v4));
1570 } 1793 }
1571 else if (sizeof (struct IPv6UdpAddress) == address->address_length) 1794 else if (sizeof (struct IPv6UdpAddress) == address->address_length)
1572 { 1795 {
@@ -1598,19 +1821,30 @@ udp_plugin_create_session (void *cls,
1598} 1821}
1599 1822
1600 1823
1824/**
1825 * Function that will be called whenever the transport service wants to
1826 * notify the plugin that a session is still active and in use and
1827 * therefore the session timeout for this session has to be updated
1828 *
1829 * @param cls closure
1830 * @param peer which peer was the session for
1831 * @param session which session is being updated
1832 */
1601static void 1833static void
1602udp_plugin_update_session_timeout (void *cls, 1834udp_plugin_update_session_timeout (void *cls,
1603 const struct GNUNET_PeerIdentity *peer, 1835 const struct GNUNET_PeerIdentity *peer,
1604 struct Session *session) 1836 struct Session *session)
1605{ 1837{
1838 struct Plugin *plugin = cls;
1839
1606 if (GNUNET_YES != 1840 if (GNUNET_YES !=
1607 GNUNET_CONTAINER_multipeermap_contains_value (plugin->sessions, peer, 1841 GNUNET_CONTAINER_multipeermap_contains_value (plugin->sessions,
1842 peer,
1608 session)) 1843 session))
1609 { 1844 {
1610 GNUNET_break(0); 1845 GNUNET_break(0);
1611 return; 1846 return;
1612 } 1847 }
1613
1614 /* Reschedule session timeout */ 1848 /* Reschedule session timeout */
1615 reschedule_session_timeout (session); 1849 reschedule_session_timeout (session);
1616} 1850}
@@ -1646,6 +1880,9 @@ udp_plugin_get_session (void *cls,
1646} 1880}
1647 1881
1648 1882
1883/**
1884 * FIXME.
1885 */
1649static void 1886static void
1650enqueue (struct Plugin *plugin, 1887enqueue (struct Plugin *plugin,
1651 struct UDP_MessageWrapper *udpw) 1888 struct UDP_MessageWrapper *udpw)
@@ -1675,9 +1912,9 @@ enqueue (struct Plugin *plugin,
1675 * Fragment message was transmitted via UDP, let fragmentation know 1912 * Fragment message was transmitted via UDP, let fragmentation know
1676 * to send the next fragment now. 1913 * to send the next fragment now.
1677 * 1914 *
1678 * @param cls the 'struct UDPMessageWrapper' of the fragment 1915 * @param cls the `struct UDPMessageWrapper *` of the fragment
1679 * @param target destination peer (ignored) 1916 * @param target destination peer (ignored)
1680 * @param result GNUNET_OK on success (ignored) 1917 * @param result #GNUNET_OK on success (ignored)
1681 * @param payload bytes payload sent 1918 * @param payload bytes payload sent
1682 * @param physical bytes physical sent 1919 * @param physical bytes physical sent
1683 */ 1920 */
@@ -1697,14 +1934,15 @@ send_next_fragment (void *cls,
1697/** 1934/**
1698 * Function that is called with messages created by the fragmentation 1935 * Function that is called with messages created by the fragmentation
1699 * module. In the case of the 'proc' callback of the 1936 * module. In the case of the 'proc' callback of the
1700 * GNUNET_FRAGMENT_context_create function, this function must 1937 * #GNUNET_FRAGMENT_context_create() function, this function must
1701 * eventually call 'GNUNET_FRAGMENT_context_transmission_done'. 1938 * eventually call #GNUNET_FRAGMENT_context_transmission_done().
1702 * 1939 *
1703 * @param cls closure, the 'struct FragmentationContext' 1940 * @param cls closure, the 'struct FragmentationContext'
1704 * @param msg the message that was created 1941 * @param msg the message that was created
1705 */ 1942 */
1706static void 1943static void
1707enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) 1944enqueue_fragment (void *cls,
1945 const struct GNUNET_MessageHeader *msg)
1708{ 1946{
1709 struct UDP_FragmentationContext *frag_ctx = cls; 1947 struct UDP_FragmentationContext *frag_ctx = cls;
1710 struct Plugin *plugin = frag_ctx->plugin; 1948 struct Plugin *plugin = frag_ctx->plugin;
@@ -1763,7 +2001,8 @@ udp_plugin_send (void *cls,
1763 size_t msgbuf_size, 2001 size_t msgbuf_size,
1764 unsigned int priority, 2002 unsigned int priority,
1765 struct GNUNET_TIME_Relative to, 2003 struct GNUNET_TIME_Relative to,
1766 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) 2004 GNUNET_TRANSPORT_TransmitContinuation cont,
2005 void *cont_cls)
1767{ 2006{
1768 struct Plugin *plugin = cls; 2007 struct Plugin *plugin = cls;
1769 size_t udpmlen = msgbuf_size + sizeof(struct UDPMessage); 2008 size_t udpmlen = msgbuf_size + sizeof(struct UDPMessage);
@@ -1793,9 +2032,11 @@ udp_plugin_send (void *cls,
1793 return GNUNET_SYSERR; 2032 return GNUNET_SYSERR;
1794 } 2033 }
1795 LOG (GNUNET_ERROR_TYPE_DEBUG, 2034 LOG (GNUNET_ERROR_TYPE_DEBUG,
1796 "UDP transmits %u-byte message to `%s' using address `%s'\n", udpmlen, 2035 "UDP transmits %u-byte message to `%s' using address `%s'\n",
2036 udpmlen,
1797 GNUNET_i2s (&s->target), 2037 GNUNET_i2s (&s->target),
1798 udp_address_to_string (NULL, s->address->address, 2038 udp_address_to_string (NULL,
2039 s->address->address,
1799 s->address->address_length)); 2040 s->address->address_length));
1800 2041
1801 /* Message */ 2042 /* Message */
@@ -1877,7 +2118,8 @@ udp_plugin_send (void *cls,
1877 * @param addrlen actual lenght of the address 2118 * @param addrlen actual lenght of the address
1878 */ 2119 */
1879static void 2120static void
1880udp_nat_port_map_callback (void *cls, int add_remove, 2121udp_nat_port_map_callback (void *cls,
2122 int add_remove,
1881 const struct sockaddr *addr, 2123 const struct sockaddr *addr,
1882 socklen_t addrlen) 2124 socklen_t addrlen)
1883{ 2125{
@@ -1888,9 +2130,10 @@ udp_nat_port_map_callback (void *cls, int add_remove,
1888 void *arg; 2130 void *arg;
1889 size_t args; 2131 size_t args;
1890 2132
1891 LOG(GNUNET_ERROR_TYPE_INFO, "NAT notification to %s address `%s'\n", 2133 LOG (GNUNET_ERROR_TYPE_INFO,
1892 (GNUNET_YES == add_remove) ? "add" : "remove", 2134 "NAT notification to %s address `%s'\n",
1893 GNUNET_a2s (addr, addrlen)); 2135 (GNUNET_YES == add_remove) ? "add" : "remove",
2136 GNUNET_a2s (addr, addrlen));
1894 2137
1895 /* convert 'address' to our internal format */ 2138 /* convert 'address' to our internal format */
1896 switch (addr->sa_family) 2139 switch (addr->sa_family)
@@ -1898,7 +2141,7 @@ udp_nat_port_map_callback (void *cls, int add_remove,
1898 case AF_INET: 2141 case AF_INET:
1899 GNUNET_assert(addrlen == sizeof(struct sockaddr_in)); 2142 GNUNET_assert(addrlen == sizeof(struct sockaddr_in));
1900 memset (&u4, 0, sizeof(u4)); 2143 memset (&u4, 0, sizeof(u4));
1901 u4.options = htonl (myoptions); 2144 u4.options = htonl (plugin->myoptions);
1902 u4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; 2145 u4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
1903 u4.u4_port = ((struct sockaddr_in *) addr)->sin_port; 2146 u4.u4_port = ((struct sockaddr_in *) addr)->sin_port;
1904 if (0 == ((struct sockaddr_in *) addr)->sin_port) 2147 if (0 == ((struct sockaddr_in *) addr)->sin_port)
@@ -1909,7 +2152,7 @@ udp_nat_port_map_callback (void *cls, int add_remove,
1909 case AF_INET6: 2152 case AF_INET6:
1910 GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); 2153 GNUNET_assert(addrlen == sizeof(struct sockaddr_in6));
1911 memset (&u6, 0, sizeof(u6)); 2154 memset (&u6, 0, sizeof(u6));
1912 u6.options = htonl (myoptions); 2155 u6.options = htonl (plugin->myoptions);
1913 if (0 == ((struct sockaddr_in6 *) addr)->sin6_port) 2156 if (0 == ((struct sockaddr_in6 *) addr)->sin6_port)
1914 return; 2157 return;
1915 memcpy (&u6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr, 2158 memcpy (&u6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr,
@@ -1924,7 +2167,9 @@ udp_nat_port_map_callback (void *cls, int add_remove,
1924 } 2167 }
1925 /* modify our published address list */ 2168 /* modify our published address list */
1926 address = GNUNET_HELLO_address_allocate (plugin->env->my_identity, 2169 address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
1927 PLUGIN_NAME, arg, args, GNUNET_HELLO_ADDRESS_INFO_NONE); 2170 PLUGIN_NAME,
2171 arg, args,
2172 GNUNET_HELLO_ADDRESS_INFO_NONE);
1928 plugin->env->notify_address (plugin->env->cls, add_remove, address); 2173 plugin->env->notify_address (plugin->env->cls, add_remove, address);
1929 GNUNET_HELLO_address_free (address); 2174 GNUNET_HELLO_address_free (address);
1930} 2175}
@@ -1934,14 +2179,15 @@ udp_nat_port_map_callback (void *cls, int add_remove,
1934 * Message tokenizer has broken up an incomming message. Pass it on 2179 * Message tokenizer has broken up an incomming message. Pass it on
1935 * to the service. 2180 * to the service.
1936 * 2181 *
1937 * @param cls the 'struct Plugin' 2182 * @param cls the `struct Plugin *`
1938 * @param client the `struct SourceInformation` 2183 * @param client the `struct SourceInformation *`
1939 * @param hdr the actual message 2184 * @param hdr the actual message
1940 * @return #GNUNET_OK (always) 2185 * @return #GNUNET_OK (always)
1941 */ 2186 */
1942static int 2187static int
1943process_inbound_tokenized_messages (void *cls, void *client, 2188process_inbound_tokenized_messages (void *cls,
1944 const struct GNUNET_MessageHeader *hdr) 2189 void *client,
2190 const struct GNUNET_MessageHeader *hdr)
1945{ 2191{
1946 struct Plugin *plugin = cls; 2192 struct Plugin *plugin = cls;
1947 struct SourceInformation *si = client; 2193 struct SourceInformation *si = client;
@@ -1951,12 +2197,16 @@ process_inbound_tokenized_messages (void *cls, void *client,
1951 if (GNUNET_YES == si->session->in_destroy) 2197 if (GNUNET_YES == si->session->in_destroy)
1952 return GNUNET_OK; 2198 return GNUNET_OK;
1953 /* setup ATS */ 2199 /* setup ATS */
1954 GNUNET_break(ntohl (si->session->ats.value) != GNUNET_ATS_NET_UNSPECIFIED); 2200 GNUNET_break (ntohl (si->session->ats.value) != GNUNET_ATS_NET_UNSPECIFIED);
1955 reschedule_session_timeout (si->session); 2201 reschedule_session_timeout (si->session);
1956 delay = plugin->env->receive (plugin->env->cls, si->session->address, si->session, hdr); 2202 delay = plugin->env->receive (plugin->env->cls,
2203 si->session->address,
2204 si->session,
2205 hdr);
1957 plugin->env->update_address_metrics (plugin->env->cls, 2206 plugin->env->update_address_metrics (plugin->env->cls,
1958 si->session->address, si->session, 2207 si->session->address,
1959 &si->session->ats, 1); 2208 si->session,
2209 &si->session->ats, 1);
1960 si->session->flow_delay_for_other_peer = delay; 2210 si->session->flow_delay_for_other_peer = delay;
1961 return GNUNET_OK; 2211 return GNUNET_OK;
1962} 2212}
@@ -1968,7 +2218,7 @@ process_inbound_tokenized_messages (void *cls, void *client,
1968 * @param plugin plugin context 2218 * @param plugin plugin context
1969 * @param msg the message 2219 * @param msg the message
1970 * @param sender_addr sender address 2220 * @param sender_addr sender address
1971 * @param sender_addr_len number of bytes in sender_addr 2221 * @param sender_addr_len number of bytes in @a sender_addr
1972 */ 2222 */
1973static void 2223static void
1974process_udp_message (struct Plugin *plugin, 2224process_udp_message (struct Plugin *plugin,
@@ -2027,7 +2277,8 @@ process_udp_message (struct Plugin *plugin,
2027 GNUNET_a2s (sender_addr, sender_addr_len)); 2277 GNUNET_a2s (sender_addr, sender_addr_len));
2028 2278
2029 address = GNUNET_HELLO_address_allocate ( &msg->sender, PLUGIN_NAME, 2279 address = GNUNET_HELLO_address_allocate ( &msg->sender, PLUGIN_NAME,
2030 arg, args, GNUNET_HELLO_ADDRESS_INFO_INBOUND); 2280 arg, args,
2281 GNUNET_HELLO_ADDRESS_INFO_INBOUND);
2031 if (NULL == (s = udp_plugin_lookup_session (plugin, address))) 2282 if (NULL == (s = udp_plugin_lookup_session (plugin, address)))
2032 { 2283 {
2033 s = udp_plugin_create_session (plugin, address); 2284 s = udp_plugin_create_session (plugin, address);
@@ -2049,14 +2300,16 @@ process_udp_message (struct Plugin *plugin,
2049 free_session (s); 2300 free_session (s);
2050} 2301}
2051 2302
2303
2052/** 2304/**
2053 * Process a defragmented message. 2305 * Process a defragmented message.
2054 * 2306 *
2055 * @param cls the 'struct ReceiveContext' 2307 * @param cls the `struct DefragContext *`
2056 * @param msg the message 2308 * @param msg the message
2057 */ 2309 */
2058static void 2310static void
2059fragment_msg_proc (void *cls, const struct GNUNET_MessageHeader *msg) 2311fragment_msg_proc (void *cls,
2312 const struct GNUNET_MessageHeader *msg)
2060{ 2313{
2061 struct DefragContext *rc = cls; 2314 struct DefragContext *rc = cls;
2062 2315
@@ -2070,100 +2323,24 @@ fragment_msg_proc (void *cls, const struct GNUNET_MessageHeader *msg)
2070 GNUNET_break(0); 2323 GNUNET_break(0);
2071 return; 2324 return;
2072 } 2325 }
2073 process_udp_message (rc->plugin, (const struct UDPMessage *) msg, 2326 process_udp_message (rc->plugin,
2074 rc->src_addr, rc->addr_len); 2327 (const struct UDPMessage *) msg,
2075} 2328 rc->src_addr,
2076 2329 rc->addr_len);
2077
2078/**
2079 * Context to lookup a session based on a IP address
2080 */
2081struct LookupContext
2082{
2083 /**
2084 * The result
2085 */
2086 struct Session *res;
2087
2088 /**
2089 * The socket address
2090 */
2091 const struct sockaddr *address;
2092
2093 /**
2094 * The socket address length
2095 */
2096 size_t addr_len;
2097
2098 /**
2099 * Is a fragmentation context required for the session
2100 */
2101 int must_have_frag_ctx;
2102};
2103
2104
2105static int
2106lookup_session_by_sockaddr_it (void *cls,
2107 const struct GNUNET_PeerIdentity *key,
2108 void *value)
2109{
2110 struct LookupContext *l_ctx = cls;
2111 struct Session * s = value;
2112 struct IPv4UdpAddress u4;
2113 struct IPv6UdpAddress u6;
2114 void *arg;
2115 size_t args;
2116
2117 /* convert address */
2118 switch (l_ctx->address->sa_family)
2119 {
2120 case AF_INET:
2121 GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in));
2122 memset (&u4, 0, sizeof(u4));
2123 u6.options = htonl (0);
2124 u4.ipv4_addr = ((struct sockaddr_in *) l_ctx->address)->sin_addr.s_addr;
2125 u4.u4_port = ((struct sockaddr_in *) l_ctx->address)->sin_port;
2126 arg = &u4;
2127 args = sizeof(u4);
2128 break;
2129 case AF_INET6:
2130 GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in6));
2131 memset (&u6, 0, sizeof(u6));
2132 u6.options = htonl (0);
2133 u6.ipv6_addr = ((struct sockaddr_in6 *) l_ctx->address)->sin6_addr;
2134 u6.u6_port = ((struct sockaddr_in6 *) l_ctx->address)->sin6_port;
2135 arg = &u6;
2136 args = sizeof(u6);
2137 break;
2138 default:
2139 GNUNET_break(0);
2140 return GNUNET_YES;
2141 }
2142
2143
2144 if ((GNUNET_YES == l_ctx->must_have_frag_ctx) && (NULL == s->frag_ctx))
2145 return GNUNET_YES;
2146
2147 /* Does not compare peer identities but addresses */
2148 if ((args == s->address->address_length) &&
2149 (0 == memcmp (arg, s->address->address, args)))
2150 {
2151 l_ctx->res = s;
2152 return GNUNET_YES;
2153 }
2154 return GNUNET_YES;
2155} 2330}
2156 2331
2157 2332
2158/** 2333/**
2159 * Transmit an acknowledgement. 2334 * Transmit an acknowledgement.
2160 * 2335 *
2161 * @param cls the 'struct ReceiveContext' 2336 * @param cls the `struct DefragContext *`
2162 * @param id message ID (unused) 2337 * @param id message ID (unused)
2163 * @param msg ack to transmit 2338 * @param msg ack to transmit
2164 */ 2339 */
2165static void 2340static void
2166ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) 2341ack_proc (void *cls,
2342 uint32_t id,
2343 const struct GNUNET_MessageHeader *msg)
2167{ 2344{
2168 struct DefragContext *rc = cls; 2345 struct DefragContext *rc = cls;
2169 size_t msize = sizeof(struct UDP_ACK_Message) + ntohs (msg->size); 2346 size_t msize = sizeof(struct UDP_ACK_Message) + ntohs (msg->size);
@@ -2178,7 +2355,8 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
2178 l_ctx.must_have_frag_ctx = GNUNET_NO; 2355 l_ctx.must_have_frag_ctx = GNUNET_NO;
2179 l_ctx.res = NULL; 2356 l_ctx.res = NULL;
2180 GNUNET_CONTAINER_multipeermap_iterate (rc->plugin->sessions, 2357 GNUNET_CONTAINER_multipeermap_iterate (rc->plugin->sessions,
2181 &lookup_session_by_sockaddr_it, &l_ctx); 2358 &lookup_session_by_sockaddr_it,
2359 &l_ctx);
2182 s = l_ctx.res; 2360 s = l_ctx.res;
2183 if (NULL == s) 2361 if (NULL == s)
2184 { 2362 {
@@ -2195,9 +2373,11 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
2195 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX) 2373 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX)
2196 delay = s->flow_delay_for_other_peer.rel_value_us; 2374 delay = s->flow_delay_for_other_peer.rel_value_us;
2197 2375
2198 LOG(GNUNET_ERROR_TYPE_DEBUG, "Sending ACK to `%s' including delay of %s\n", 2376 LOG (GNUNET_ERROR_TYPE_DEBUG,
2199 GNUNET_a2s (rc->src_addr, (rc->src_addr->sa_family == AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)), 2377 "Sending ACK to `%s' including delay of %s\n",
2200 GNUNET_STRINGS_relative_time_to_string (s->flow_delay_for_other_peer, GNUNET_YES)); 2378 GNUNET_a2s (rc->src_addr, (rc->src_addr->sa_family == AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)),
2379 GNUNET_STRINGS_relative_time_to_string (s->flow_delay_for_other_peer,
2380 GNUNET_YES));
2201 udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msize); 2381 udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msize);
2202 udpw->msg_size = msize; 2382 udpw->msg_size = msize;
2203 udpw->payload_size = 0; 2383 udpw->payload_size = 0;
@@ -2216,6 +2396,9 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
2216} 2396}
2217 2397
2218 2398
2399/**
2400 * FIXME.
2401 */
2219static void 2402static void
2220read_process_msg (struct Plugin *plugin, 2403read_process_msg (struct Plugin *plugin,
2221 const struct GNUNET_MessageHeader *msg, 2404 const struct GNUNET_MessageHeader *msg,
@@ -2227,10 +2410,16 @@ read_process_msg (struct Plugin *plugin,
2227 GNUNET_break_op(0); 2410 GNUNET_break_op(0);
2228 return; 2411 return;
2229 } 2412 }
2230 process_udp_message (plugin, (const struct UDPMessage *) msg, addr, fromlen); 2413 process_udp_message (plugin,
2414 (const struct UDPMessage *) msg,
2415 addr,
2416 fromlen);
2231} 2417}
2232 2418
2233 2419
2420/**
2421 * FIXME.
2422 */
2234static void 2423static void
2235read_process_ack (struct Plugin *plugin, 2424read_process_ack (struct Plugin *plugin,
2236 const struct GNUNET_MessageHeader *msg, 2425 const struct GNUNET_MessageHeader *msg,
@@ -2299,6 +2488,9 @@ read_process_ack (struct Plugin *plugin,
2299} 2488}
2300 2489
2301 2490
2491/**
2492 * FIXME.
2493 */
2302static void 2494static void
2303read_process_fragment (struct Plugin *plugin, 2495read_process_fragment (struct Plugin *plugin,
2304 const struct GNUNET_MessageHeader *msg, 2496 const struct GNUNET_MessageHeader *msg,
@@ -2426,12 +2618,10 @@ udp_select_read (struct Plugin *plugin,
2426 GNUNET_break_op(0); 2618 GNUNET_break_op(0);
2427 return; 2619 return;
2428 } 2620 }
2429 2621 GNUNET_STATISTICS_update (plugin->env->stats,
2430 GNUNET_STATISTICS_update (plugin->env->stats, "# UDP, total, bytes, received", 2622 "# UDP, total, bytes, received",
2431 size, GNUNET_NO); 2623 size,
2432 2624 GNUNET_NO);
2433
2434
2435 2625
2436 switch (ntohs (msg->type)) 2626 switch (ntohs (msg->type))
2437 { 2627 {
@@ -2457,16 +2647,23 @@ udp_select_read (struct Plugin *plugin,
2457} 2647}
2458 2648
2459 2649
2650/**
2651 * FIXME.
2652 */
2460static struct UDP_MessageWrapper * 2653static struct UDP_MessageWrapper *
2461remove_timeout_messages_and_select (struct UDP_MessageWrapper *head, 2654remove_timeout_messages_and_select (struct UDP_MessageWrapper *head,
2462 struct GNUNET_NETWORK_Handle *sock) 2655 struct GNUNET_NETWORK_Handle *sock)
2463{ 2656{
2464 struct UDP_MessageWrapper *udpw = NULL; 2657 struct UDP_MessageWrapper *udpw = NULL;
2465 struct GNUNET_TIME_Relative remaining; 2658 struct GNUNET_TIME_Relative remaining;
2659 struct Session *session;
2660 struct Plugin *plugin;
2466 2661
2467 udpw = head; 2662 udpw = head;
2468 while (udpw != NULL ) 2663 while (NULL != udpw)
2469 { 2664 {
2665 session = udpw->session;
2666 plugin = session->plugin;
2470 /* Find messages with timeout */ 2667 /* Find messages with timeout */
2471 remaining = GNUNET_TIME_absolute_get_remaining (udpw->timeout); 2668 remaining = GNUNET_TIME_absolute_get_remaining (udpw->timeout);
2472 if (GNUNET_TIME_UNIT_ZERO.rel_value_us == remaining.rel_value_us) 2669 if (GNUNET_TIME_UNIT_ZERO.rel_value_us == remaining.rel_value_us)
@@ -2568,12 +2765,14 @@ remove_timeout_messages_and_select (struct UDP_MessageWrapper *head,
2568} 2765}
2569 2766
2570 2767
2768/**
2769 * FIXME.
2770 */
2571static void 2771static void
2572analyze_send_error (struct Plugin *plugin, 2772analyze_send_error (struct Plugin *plugin,
2573 const struct sockaddr *sa, 2773 const struct sockaddr *sa,
2574 socklen_t slen, int error) 2774 socklen_t slen, int error)
2575{ 2775{
2576 static int network_down_error;
2577 struct GNUNET_ATS_Information type; 2776 struct GNUNET_ATS_Information type;
2578 2777
2579 type = plugin->env->get_address_type (plugin->env->cls, sa, slen); 2778 type = plugin->env->get_address_type (plugin->env->cls, sa, slen);
@@ -2581,7 +2780,7 @@ analyze_send_error (struct Plugin *plugin,
2581 || (GNUNET_ATS_NET_WAN == ntohl (type.value))) 2780 || (GNUNET_ATS_NET_WAN == ntohl (type.value)))
2582 && ((ENETUNREACH == errno)|| (ENETDOWN == errno))) 2781 && ((ENETUNREACH == errno)|| (ENETDOWN == errno)))
2583 { 2782 {
2584 if ((network_down_error == GNUNET_NO) && (slen == sizeof (struct sockaddr_in))) 2783 if (slen == sizeof (struct sockaddr_in))
2585 { 2784 {
2586 /* IPv4: "Network unreachable" or "Network down" 2785 /* IPv4: "Network unreachable" or "Network down"
2587 * 2786 *
@@ -2592,7 +2791,7 @@ analyze_send_error (struct Plugin *plugin,
2592 "Network seems down, please check your network configuration\n"), 2791 "Network seems down, please check your network configuration\n"),
2593 GNUNET_a2s (sa, slen)); 2792 GNUNET_a2s (sa, slen));
2594 } 2793 }
2595 if ((network_down_error == GNUNET_NO) && (slen == sizeof (struct sockaddr_in6))) 2794 if (slen == sizeof (struct sockaddr_in6))
2596 { 2795 {
2597 /* IPv6: "Network unreachable" or "Network down" 2796 /* IPv6: "Network unreachable" or "Network down"
2598 * 2797 *
@@ -2600,7 +2799,6 @@ analyze_send_error (struct Plugin *plugin,
2600 * have a valid global IPv6 address assigned or we do not have 2799 * have a valid global IPv6 address assigned or we do not have
2601 * connectivity 2800 * connectivity
2602 */ 2801 */
2603
2604 LOG (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, 2802 LOG (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
2605 _("UDP could not transmit IPv6 message! " 2803 _("UDP could not transmit IPv6 message! "
2606 "Please check your network configuration and disable IPv6 if your " 2804 "Please check your network configuration and disable IPv6 if your "
@@ -2616,6 +2814,9 @@ analyze_send_error (struct Plugin *plugin,
2616} 2814}
2617 2815
2618 2816
2817/**
2818 * FIXME.
2819 */
2619static size_t 2820static size_t
2620udp_select_send (struct Plugin *plugin, 2821udp_select_send (struct Plugin *plugin,
2621 struct GNUNET_NETWORK_Handle *sock) 2822 struct GNUNET_NETWORK_Handle *sock)
@@ -2823,7 +3024,8 @@ setup_sockets (struct Plugin *plugin,
2823 tries = 0; 3024 tries = 0;
2824 while (tries < 10) 3025 while (tries < 10)
2825 { 3026 {
2826 LOG(GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv6 `%s'\n", 3027 LOG(GNUNET_ERROR_TYPE_DEBUG,
3028 "Binding to IPv6 `%s'\n",
2827 GNUNET_a2s (server_addr, addrlen)); 3029 GNUNET_a2s (server_addr, addrlen));
2828 /* binding */ 3030 /* binding */
2829 if (GNUNET_OK 3031 if (GNUNET_OK
@@ -2851,16 +3053,19 @@ setup_sockets (struct Plugin *plugin,
2851 3053
2852 if (plugin->sockv6 != NULL ) 3054 if (plugin->sockv6 != NULL )
2853 { 3055 {
2854 LOG(GNUNET_ERROR_TYPE_DEBUG, "IPv6 socket created on port %s\n", 3056 LOG (GNUNET_ERROR_TYPE_DEBUG,
2855 GNUNET_a2s (server_addr, addrlen)); 3057 "IPv6 socket created on port %s\n",
3058 GNUNET_a2s (server_addr, addrlen));
2856 addrs[sockets_created] = (struct sockaddr *) &server_addrv6; 3059 addrs[sockets_created] = (struct sockaddr *) &server_addrv6;
2857 addrlens[sockets_created] = sizeof(struct sockaddr_in6); 3060 addrlens[sockets_created] = sizeof(struct sockaddr_in6);
2858 sockets_created++; 3061 sockets_created++;
2859 } 3062 }
2860 else 3063 else
2861 { 3064 {
2862 LOG(GNUNET_ERROR_TYPE_ERROR, "Failed to bind UDP socket to %s: %s\n", 3065 LOG (GNUNET_ERROR_TYPE_ERROR,
2863 GNUNET_a2s (server_addr, addrlen), STRERROR (eno)); 3066 "Failed to bind UDP socket to %s: %s\n",
3067 GNUNET_a2s (server_addr, addrlen),
3068 STRERROR (eno));
2864 } 3069 }
2865 } 3070 }
2866 } 3071 }
@@ -2870,7 +3075,8 @@ setup_sockets (struct Plugin *plugin,
2870 plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0); 3075 plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
2871 if (NULL == plugin->sockv4) 3076 if (NULL == plugin->sockv4)
2872 { 3077 {
2873 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "socket"); 3078 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
3079 "socket");
2874 LOG(GNUNET_ERROR_TYPE_WARNING, 3080 LOG(GNUNET_ERROR_TYPE_WARNING,
2875 "Disabling IPv4 since it is not supported on this system!\n"); 3081 "Disabling IPv4 since it is not supported on this system!\n");
2876 plugin->enable_ipv4 = GNUNET_NO; 3082 plugin->enable_ipv4 = GNUNET_NO;
@@ -2989,6 +3195,62 @@ setup_sockets (struct Plugin *plugin,
2989 3195
2990 3196
2991/** 3197/**
3198 * Return information about the given session to the
3199 * monitor callback.
3200 *
3201 * @param cls the `struct Plugin` with the monitor callback (`sic`)
3202 * @param peer peer we send information about
3203 * @param value our `struct Session` to send information about
3204 * @return #GNUNET_OK (continue to iterate)
3205 */
3206static int
3207send_session_info_iter (void *cls,
3208 const struct GNUNET_PeerIdentity *peer,
3209 void *value)
3210{
3211 struct Plugin *plugin = cls;
3212 struct Session *session = value;
3213
3214 notify_session_monitor (plugin,
3215 session,
3216 GNUNET_TRANSPORT_SS_UP);
3217 return GNUNET_OK;
3218}
3219
3220
3221/**
3222 * Begin monitoring sessions of a plugin. There can only
3223 * be one active monitor per plugin (i.e. if there are
3224 * multiple monitors, the transport service needs to
3225 * multiplex the generated events over all of them).
3226 *
3227 * @param cls closure of the plugin
3228 * @param sic callback to invoke, NULL to disable monitor;
3229 * plugin will being by iterating over all active
3230 * sessions immediately and then enter monitor mode
3231 * @param sic_cls closure for @a sic
3232 */
3233static void
3234udp_plugin_setup_monitor (void *cls,
3235 GNUNET_TRANSPORT_SessionInfoCallback sic,
3236 void *sic_cls)
3237{
3238 struct Plugin *plugin = cls;
3239
3240 plugin->sic = sic;
3241 plugin->sic_cls = sic_cls;
3242 if (NULL != sic)
3243 {
3244 GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions,
3245 &send_session_info_iter,
3246 plugin);
3247 /* signal end of first iteration */
3248 sic (sic_cls, NULL, NULL);
3249 }
3250}
3251
3252
3253/**
2992 * The exported method. Makes the core api available via a global and 3254 * The exported method. Makes the core api available via a global and
2993 * returns the udp transport API. 3255 * returns the udp transport API.
2994 * 3256 *
@@ -3058,13 +3320,16 @@ libgnunet_plugin_transport_udp_init (void *cls)
3058 /* Addresses */ 3320 /* Addresses */
3059 have_bind4 = GNUNET_NO; 3321 have_bind4 = GNUNET_NO;
3060 memset (&server_addrv4, 0, sizeof(server_addrv4)); 3322 memset (&server_addrv4, 0, sizeof(server_addrv4));
3061 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp", 3323 if (GNUNET_YES ==
3062 "BINDTO", &bind4_address)) 3324 GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp",
3325 "BINDTO", &bind4_address))
3063 { 3326 {
3064 LOG (GNUNET_ERROR_TYPE_DEBUG, 3327 LOG (GNUNET_ERROR_TYPE_DEBUG,
3065 "Binding udp plugin to specific address: `%s'\n", 3328 "Binding udp plugin to specific address: `%s'\n",
3066 bind4_address); 3329 bind4_address);
3067 if (1 != inet_pton (AF_INET, bind4_address, &server_addrv4.sin_addr)) 3330 if (1 != inet_pton (AF_INET,
3331 bind4_address,
3332 &server_addrv4.sin_addr))
3068 { 3333 {
3069 GNUNET_free (bind4_address); 3334 GNUNET_free (bind4_address);
3070 return NULL; 3335 return NULL;
@@ -3079,8 +3344,11 @@ libgnunet_plugin_transport_udp_init (void *cls)
3079 "BINDTO6", &bind6_address)) 3344 "BINDTO6", &bind6_address))
3080 { 3345 {
3081 LOG (GNUNET_ERROR_TYPE_DEBUG, 3346 LOG (GNUNET_ERROR_TYPE_DEBUG,
3082 "Binding udp plugin to specific address: `%s'\n", bind6_address); 3347 "Binding udp plugin to specific address: `%s'\n",
3083 if (1 != inet_pton (AF_INET6, bind6_address, &server_addrv6.sin6_addr)) 3348 bind6_address);
3349 if (1 != inet_pton (AF_INET6,
3350 bind6_address,
3351 &server_addrv6.sin6_addr))
3084 { 3352 {
3085 LOG (GNUNET_ERROR_TYPE_ERROR, 3353 LOG (GNUNET_ERROR_TYPE_ERROR,
3086 _("Invalid IPv6 address: `%s'\n"), 3354 _("Invalid IPv6 address: `%s'\n"),
@@ -3092,9 +3360,6 @@ libgnunet_plugin_transport_udp_init (void *cls)
3092 } 3360 }
3093 GNUNET_free_non_null (bind6_address); 3361 GNUNET_free_non_null (bind6_address);
3094 3362
3095 /* Initialize my flags */
3096 myoptions = 0;
3097
3098 /* Enable neighbour discovery */ 3363 /* Enable neighbour discovery */
3099 enable_broadcasting = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 3364 enable_broadcasting = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
3100 "transport-udp", "BROADCAST"); 3365 "transport-udp", "BROADCAST");
@@ -3106,16 +3371,17 @@ libgnunet_plugin_transport_udp_init (void *cls)
3106 if (enable_broadcasting_recv == GNUNET_SYSERR) 3371 if (enable_broadcasting_recv == GNUNET_SYSERR)
3107 enable_broadcasting_recv = GNUNET_YES; 3372 enable_broadcasting_recv = GNUNET_YES;
3108 3373
3109 if (GNUNET_SYSERR 3374 if (GNUNET_SYSERR ==
3110 == GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp", 3375 GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp",
3111 "BROADCAST_INTERVAL", &fancy_interval)) 3376 "BROADCAST_INTERVAL",
3377 &fancy_interval))
3112 { 3378 {
3113 interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); 3379 interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10);
3114 } 3380 }
3115 else 3381 else
3116 { 3382 {
3117 if (GNUNET_SYSERR 3383 if (GNUNET_SYSERR ==
3118 == GNUNET_STRINGS_fancy_time_to_relative (fancy_interval, &interval)) 3384 GNUNET_STRINGS_fancy_time_to_relative (fancy_interval, &interval))
3119 { 3385 {
3120 interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); 3386 interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30);
3121 } 3387 }
@@ -3145,9 +3411,8 @@ libgnunet_plugin_transport_udp_init (void *cls)
3145 p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, p); 3411 p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, p);
3146 GNUNET_BANDWIDTH_tracker_init (&p->tracker, NULL, NULL, 3412 GNUNET_BANDWIDTH_tracker_init (&p->tracker, NULL, NULL,
3147 GNUNET_BANDWIDTH_value_init ((uint32_t) udp_max_bps), 30); 3413 GNUNET_BANDWIDTH_value_init ((uint32_t) udp_max_bps), 30);
3148 plugin = p; 3414 LOG(GNUNET_ERROR_TYPE_DEBUG,
3149 3415 "Setting up sockets\n");
3150 LOG(GNUNET_ERROR_TYPE_DEBUG, "Setting up sockets\n");
3151 res = setup_sockets (p, 3416 res = setup_sockets (p,
3152 (GNUNET_YES == have_bind6) ? &server_addrv6 : NULL, 3417 (GNUNET_YES == have_bind6) ? &server_addrv6 : NULL,
3153 (GNUNET_YES == have_bind4) ? &server_addrv4 : NULL); 3418 (GNUNET_YES == have_bind4) ? &server_addrv4 : NULL);
@@ -3179,6 +3444,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
3179 api->send = &udp_plugin_send; 3444 api->send = &udp_plugin_send;
3180 api->get_network = &udp_get_network; 3445 api->get_network = &udp_get_network;
3181 api->update_session_timeout = &udp_plugin_update_session_timeout; 3446 api->update_session_timeout = &udp_plugin_update_session_timeout;
3447 api->setup_monitor = &udp_plugin_setup_monitor;
3182 return api; 3448 return api;
3183} 3449}
3184 3450
@@ -3246,7 +3512,8 @@ libgnunet_plugin_transport_udp_done (void *cls)
3246 { 3512 {
3247 if (NULL != plugin->sockv4) 3513 if (NULL != plugin->sockv4)
3248 { 3514 {
3249 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4)); 3515 GNUNET_break (GNUNET_OK ==
3516 GNUNET_NETWORK_socket_close (plugin->sockv4));
3250 plugin->sockv4 = NULL; 3517 plugin->sockv4 = NULL;
3251 } 3518 }
3252 GNUNET_NETWORK_fdset_destroy (plugin->rs_v4); 3519 GNUNET_NETWORK_fdset_destroy (plugin->rs_v4);
@@ -3256,7 +3523,8 @@ libgnunet_plugin_transport_udp_done (void *cls)
3256 { 3523 {
3257 if (NULL != plugin->sockv6) 3524 if (NULL != plugin->sockv6)
3258 { 3525 {
3259 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv6)); 3526 GNUNET_break (GNUNET_OK ==
3527 GNUNET_NETWORK_socket_close (plugin->sockv6));
3260 plugin->sockv6 = NULL; 3528 plugin->sockv6 = NULL;
3261 3529
3262 GNUNET_NETWORK_fdset_destroy (plugin->rs_v6); 3530 GNUNET_NETWORK_fdset_destroy (plugin->rs_v6);
@@ -3308,13 +3576,13 @@ libgnunet_plugin_transport_udp_done (void *cls)
3308 &disconnect_and_free_it, plugin); 3576 &disconnect_and_free_it, plugin);
3309 GNUNET_CONTAINER_multipeermap_destroy (plugin->sessions); 3577 GNUNET_CONTAINER_multipeermap_destroy (plugin->sessions);
3310 3578
3311 next = ppc_dll_head; 3579 next = plugin->ppc_dll_head;
3312 for (cur = next; NULL != cur; cur = next) 3580 for (cur = next; NULL != cur; cur = next)
3313 { 3581 {
3314 GNUNET_break(0); 3582 GNUNET_break(0);
3315 next = cur->next; 3583 next = cur->next;
3316 GNUNET_CONTAINER_DLL_remove (ppc_dll_head, 3584 GNUNET_CONTAINER_DLL_remove (plugin->ppc_dll_head,
3317 ppc_dll_tail, 3585 plugin->ppc_dll_tail,
3318 cur); 3586 cur);
3319 GNUNET_RESOLVER_request_cancel (cur->resolver_handle); 3587 GNUNET_RESOLVER_request_cancel (cur->resolver_handle);
3320 GNUNET_free (cur); 3588 GNUNET_free (cur);
diff --git a/src/transport/plugin_transport_udp.h b/src/transport/plugin_transport_udp.h
index 44791668b..3770b3b70 100644
--- a/src/transport/plugin_transport_udp.h
+++ b/src/transport/plugin_transport_udp.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2010, 2011 Christian Grothoff (and other contributing authors) 3 (C) 2010-2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -47,6 +47,7 @@
47#define PLUGIN_NAME "udp" 47#define PLUGIN_NAME "udp"
48 48
49#define DEBUG_UDP GNUNET_NO 49#define DEBUG_UDP GNUNET_NO
50
50#define DEBUG_UDP_BROADCASTING GNUNET_NO 51#define DEBUG_UDP_BROADCASTING GNUNET_NO
51 52
52/** 53/**
@@ -126,6 +127,8 @@ struct UDPMessage
126 127
127struct UDP_MessageWrapper; 128struct UDP_MessageWrapper;
128 129
130struct PrettyPrinterContext;
131
129 132
130/** 133/**
131 * Encapsulation of all of the state of the plugin. 134 * Encapsulation of all of the state of the plugin.
@@ -140,7 +143,7 @@ struct Plugin
140 143
141 /** 144 /**
142 * Session of peers with whom we are currently connected, 145 * Session of peers with whom we are currently connected,
143 * map of peer identity to 'struct PeerSession'. 146 * map of peer identity to `struct Session *`.
144 */ 147 */
145 struct GNUNET_CONTAINER_MultiPeerMap *sessions; 148 struct GNUNET_CONTAINER_MultiPeerMap *sessions;
146 149
@@ -150,9 +153,13 @@ struct Plugin
150 struct GNUNET_CONTAINER_Heap *defrag_ctxs; 153 struct GNUNET_CONTAINER_Heap *defrag_ctxs;
151 154
152 /** 155 /**
153 * ID of select task 156 * ID of select task for IPv4
154 */ 157 */
155 GNUNET_SCHEDULER_TaskIdentifier select_task; 158 GNUNET_SCHEDULER_TaskIdentifier select_task;
159
160 /**
161 * ID of select task for IPv6
162 */
156 GNUNET_SCHEDULER_TaskIdentifier select_task_v6; 163 GNUNET_SCHEDULER_TaskIdentifier select_task_v6;
157 164
158 /** 165 /**
@@ -175,12 +182,6 @@ struct Plugin
175 */ 182 */
176 char *bind6_address; 183 char *bind6_address;
177 184
178
179 /**
180 * Bytes currently in buffer
181 */
182 int64_t bytes_in_buffer;
183
184 /** 185 /**
185 * Handle to NAT traversal support. 186 * Handle to NAT traversal support.
186 */ 187 */
@@ -196,13 +197,11 @@ struct Plugin
196 */ 197 */
197 struct GNUNET_NETWORK_FDSet *ws_v4; 198 struct GNUNET_NETWORK_FDSet *ws_v4;
198 199
199
200 /** 200 /**
201 * The read socket for IPv4 201 * The read socket for IPv4
202 */ 202 */
203 struct GNUNET_NETWORK_Handle *sockv4; 203 struct GNUNET_NETWORK_Handle *sockv4;
204 204
205
206 /** 205 /**
207 * FD Read set 206 * FD Read set
208 */ 207 */
@@ -219,20 +218,64 @@ struct Plugin
219 struct GNUNET_NETWORK_Handle *sockv6; 218 struct GNUNET_NETWORK_Handle *sockv6;
220 219
221 /** 220 /**
222 * Beacon broadcasting 221 * Tokenizer for inbound IPv6 messages.
223 * -------------------
224 */ 222 */
223 struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv6_mst;
225 224
226 /** 225 /**
227 * Broadcast interval 226 * Tokenizer for inbound IPv4 messages.
228 */ 227 */
229 struct GNUNET_TIME_Relative broadcast_interval; 228 struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv4_mst;
230 229
231 /** 230 /**
232 * Tokenizer for inbound messages. 231 * Head of DLL of broadcast addresses
233 */ 232 */
234 struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv6_mst; 233 struct BroadcastAddress *broadcast_tail;
235 struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv4_mst; 234
235 /**
236 * Tail of DLL of broadcast addresses
237 */
238 struct BroadcastAddress *broadcast_head;
239
240 /**
241 * Head of messages in IPv4 queue.
242 */
243 struct UDP_MessageWrapper *ipv4_queue_head;
244
245 /**
246 * Tail of messages in IPv4 queue.
247 */
248 struct UDP_MessageWrapper *ipv4_queue_tail;
249
250 /**
251 * Head of messages in IPv6 queue.
252 */
253 struct UDP_MessageWrapper *ipv6_queue_head;
254
255 /**
256 * Tail of messages in IPv6 queue.
257 */
258 struct UDP_MessageWrapper *ipv6_queue_tail;
259
260 /**
261 * Running pretty printers: head
262 */
263 struct PrettyPrinterContext *ppc_dll_head;
264
265 /**
266 * Running pretty printers: tail
267 */
268 struct PrettyPrinterContext *ppc_dll_tail;
269
270 /**
271 * Function to call about session status changes.
272 */
273 GNUNET_TRANSPORT_SessionInfoCallback sic;
274
275 /**
276 * Closure for @e sic.
277 */
278 void *sic_cls;
236 279
237 /** 280 /**
238 * IPv6 multicast address 281 * IPv6 multicast address
@@ -240,28 +283,37 @@ struct Plugin
240 struct sockaddr_in6 ipv6_multicast_address; 283 struct sockaddr_in6 ipv6_multicast_address;
241 284
242 /** 285 /**
243 * DLL of broadcast addresses 286 * Broadcast interval
244 */ 287 */
245 struct BroadcastAddress *broadcast_tail; 288 struct GNUNET_TIME_Relative broadcast_interval;
246 struct BroadcastAddress *broadcast_head; 289
290 /**
291 * Bytes currently in buffer
292 */
293 int64_t bytes_in_buffer;
247 294
248 /** 295 /**
249 * Is IPv6 enabled: GNUNET_YES or GNUNET_NO 296 * Address options
297 */
298 uint32_t myoptions;
299
300 /**
301 * Is IPv6 enabled: #GNUNET_YES or #GNUNET_NO
250 */ 302 */
251 int enable_ipv6; 303 int enable_ipv6;
252 304
253 /** 305 /**
254 * Is IPv4 enabled: GNUNET_YES or GNUNET_NO 306 * Is IPv4 enabled: #GNUNET_YES or #GNUNET_NO
255 */ 307 */
256 int enable_ipv4; 308 int enable_ipv4;
257 309
258 /** 310 /**
259 * Is broadcasting enabled: GNUNET_YES or GNUNET_NO 311 * Is broadcasting enabled: #GNUNET_YES or #GNUNET_NO
260 */ 312 */
261 int enable_broadcasting; 313 int enable_broadcasting;
262 314
263 /** 315 /**
264 * Is receiving broadcasts enabled: GNUNET_YES or GNUNET_NO 316 * Is receiving broadcasts enabled: #GNUNET_YES or #GNUNET_NO
265 */ 317 */
266 int enable_broadcasting_receiving; 318 int enable_broadcasting_receiving;
267 319
@@ -280,11 +332,6 @@ struct Plugin
280 */ 332 */
281 uint16_t aport; 333 uint16_t aport;
282 334
283 struct UDP_MessageWrapper *ipv4_queue_head;
284 struct UDP_MessageWrapper *ipv4_queue_tail;
285
286 struct UDP_MessageWrapper *ipv6_queue_head;
287 struct UDP_MessageWrapper *ipv6_queue_tail;
288}; 335};
289 336
290 337
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c
index 6c0c12065..0c3d29733 100644
--- a/src/transport/plugin_transport_unix.c
+++ b/src/transport/plugin_transport_unix.c
@@ -522,17 +522,17 @@ session_timeout (void *cls,
522 session->timeout_task = GNUNET_SCHEDULER_NO_TASK; 522 session->timeout_task = GNUNET_SCHEDULER_NO_TASK;
523 left = GNUNET_TIME_absolute_get_remaining (session->timeout); 523 left = GNUNET_TIME_absolute_get_remaining (session->timeout);
524 if (0 != left.rel_value_us) 524 if (0 != left.rel_value_us)
525 { 525 {
526 /* not actually our turn yet, but let's at least update 526 /* not actually our turn yet, but let's at least update
527 the monitor, it may think we're about to die ... */ 527 the monitor, it may think we're about to die ... */
528 notify_session_monitor (session->plugin, 528 notify_session_monitor (session->plugin,
529 session, 529 session,
530 GNUNET_TRANSPORT_SS_UP); 530 GNUNET_TRANSPORT_SS_UP);
531 session->timeout_task = GNUNET_SCHEDULER_add_delayed (left, 531 session->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
532 &session_timeout, 532 &session_timeout,
533 session); 533 session);
534 return; 534 return;
535 } 535 }
536 LOG (GNUNET_ERROR_TYPE_DEBUG, 536 LOG (GNUNET_ERROR_TYPE_DEBUG,
537 "Session %p was idle for %s, disconnecting\n", 537 "Session %p was idle for %s, disconnecting\n",
538 session, 538 session,