removing ats functions from plugins, instead provide callback function
[oweals/gnunet.git] / src / transport / plugin_transport_udp.c
1 /*
2      This file is part of GNUnet
3      (C) 2010, 2011 Christian Grothoff (and other contributing authors)
4
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
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file transport/plugin_transport_udp.c
23  * @brief Implementation of the UDP NAT punching
24  *        transport service
25  * @author Christian Grothoff
26  * @author Nathan Evans
27  */
28 #include "platform.h"
29 #include "gnunet_hello_lib.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_fragmentation_lib.h"
32 #include "gnunet_nat_lib.h"
33 #include "gnunet_protocols.h"
34 #include "gnunet_resolver_service.h"
35 #include "gnunet_signatures.h"
36 #include "gnunet_constants.h"
37 #include "gnunet_statistics_service.h"
38 #include "gnunet_transport_service.h"
39 #include "gnunet_transport_plugin.h"
40 #include "transport.h"
41
42 #define LOG(kind,...) GNUNET_log_from (kind, "transport-udp", __VA_ARGS__)
43
44
45 #define DEBUG_UDP GNUNET_EXTRA_LOGGING
46
47 /**
48  * MTU for fragmentation subsystem.  Should be conservative since
49  * all communicating peers MUST work with this MTU.
50  */
51 #define UDP_MTU 1400
52
53 /**
54  * Number of messages we can defragment in parallel.  We only really
55  * defragment 1 message at a time, but if messages get re-ordered, we
56  * may want to keep knowledge about the previous message to avoid
57  * discarding the current message in favor of a single fragment of a
58  * previous message.  3 should be good since we don't expect massive
59  * message reorderings with UDP.
60  */
61 #define UDP_MAX_MESSAGES_IN_DEFRAG 3
62
63 /**
64  * We keep a defragmentation queue per sender address.  How many
65  * sender addresses do we support at the same time? Memory consumption
66  * is roughly a factor of 32k * UDP_MAX_MESSAGES_IN_DEFRAG times this
67  * value. (So 128 corresponds to 12 MB and should suffice for
68  * connecting to roughly 128 peers via UDP).
69  */
70 #define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128
71
72
73 /**
74  * UDP Message-Packet header (after defragmentation).
75  */
76 struct UDPMessage
77 {
78   /**
79    * Message header.
80    */
81   struct GNUNET_MessageHeader header;
82
83   /**
84    * Always zero for now.
85    */
86   uint32_t reserved;
87
88   /**
89    * What is the identity of the sender
90    */
91   struct GNUNET_PeerIdentity sender;
92
93 };
94
95
96 /**
97  * UDP ACK Message-Packet header (after defragmentation).
98  */
99 struct UDP_ACK_Message
100 {
101   /**
102    * Message header.
103    */
104   struct GNUNET_MessageHeader header;
105
106   /**
107    * Desired delay for flow control
108    */
109   uint32_t delay;
110
111   /**
112    * What is the identity of the sender
113    */
114   struct GNUNET_PeerIdentity sender;
115 };
116
117
118 struct UDP_Beacon_Message
119 {
120  /**
121   * Message header.
122   */
123   struct GNUNET_MessageHeader header;
124
125  /**
126   * What is the identity of the sender
127   */
128   struct GNUNET_PeerIdentity sender;
129 };
130
131
132 /**
133  * Network format for IPv4 addresses.
134  */
135 struct IPv4UdpAddress
136 {
137   /**
138    * IPv4 address, in network byte order.
139    */
140   uint32_t ipv4_addr GNUNET_PACKED;
141
142   /**
143    * Port number, in network byte order.
144    */
145   uint16_t u4_port GNUNET_PACKED;
146 };
147
148
149 /**
150  * Network format for IPv6 addresses.
151  */
152 struct IPv6UdpAddress
153 {
154
155   /**
156    * IPv6 address.
157    */
158   struct in6_addr ipv6_addr GNUNET_PACKED;
159
160   /**
161    * Port number, in network byte order.
162    */
163   uint16_t u6_port GNUNET_PACKED;
164 };
165
166
167 /* Forward definition */
168 struct Plugin;
169
170
171 /**
172  * Session with another peer.  FIXME: why not make this into
173  * a regular 'struct Session' and pass it around!?
174  */
175 struct Session
176 {
177
178   /**
179    * Which peer is this session for?
180    */
181   struct GNUNET_PeerIdentity target;
182
183   /**
184    * Pointer to the global plugin struct.
185    */
186   struct Plugin *plugin;
187
188   /**
189    * Address of the other peer
190    */
191   const struct sockaddr *sock_addr;
192
193   size_t addrlen;
194
195   /**
196    * Function to call upon completion of the transmission.
197    */
198   GNUNET_TRANSPORT_TransmitContinuation cont;
199
200   /**
201    * Closure for 'cont'.
202    */
203   void *cont_cls;
204
205   /**
206    * Current outgoing message to this peer.
207    */
208   struct GNUNET_FRAGMENT_Context *frag;
209
210   struct GNUNET_TIME_Absolute valid_until;
211
212   GNUNET_SCHEDULER_TaskIdentifier invalidation_task;
213
214   GNUNET_SCHEDULER_TaskIdentifier delayed_cont_task;
215
216   /**
217    * Desired delay for next sending we send to other peer
218    */
219   struct GNUNET_TIME_Relative flow_delay_for_other_peer;
220
221   /**
222    * Desired delay for next sending we received from other peer
223    */
224   struct GNUNET_TIME_Absolute flow_delay_from_other_peer;
225 };
226
227
228 /**
229  * Data structure to track defragmentation contexts based
230  * on the source of the UDP traffic.
231  */
232 struct ReceiveContext
233 {
234
235   /**
236    * Defragmentation context.
237    */
238   struct GNUNET_DEFRAGMENT_Context *defrag;
239
240   /**
241    * Source address this receive context is for (allocated at the
242    * end of the struct).
243    */
244   const struct sockaddr *src_addr;
245
246   /**
247    * Reference to master plugin struct.
248    */
249   struct Plugin *plugin;
250
251   /**
252    * Node in the defrag heap.
253    */
254   struct GNUNET_CONTAINER_HeapNode *hnode;
255
256   /**
257    * Length of 'src_addr'
258    */
259   size_t addr_len;
260
261   struct GNUNET_PeerIdentity id;
262
263 };
264
265 struct BroadcastAddress
266 {
267   struct BroadcastAddress *next;
268   struct BroadcastAddress *prev;
269
270   void *addr;
271   socklen_t addrlen;
272 };
273
274
275 /**
276  * Encapsulation of all of the state of the plugin.
277  */
278 struct Plugin
279 {
280
281   /**
282    * Our environment.
283    */
284   struct GNUNET_TRANSPORT_PluginEnvironment *env;
285
286   /**
287    * Session of peers with whom we are currently connected,
288    * map of peer identity to 'struct PeerSession'.
289    */
290   struct GNUNET_CONTAINER_MultiHashMap *sessions;
291
292   /**
293    * Session of peers with whom we are currently connected,
294    * map of peer identity to 'struct PeerSession'.
295    */
296   struct GNUNET_CONTAINER_MultiHashMap *inbound_sessions;
297
298   /**
299    * Heap with all of our defragmentation activities.
300    */
301   struct GNUNET_CONTAINER_Heap *defrags;
302
303   /**
304    * ID of select task
305    */
306   GNUNET_SCHEDULER_TaskIdentifier select_task;
307
308   /**
309    * Tokenizer for inbound messages.
310    */
311   struct GNUNET_SERVER_MessageStreamTokenizer *mst;
312
313   /**
314    * Bandwidth tracker to limit global UDP traffic.
315    */
316   struct GNUNET_BANDWIDTH_Tracker tracker;
317
318   /**
319    * Address we were told to bind to exclusively (IPv4).
320    */
321   char *bind4_address;
322
323   /**
324    * Address we were told to bind to exclusively (IPv6).
325    */
326   char *bind6_address;
327
328   /**
329    * Handle to NAT traversal support.
330    */
331   struct GNUNET_NAT_Handle *nat;
332
333   /**
334    * FD Read set
335    */
336   struct GNUNET_NETWORK_FDSet *rs;
337
338   /**
339    * The read socket for IPv4
340    */
341   struct GNUNET_NETWORK_Handle *sockv4;
342
343   /**
344    * The read socket for IPv6
345    */
346   struct GNUNET_NETWORK_Handle *sockv6;
347
348   /**
349    * Beacon broadcasting
350    * -------------------
351    */
352
353   /**
354    * Broadcast interval
355    */
356   struct GNUNET_TIME_Relative broadcast_interval;
357
358   /**
359    * Broadcast with IPv4
360    */
361   int broadcast_ipv4;
362
363   /**
364    * Broadcast with IPv6
365    */
366   int broadcast_ipv6;
367
368
369   /**
370    * Tokenizer for inbound messages.
371    */
372   struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv6_mst;
373   struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv4_mst;
374
375   /**
376    * ID of select broadcast task
377    */
378   GNUNET_SCHEDULER_TaskIdentifier send_ipv4_broadcast_task;
379
380   /**
381    * ID of select broadcast task
382    */
383   GNUNET_SCHEDULER_TaskIdentifier send_ipv6_broadcast_task;
384
385   /**
386    * IPv6 multicast address
387    */
388   struct sockaddr_in6 ipv6_multicast_address;
389
390   /**
391    * DLL of IPv4 broadcast addresses
392    */
393   struct BroadcastAddress *ipv4_broadcast_tail;
394   struct BroadcastAddress *ipv4_broadcast_head;
395
396
397   /**
398    * expected delay for ACKs
399    */
400   struct GNUNET_TIME_Relative last_expected_delay;
401
402   /**
403    * Port we broadcasting on.
404    */
405   uint16_t broadcast_port;
406
407   /**
408    * Port we listen on.
409    */
410   uint16_t port;
411
412   /**
413    * Port we advertise on.
414    */
415   uint16_t aport;
416
417 };
418
419 struct PeerSessionIteratorContext
420 {
421   struct Session *result;
422   const void *addr;
423   size_t addrlen;
424 };
425
426
427 /**
428  * Lookup the session for the given peer.
429  *
430  * @param plugin the plugin
431  * @param peer peer's identity
432  * @return NULL if we have no session
433  */
434 static struct Session *
435 find_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *peer)
436 {
437   return GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
438                                             &peer->hashPubKey);
439 }
440
441
442 static int
443 inbound_session_iterator (void *cls, const GNUNET_HashCode * key, void *value)
444 {
445   struct PeerSessionIteratorContext *psc = cls;
446   struct Session *s = value;
447
448   if (s->addrlen == psc->addrlen)
449   {
450     if (0 == memcmp (&s[1], psc->addr, s->addrlen))
451       psc->result = s;
452   }
453   if (psc->result != NULL)
454     return GNUNET_NO;
455   return GNUNET_YES;
456 }
457
458
459 /**
460  * Lookup the session for the given peer.
461  *
462  * @param plugin the plugin
463  * @param peer peer's identity
464  * @param addr address
465  * @param addrlen address length
466  * @return NULL if we have no session
467  */
468 static struct Session *
469 find_inbound_session (struct Plugin *plugin,
470                       const struct GNUNET_PeerIdentity *peer, const void *addr,
471                       size_t addrlen)
472 {
473   struct PeerSessionIteratorContext psc;
474
475   psc.result = NULL;
476   psc.addrlen = addrlen;
477   psc.addr = addr;
478
479   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->inbound_sessions,
480                                               &peer->hashPubKey,
481                                               &inbound_session_iterator, &psc);
482   return psc.result;
483 }
484
485
486 static int
487 inbound_session_by_addr_iterator (void *cls, const GNUNET_HashCode * key,
488                                   void *value)
489 {
490   struct PeerSessionIteratorContext *psc = cls;
491   struct Session *s = value;
492
493   if (s->addrlen == psc->addrlen)
494   {
495     if (0 == memcmp (&s[1], psc->addr, s->addrlen))
496       psc->result = s;
497   }
498   if (psc->result != NULL)
499     return GNUNET_NO;
500   else
501     return GNUNET_YES;
502 };
503
504 /**
505  * Lookup the session for the given peer just by address.
506  *
507  * @param plugin the plugin
508  * @param addr address
509  * @param addrlen address length
510  * @return NULL if we have no session
511  */
512 static struct Session *
513 find_inbound_session_by_addr (struct Plugin *plugin, const void *addr,
514                               size_t addrlen)
515 {
516   struct PeerSessionIteratorContext psc;
517
518   psc.result = NULL;
519   psc.addrlen = addrlen;
520   psc.addr = addr;
521
522   GNUNET_CONTAINER_multihashmap_iterate (plugin->inbound_sessions,
523                                          &inbound_session_by_addr_iterator,
524                                          &psc);
525   return psc.result;
526 }
527
528
529 /**
530  * Destroy a session, plugin is being unloaded.
531  *
532  * @param cls unused
533  * @param key hash of public key of target peer
534  * @param value a 'struct PeerSession*' to clean up
535  * @return GNUNET_OK (continue to iterate)
536  */
537 static int
538 destroy_session (void *cls, const GNUNET_HashCode * key, void *value)
539 {
540   struct Session *peer_session = value;
541
542   GNUNET_assert (GNUNET_YES ==
543                  GNUNET_CONTAINER_multihashmap_remove (peer_session->
544                                                        plugin->sessions,
545                                                        &peer_session->
546                                                        target.hashPubKey,
547                                                        peer_session));
548   if (peer_session->frag != NULL)
549     GNUNET_FRAGMENT_context_destroy (peer_session->frag);
550   if (GNUNET_SCHEDULER_NO_TASK != peer_session->delayed_cont_task)
551     GNUNET_SCHEDULER_cancel (peer_session->delayed_cont_task);
552   GNUNET_free (peer_session);
553   return GNUNET_OK;
554 }
555
556
557 /**
558  * Destroy a session, plugin is being unloaded.
559  *
560  * @param cls unused
561  * @param key hash of public key of target peer
562  * @param value a 'struct PeerSession*' to clean up
563  * @return GNUNET_OK (continue to iterate)
564  */
565 static int
566 destroy_inbound_session (void *cls, const GNUNET_HashCode * key, void *value)
567 {
568   struct Session *s = value;
569
570   if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK)
571     GNUNET_SCHEDULER_cancel (s->invalidation_task);
572   if (GNUNET_SCHEDULER_NO_TASK != s->delayed_cont_task)
573     GNUNET_SCHEDULER_cancel (s->delayed_cont_task);
574   GNUNET_CONTAINER_multihashmap_remove (s->plugin->inbound_sessions,
575                                         &s->target.hashPubKey, s);
576   GNUNET_free (s);
577   return GNUNET_OK;
578 }
579
580
581 /**
582  * Disconnect from a remote node.  Clean up session if we have one for this peer
583  *
584  * @param cls closure for this call (should be handle to Plugin)
585  * @param target the peeridentity of the peer to disconnect
586  * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
587  */
588 static void
589 udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
590 {
591   struct Plugin *plugin = cls;
592   struct Session *session;
593
594   session = find_session (plugin, target);
595   if (NULL == session)
596     return;
597   GNUNET_assert (GNUNET_OK ==
598                  GNUNET_CONTAINER_multihashmap_remove (plugin->sessions,
599                                                        &target->hashPubKey,
600                                                        session));
601
602   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->inbound_sessions,
603                                               &target->hashPubKey,
604                                               &destroy_inbound_session, NULL);
605   plugin->last_expected_delay = GNUNET_FRAGMENT_context_destroy (session->frag);
606   if (GNUNET_SCHEDULER_NO_TASK != session->delayed_cont_task)
607     GNUNET_SCHEDULER_cancel (session->delayed_cont_task);
608   if (session->cont != NULL)
609     session->cont (session->cont_cls, target, GNUNET_SYSERR);
610   GNUNET_free (session);
611 }
612
613
614 /**
615  * Actually send out the message.
616  *
617  * @param plugin the plugin
618  * @param sa the address to send the message to
619  * @param msg message to transmit
620  * @return the number of bytes written
621  */
622 static ssize_t
623 udp_send (struct Plugin *plugin, const struct sockaddr *sa,
624           const struct GNUNET_MessageHeader *msg)
625 {
626   ssize_t sent;
627   size_t slen;
628
629   switch (sa->sa_family)
630   {
631   case AF_INET:
632     if (NULL == plugin->sockv4)
633       return 0;
634     sent =
635         GNUNET_NETWORK_socket_sendto (plugin->sockv4, msg, ntohs (msg->size),
636                                       sa, slen = sizeof (struct sockaddr_in));
637     break;
638   case AF_INET6:
639     if (NULL == plugin->sockv6)
640       return 0;
641     sent =
642         GNUNET_NETWORK_socket_sendto (plugin->sockv6, msg, ntohs (msg->size),
643                                       sa, slen = sizeof (struct sockaddr_in6));
644     break;
645   default:
646     GNUNET_break (0);
647     return 0;
648   }
649   if (GNUNET_SYSERR == sent)
650   {
651     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
652     LOG (GNUNET_ERROR_TYPE_ERROR,
653          "UDP transmited %u-byte message to %s (%d: %s)\n",
654          (unsigned int) ntohs (msg->size), GNUNET_a2s (sa, slen), (int) sent,
655          (sent < 0) ? STRERROR (errno) : "ok");
656
657   }
658   LOG (GNUNET_ERROR_TYPE_DEBUG,
659        "UDP transmited %u-byte message to %s (%d: %s)\n",
660        (unsigned int) ntohs (msg->size), GNUNET_a2s (sa, slen), (int) sent,
661        (sent < 0) ? STRERROR (errno) : "ok");
662   return sent;
663 }
664
665
666 /**
667  * Function that is called with messages created by the fragmentation
668  * module.  In the case of the 'proc' callback of the
669  * GNUNET_FRAGMENT_context_create function, this function must
670  * eventually call 'GNUNET_FRAGMENT_context_transmission_done'.
671  *
672  * @param cls closure, the 'struct PeerSession'
673  * @param msg the message that was created
674  */
675 static void
676 send_fragment (void *cls, const struct GNUNET_MessageHeader *msg)
677 {
678   struct Session *session = cls;
679
680   udp_send (session->plugin, session->sock_addr, msg);
681   GNUNET_FRAGMENT_context_transmission_done (session->frag);
682 }
683
684
685 static struct Session *
686 create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
687                 const void *addr, size_t addrlen,
688                 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
689 {
690   struct Session *peer_session;
691   const struct IPv4UdpAddress *t4;
692   const struct IPv6UdpAddress *t6;
693   struct sockaddr_in *v4;
694   struct sockaddr_in6 *v6;
695   size_t len;
696
697   switch (addrlen)
698   {
699   case sizeof (struct IPv4UdpAddress):
700     if (NULL == plugin->sockv4)
701     {
702       return NULL;
703     }
704     t4 = addr;
705     peer_session =
706         GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in));
707     len = sizeof (struct sockaddr_in);
708     v4 = (struct sockaddr_in *) &peer_session[1];
709     v4->sin_family = AF_INET;
710 #if HAVE_SOCKADDR_IN_SIN_LEN
711     v4->sin_len = sizeof (struct sockaddr_in);
712 #endif
713     v4->sin_port = t4->u4_port;
714     v4->sin_addr.s_addr = t4->ipv4_addr;
715     break;
716   case sizeof (struct IPv6UdpAddress):
717     if (NULL == plugin->sockv6)
718     {
719       return NULL;
720     }
721     t6 = addr;
722     peer_session =
723         GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in6));
724     len = sizeof (struct sockaddr_in6);
725     v6 = (struct sockaddr_in6 *) &peer_session[1];
726     v6->sin6_family = AF_INET6;
727 #if HAVE_SOCKADDR_IN_SIN_LEN
728     v6->sin6_len = sizeof (struct sockaddr_in6);
729 #endif
730     v6->sin6_port = t6->u6_port;
731     v6->sin6_addr = t6->ipv6_addr;
732     break;
733   default:
734     /* Must have a valid address to send to */
735     GNUNET_break_op (0);
736     return NULL;
737   }
738
739   peer_session->valid_until = GNUNET_TIME_absolute_get_zero ();
740   peer_session->invalidation_task = GNUNET_SCHEDULER_NO_TASK;
741   peer_session->addrlen = len;
742   peer_session->target = *target;
743   peer_session->plugin = plugin;
744   peer_session->sock_addr = (const struct sockaddr *) &peer_session[1];
745   peer_session->cont = cont;
746   peer_session->cont_cls = cont_cls;
747
748   return peer_session;
749 }
750
751 static const char *
752 udp_address_to_string (void *cls, const void *addr, size_t addrlen);
753
754
755 static void
756 udp_call_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
757 {
758   struct Session *s = cls;
759   GNUNET_TRANSPORT_TransmitContinuation cont = s->cont;
760
761   s->delayed_cont_task = GNUNET_SCHEDULER_NO_TASK;
762   s->cont = NULL;
763   cont (s->cont_cls, &s->target, GNUNET_OK);
764 }
765
766
767 /**
768  * Function that can be used by the transport service to transmit
769  * a message using the plugin.
770  *
771  * @param cls closure
772  * @param target who should receive this message (ignored by UDP)
773  * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
774  * @param msgbuf_size the size of the msgbuf to send
775  * @param priority how important is the message (ignored by UDP)
776  * @param timeout when should we time out (give up) if we can not transmit?
777  * @param session identifier used for this session (NULL for UDP)
778  * @param addr the addr to send the message to
779  * @param addrlen the len of addr
780  * @param force_address not used, we had better have an address to send to
781  *        because we are stateless!!
782  * @param cont continuation to call once the message has
783  *        been transmitted (or if the transport is ready
784  *        for the next transmission call; or if the
785  *        peer disconnected...)
786  * @param cont_cls closure for cont
787  *
788  * @return the number of bytes written (may return 0 and the message can
789  *         still be transmitted later!)
790  */
791 static ssize_t
792 udp_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
793                  const char *msgbuf, size_t msgbuf_size, unsigned int priority,
794                  struct GNUNET_TIME_Relative timeout, struct Session *session,
795                  const void *addr, size_t addrlen, int force_address,
796                  GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
797 {
798   struct Plugin *plugin = cls;
799   struct Session *peer_session;
800   struct Session *s;
801   const struct IPv4UdpAddress *t4;
802   const struct IPv6UdpAddress *t6;
803   size_t mlen = msgbuf_size + sizeof (struct UDPMessage);
804   char mbuf[mlen];
805   struct UDPMessage *udp;
806   struct GNUNET_TIME_Relative delta;
807
808   if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
809   {
810     GNUNET_break (0);
811     return GNUNET_SYSERR;
812   }
813
814   LOG (GNUNET_ERROR_TYPE_DEBUG,
815        "UDP transmits %u-byte message to `%s' using address `%s' session 0x%X mode %i\n",
816        msgbuf_size, GNUNET_i2s (target), udp_address_to_string (NULL, addr,
817                                                                 addrlen),
818        session, force_address);
819
820   if ((force_address == GNUNET_SYSERR) && (session == NULL))
821     return GNUNET_SYSERR;
822
823   s = NULL;
824   /* safety check: comparing address to address stored in session */
825   if ((session != NULL) && (addr != NULL) && (addrlen != 0))
826   {
827     s = session;
828     GNUNET_assert (GNUNET_YES ==
829                    GNUNET_CONTAINER_multihashmap_contains_value
830                    (plugin->inbound_sessions, &target->hashPubKey, s));
831
832     if (0 != memcmp (&s->target, target, sizeof (struct GNUNET_PeerIdentity)))
833       return GNUNET_SYSERR;
834     switch (addrlen)
835     {
836     case sizeof (struct IPv4UdpAddress):
837       if (NULL == plugin->sockv4)
838       {
839         if (cont != NULL)
840           cont (cont_cls, target, GNUNET_SYSERR);
841         return GNUNET_SYSERR;
842       }
843       t4 = addr;
844       if (s->addrlen != (sizeof (struct sockaddr_in)))
845         return GNUNET_SYSERR;
846       struct sockaddr_in *a4 = (struct sockaddr_in *) s->sock_addr;
847
848       GNUNET_assert (a4->sin_port == t4->u4_port);
849       GNUNET_assert (0 ==
850                      memcmp (&a4->sin_addr, &t4->ipv4_addr,
851                              sizeof (struct in_addr)));
852       LOG (GNUNET_ERROR_TYPE_DEBUG, "Session 0x%X successfully checked!\n",
853            session);
854       break;
855     case sizeof (struct IPv6UdpAddress):
856       if (NULL == plugin->sockv6)
857       {
858         if (cont != NULL)
859           cont (cont_cls, target, GNUNET_SYSERR);
860         return GNUNET_SYSERR;
861       }
862       t6 = addr;
863       GNUNET_assert (s->addrlen == sizeof (struct sockaddr_in6));
864       struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) s->sock_addr;
865
866       GNUNET_assert (a6->sin6_port == t6->u6_port);
867       GNUNET_assert (0 ==
868                      memcmp (&a6->sin6_addr, &t6->ipv6_addr,
869                              sizeof (struct in6_addr)));
870       LOG (GNUNET_ERROR_TYPE_DEBUG, "Session 0x%X successfully checked!\n",
871            session);
872       break;
873     default:
874       /* Must have a valid address to send to */
875       GNUNET_break_op (0);
876     }
877   }
878 //session_invalid:
879   if ((addr == NULL) || (addrlen == 0))
880     return GNUNET_SYSERR;
881   peer_session = create_session (plugin, target, addr, addrlen, cont, cont_cls);
882   if (peer_session == NULL)
883   {
884     if (cont != NULL)
885       cont (cont_cls, target, GNUNET_SYSERR);
886     return GNUNET_SYSERR;;
887   }
888
889   /* Message */
890   udp = (struct UDPMessage *) mbuf;
891   udp->header.size = htons (mlen);
892   udp->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE);
893   udp->reserved = htonl (0);
894   udp->sender = *plugin->env->my_identity;
895   memcpy (&udp[1], msgbuf, msgbuf_size);
896
897   if (s != NULL)
898     delta = GNUNET_TIME_absolute_get_remaining (s->flow_delay_from_other_peer);
899   else
900     delta = GNUNET_TIME_UNIT_ZERO;
901   if (mlen <= UDP_MTU)
902   {
903     mlen = udp_send (plugin, peer_session->sock_addr, &udp->header);
904     if (cont != NULL)
905     {
906       if ((delta.rel_value > 0) && (mlen > 0))
907       {
908         s->cont = cont;
909         s->cont_cls = cont_cls;
910         s->delayed_cont_task =
911             GNUNET_SCHEDULER_add_delayed (delta, &udp_call_continuation, s);
912       }
913       else
914         cont (cont_cls, target, (mlen > 0) ? GNUNET_OK : GNUNET_SYSERR);
915     }
916     GNUNET_free_non_null (peer_session);
917   }
918   else
919   {
920     GNUNET_assert (GNUNET_OK ==
921                    GNUNET_CONTAINER_multihashmap_put (plugin->sessions,
922                                                       &target->hashPubKey,
923                                                       peer_session,
924                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
925     peer_session->frag =
926         GNUNET_FRAGMENT_context_create (plugin->env->stats, UDP_MTU,
927                                         &plugin->tracker,
928                                         plugin->last_expected_delay,
929                                         &udp->header, &send_fragment,
930                                         peer_session);
931   }
932   return mlen;
933 }
934
935
936 /**
937  * Closure for 'process_inbound_tokenized_messages'
938  */
939 struct SourceInformation
940 {
941   /**
942    * Sender identity.
943    */
944   struct GNUNET_PeerIdentity sender;
945
946   /**
947    * Source address.
948    */
949   const void *arg;
950
951   /**
952    * Number of bytes in source address.
953    */
954   size_t args;
955
956   struct Session *session;
957 };
958
959
960 /**
961  * Message tokenizer has broken up an incomming message. Pass it on
962  * to the service.
963  *
964  * @param cls the 'struct Plugin'
965  * @param client the 'struct SourceInformation'
966  * @param hdr the actual message
967  */
968 static void
969 process_inbound_tokenized_messages (void *cls, void *client,
970                                     const struct GNUNET_MessageHeader *hdr)
971 {
972   struct Plugin *plugin = cls;
973   struct SourceInformation *si = client;
974   struct GNUNET_ATS_Information distance;
975   struct GNUNET_TIME_Relative delay;
976
977   /* setup ATS */
978   distance.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
979   distance.value = htonl (1);
980
981   LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving Session %X %s  to transport\n",
982        si->session, GNUNET_i2s (&si->session->target));
983   delay =
984       plugin->env->receive (plugin->env->cls, &si->sender, hdr, &distance, 1,
985                             si->session, si->arg, si->args);
986   si->session->flow_delay_for_other_peer = delay;
987 }
988
989 static void
990 invalidation_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
991 {
992   struct Session *s = cls;
993
994   s->invalidation_task = GNUNET_SCHEDULER_NO_TASK;
995   LOG (GNUNET_ERROR_TYPE_DEBUG, "Session %X (`%s') is now invalid\n", s,
996        GNUNET_a2s (s->sock_addr, s->addrlen));
997
998   s->plugin->env->session_end (s->plugin->env->cls, &s->target, s);
999   GNUNET_assert (GNUNET_YES ==
1000                  GNUNET_CONTAINER_multihashmap_remove (s->
1001                                                        plugin->inbound_sessions,
1002                                                        &s->target.hashPubKey,
1003                                                        s));
1004   GNUNET_free (s);
1005 }
1006
1007
1008 /**
1009  * We've received a UDP Message.  Process it (pass contents to main service).
1010  *
1011  * @param plugin plugin context
1012  * @param msg the message
1013  * @param sender_addr sender address
1014  * @param sender_addr_len number of bytes in sender_addr
1015  */
1016 static void
1017 process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
1018                      const struct sockaddr *sender_addr,
1019                      socklen_t sender_addr_len)
1020 {
1021   struct SourceInformation si;
1022   struct IPv4UdpAddress u4;
1023   struct IPv6UdpAddress u6;
1024   const void *arg;
1025   size_t args;
1026
1027   if (0 != ntohl (msg->reserved))
1028   {
1029     GNUNET_break_op (0);
1030     return;
1031   }
1032   if (ntohs (msg->header.size) <
1033       sizeof (struct GNUNET_MessageHeader) + sizeof (struct UDPMessage))
1034   {
1035     GNUNET_break_op (0);
1036     return;
1037   }
1038
1039   /* convert address */
1040   switch (sender_addr->sa_family)
1041   {
1042   case AF_INET:
1043     GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in));
1044     u4.ipv4_addr = ((struct sockaddr_in *) sender_addr)->sin_addr.s_addr;
1045     u4.u4_port = ((struct sockaddr_in *) sender_addr)->sin_port;
1046     arg = &u4;
1047     args = sizeof (u4);
1048     break;
1049   case AF_INET6:
1050     GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in6));
1051     u6.ipv6_addr = ((struct sockaddr_in6 *) sender_addr)->sin6_addr;
1052     u6.u6_port = ((struct sockaddr_in6 *) sender_addr)->sin6_port;
1053     arg = &u6;
1054     args = sizeof (u6);
1055     break;
1056   default:
1057     GNUNET_break (0);
1058     return;
1059   }
1060 #if DEBUG_UDP
1061   LOG (GNUNET_ERROR_TYPE_DEBUG,
1062        "Received message with %u bytes from peer `%s' at `%s'\n",
1063        (unsigned int) ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
1064        GNUNET_a2s (sender_addr, sender_addr_len));
1065 #endif
1066
1067   /* create a session for inbound connections */
1068   const struct UDPMessage *udp_msg = (const struct UDPMessage *) msg;
1069
1070   LOG (GNUNET_ERROR_TYPE_DEBUG,
1071        "Lookup inbound UDP sessions for peer `%s' address `%s'\n",
1072        GNUNET_i2s (&udp_msg->sender), udp_address_to_string (NULL, arg, args));
1073
1074   struct Session *s = NULL;
1075
1076   s = find_inbound_session (plugin, &udp_msg->sender, sender_addr,
1077                             sender_addr_len);
1078
1079   if (s != NULL)
1080   {
1081     LOG (GNUNET_ERROR_TYPE_DEBUG,
1082          "Found existing inbound UDP sessions 0x%X for peer `%s' address `%s'\n",
1083          s, GNUNET_i2s (&s->target), udp_address_to_string (NULL, arg, args));
1084   }
1085   else
1086   {
1087     s = create_session (plugin, &udp_msg->sender, arg, args, NULL, NULL);
1088     LOG (GNUNET_ERROR_TYPE_DEBUG,
1089          "Creating inbound UDP sessions 0x%X for peer `%s' address `%s'\n", s,
1090          GNUNET_i2s (&s->target), udp_address_to_string (NULL, arg, args));
1091
1092     GNUNET_assert (GNUNET_OK ==
1093                    GNUNET_CONTAINER_multihashmap_put (plugin->inbound_sessions,
1094                                                       &s->target.hashPubKey, s,
1095                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1096   }
1097   s->valid_until =
1098       GNUNET_TIME_relative_to_absolute
1099       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1100   if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK)
1101   {
1102     GNUNET_SCHEDULER_cancel (s->invalidation_task);
1103     s->invalidation_task = GNUNET_SCHEDULER_NO_TASK;
1104     LOG (GNUNET_ERROR_TYPE_DEBUG, "Rescheduling %X' `%s'\n", s,
1105          udp_address_to_string (NULL, arg, args));
1106   }
1107   s->invalidation_task =
1108       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1109                                     &invalidation_task, s);
1110   /* iterate over all embedded messages */
1111   si.sender = msg->sender;
1112   si.arg = arg;
1113   si.args = args;
1114   si.session = s;
1115   GNUNET_SERVER_mst_receive (plugin->mst, &si, (const char *) &msg[1],
1116                              ntohs (msg->header.size) -
1117                              sizeof (struct UDPMessage), GNUNET_YES, GNUNET_NO);
1118 }
1119
1120
1121 /**
1122  * Process a defragmented message.
1123  *
1124  * @param cls the 'struct ReceiveContext'
1125  * @param msg the message
1126  */
1127 static void
1128 fragment_msg_proc (void *cls, const struct GNUNET_MessageHeader *msg)
1129 {
1130   struct ReceiveContext *rc = cls;
1131
1132   if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE)
1133   {
1134     GNUNET_break (0);
1135     return;
1136   }
1137   if (ntohs (msg->size) < sizeof (struct UDPMessage))
1138   {
1139     GNUNET_break (0);
1140     return;
1141   }
1142   process_udp_message (rc->plugin, (const struct UDPMessage *) msg,
1143                        rc->src_addr, rc->addr_len);
1144 }
1145
1146
1147 /**
1148  * Transmit an acknowledgement.
1149  *
1150  * @param cls the 'struct ReceiveContext'
1151  * @param id message ID (unused)
1152  * @param msg ack to transmit
1153  */
1154 static void
1155 ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
1156 {
1157   struct ReceiveContext *rc = cls;
1158
1159   size_t msize = sizeof (struct UDP_ACK_Message) + ntohs (msg->size);
1160   char buf[msize];
1161   struct UDP_ACK_Message *udp_ack;
1162   uint32_t delay = 0;
1163
1164   struct Session *s;
1165
1166   s = find_inbound_session_by_addr (rc->plugin, rc->src_addr, rc->addr_len);
1167   if (s != NULL)
1168   {
1169     if (s->flow_delay_for_other_peer.rel_value <= UINT32_MAX)
1170       delay = s->flow_delay_for_other_peer.rel_value;
1171     else
1172       delay = UINT32_MAX;
1173   }
1174
1175
1176 #if DEBUG_UDP
1177   LOG (GNUNET_ERROR_TYPE_DEBUG,
1178        "Sending ACK to `%s' including delay of %u ms\n",
1179        GNUNET_a2s (rc->src_addr,
1180                    (rc->src_addr->sa_family ==
1181                     AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct
1182                                                                      sockaddr_in6)),
1183        delay);
1184 #endif
1185   udp_ack = (struct UDP_ACK_Message *) buf;
1186   udp_ack->header.size = htons ((uint16_t) msize);
1187   udp_ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK);
1188   udp_ack->delay = htonl (delay);
1189   udp_ack->sender = *rc->plugin->env->my_identity;
1190   memcpy (&udp_ack[1], msg, ntohs (msg->size));
1191   (void) udp_send (rc->plugin, rc->src_addr, &udp_ack->header);
1192 }
1193
1194
1195 /**
1196  * Closure for 'find_receive_context'.
1197  */
1198 struct FindReceiveContext
1199 {
1200   /**
1201    * Where to store the result.
1202    */
1203   struct ReceiveContext *rc;
1204
1205   /**
1206    * Address to find.
1207    */
1208   const struct sockaddr *addr;
1209
1210   /**
1211    * Number of bytes in 'addr'.
1212    */
1213   socklen_t addr_len;
1214
1215   struct Session *session;
1216 };
1217
1218
1219 /**
1220  * Scan the heap for a receive context with the given address.
1221  *
1222  * @param cls the 'struct FindReceiveContext'
1223  * @param node internal node of the heap
1224  * @param element value stored at the node (a 'struct ReceiveContext')
1225  * @param cost cost associated with the node
1226  * @return GNUNET_YES if we should continue to iterate,
1227  *         GNUNET_NO if not.
1228  */
1229 static int
1230 find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
1231                       void *element, GNUNET_CONTAINER_HeapCostType cost)
1232 {
1233   struct FindReceiveContext *frc = cls;
1234   struct ReceiveContext *e = element;
1235
1236   if ((frc->addr_len == e->addr_len) &&
1237       (0 == memcmp (frc->addr, e->src_addr, frc->addr_len)))
1238   {
1239     frc->rc = e;
1240     return GNUNET_NO;
1241   }
1242   return GNUNET_YES;
1243 }
1244
1245 struct Mstv4Context
1246 {
1247   struct Plugin *plugin;
1248
1249   struct IPv4UdpAddress addr;
1250 };
1251
1252 struct Mstv6Context
1253 {
1254   struct Plugin *plugin;
1255
1256   struct IPv6UdpAddress addr;
1257 };
1258
1259
1260 /**
1261  * Read and process a message from the given socket.
1262  *
1263  * @param plugin the overall plugin
1264  * @param rsock socket to read from
1265  */
1266 static void
1267 udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
1268 {
1269   socklen_t fromlen;
1270   char addr[32];
1271   char buf[65536];
1272   ssize_t ret;
1273   const struct GNUNET_MessageHeader *msg;
1274   const struct GNUNET_MessageHeader *ack;
1275   struct Session *peer_session;
1276   const struct UDP_ACK_Message *udp_ack;
1277   struct ReceiveContext *rc;
1278   struct GNUNET_TIME_Absolute now;
1279   struct FindReceiveContext frc;
1280   struct Session *s = NULL;
1281   struct GNUNET_TIME_Relative flow_delay;
1282
1283   fromlen = sizeof (addr);
1284   memset (&addr, 0, sizeof (addr));
1285   ret =
1286       GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof (buf),
1287                                       (struct sockaddr *) &addr, &fromlen);
1288   if (ret < sizeof (struct GNUNET_MessageHeader))
1289   {
1290     GNUNET_break_op (0);
1291     return;
1292   }
1293   msg = (const struct GNUNET_MessageHeader *) buf;
1294
1295   LOG (GNUNET_ERROR_TYPE_DEBUG,
1296        "UDP received %u-byte message from `%s' type %i\n", (unsigned int) ret,
1297        GNUNET_a2s ((const struct sockaddr *) addr, fromlen), ntohs (msg->type));
1298
1299   if (ret != ntohs (msg->size))
1300   {
1301     GNUNET_break_op (0);
1302     return;
1303   }
1304   switch (ntohs (msg->type))
1305   {
1306   case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON:
1307   {
1308     if (fromlen == sizeof (struct sockaddr_in))
1309     {
1310       LOG (GNUNET_ERROR_TYPE_DEBUG,
1311            "Received IPv4 HELLO beacon broadcast with %i bytes from address %s\n",
1312            ret, GNUNET_a2s ((const struct sockaddr *) &addr, fromlen));
1313
1314       struct Mstv4Context *mc;
1315
1316       mc = GNUNET_malloc (sizeof (struct Mstv4Context));
1317       struct sockaddr_in *av4 = (struct sockaddr_in *) &addr;
1318
1319       mc->addr.ipv4_addr = av4->sin_addr.s_addr;
1320       mc->addr.u4_port = av4->sin_port;
1321       if (GNUNET_OK !=
1322           GNUNET_SERVER_mst_receive (plugin->broadcast_ipv4_mst, mc, buf, ret,
1323                                      GNUNET_NO, GNUNET_NO))
1324         GNUNET_free (mc);
1325     }
1326     else if (fromlen == sizeof (struct sockaddr_in6))
1327     {
1328       LOG (GNUNET_ERROR_TYPE_DEBUG,
1329            "Received IPv6 HELLO beacon broadcast with %i bytes from address %s\n",
1330            ret, GNUNET_a2s ((const struct sockaddr *) &addr, fromlen));
1331
1332       struct Mstv6Context *mc;
1333
1334       mc = GNUNET_malloc (sizeof (struct Mstv6Context));
1335       struct sockaddr_in6 *av6 = (struct sockaddr_in6 *) &addr;
1336
1337       mc->addr.ipv6_addr = av6->sin6_addr;
1338       mc->addr.u6_port = av6->sin6_port;
1339
1340       if (GNUNET_OK !=
1341           GNUNET_SERVER_mst_receive (plugin->broadcast_ipv6_mst, mc, buf, ret,
1342                                      GNUNET_NO, GNUNET_NO))
1343         GNUNET_free (mc);
1344     }
1345     return;
1346   }
1347   case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE:
1348     if (ntohs (msg->size) < sizeof (struct UDPMessage))
1349     {
1350       GNUNET_break_op (0);
1351       return;
1352     }
1353     process_udp_message (plugin, (const struct UDPMessage *) msg,
1354                          (const struct sockaddr *) addr, fromlen);
1355     return;
1356   case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK:
1357
1358     if (ntohs (msg->size) <
1359         sizeof (struct UDP_ACK_Message) + sizeof (struct GNUNET_MessageHeader))
1360     {
1361       GNUNET_break_op (0);
1362       return;
1363     }
1364     udp_ack = (const struct UDP_ACK_Message *) msg;
1365     s = find_inbound_session (plugin, &udp_ack->sender, addr, fromlen);
1366     if (s != NULL)
1367     {
1368       flow_delay.rel_value = (uint64_t) ntohl (udp_ack->delay);
1369
1370       LOG (GNUNET_ERROR_TYPE_DEBUG, "We received a sending delay of %llu\n",
1371            flow_delay.rel_value);
1372
1373       s->flow_delay_from_other_peer =
1374           GNUNET_TIME_relative_to_absolute (flow_delay);
1375     }
1376     ack = (const struct GNUNET_MessageHeader *) &udp_ack[1];
1377     if (ntohs (ack->size) !=
1378         ntohs (msg->size) - sizeof (struct UDP_ACK_Message))
1379     {
1380       GNUNET_break_op (0);
1381       return;
1382     }
1383 #if DEBUG_UDP
1384     LOG (GNUNET_ERROR_TYPE_DEBUG,
1385          "UDP processes %u-byte acknowledgement from `%s' at `%s'\n",
1386          (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender),
1387          GNUNET_a2s ((const struct sockaddr *) addr, fromlen));
1388 #endif
1389
1390     peer_session = find_session (plugin, &udp_ack->sender);
1391     if (NULL == peer_session)
1392     {
1393 #if DEBUG_UDP
1394       LOG (GNUNET_ERROR_TYPE_DEBUG,
1395            "Session for ACK not found, dropping ACK!\n");
1396 #endif
1397       return;
1398     }
1399     if (GNUNET_OK != GNUNET_FRAGMENT_process_ack (peer_session->frag, ack))
1400       return;
1401     GNUNET_assert (GNUNET_OK ==
1402                    GNUNET_CONTAINER_multihashmap_remove (plugin->sessions,
1403                                                          &udp_ack->
1404                                                          sender.hashPubKey,
1405                                                          peer_session));
1406     plugin->last_expected_delay =
1407         GNUNET_FRAGMENT_context_destroy (peer_session->frag);
1408     if (peer_session->cont != NULL)
1409       peer_session->cont (peer_session->cont_cls, &udp_ack->sender, GNUNET_OK);
1410     GNUNET_free (peer_session);
1411     return;
1412   case GNUNET_MESSAGE_TYPE_FRAGMENT:
1413     frc.rc = NULL;
1414     frc.addr = (const struct sockaddr *) addr;
1415     frc.addr_len = fromlen;
1416     GNUNET_CONTAINER_heap_iterate (plugin->defrags, &find_receive_context,
1417                                    &frc);
1418     now = GNUNET_TIME_absolute_get ();
1419     rc = frc.rc;
1420     if (rc == NULL)
1421     {
1422       /* need to create a new RC */
1423       rc = GNUNET_malloc (sizeof (struct ReceiveContext) + fromlen);
1424       memcpy (&rc[1], addr, fromlen);
1425       rc->src_addr = (const struct sockaddr *) &rc[1];
1426       rc->addr_len = fromlen;
1427       rc->plugin = plugin;
1428       rc->defrag =
1429           GNUNET_DEFRAGMENT_context_create (plugin->env->stats, UDP_MTU,
1430                                             UDP_MAX_MESSAGES_IN_DEFRAG, rc,
1431                                             &fragment_msg_proc, &ack_proc);
1432       rc->hnode =
1433           GNUNET_CONTAINER_heap_insert (plugin->defrags, rc,
1434                                         (GNUNET_CONTAINER_HeapCostType)
1435                                         now.abs_value);
1436     }
1437 #if DEBUG_UDP
1438     LOG (GNUNET_ERROR_TYPE_DEBUG, "UDP processes %u-byte fragment from `%s'\n",
1439          (unsigned int) ntohs (msg->size),
1440          GNUNET_a2s ((const struct sockaddr *) addr, fromlen));
1441 #endif
1442
1443     if (GNUNET_OK == GNUNET_DEFRAGMENT_process_fragment (rc->defrag, msg))
1444     {
1445       /* keep this 'rc' from expiring */
1446       GNUNET_CONTAINER_heap_update_cost (plugin->defrags, rc->hnode,
1447                                          (GNUNET_CONTAINER_HeapCostType)
1448                                          now.abs_value);
1449     }
1450     if (GNUNET_CONTAINER_heap_get_size (plugin->defrags) >
1451         UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG)
1452     {
1453       /* remove 'rc' that was inactive the longest */
1454       rc = GNUNET_CONTAINER_heap_remove_root (plugin->defrags);
1455       GNUNET_assert (NULL != rc);
1456       GNUNET_DEFRAGMENT_context_destroy (rc->defrag);
1457       GNUNET_free (rc);
1458     }
1459     return;
1460   default:
1461     GNUNET_break_op (0);
1462     return;
1463   }
1464 }
1465
1466
1467 /**
1468  * We have been notified that our writeset has something to read.  We don't
1469  * know which socket needs to be read, so we have to check each one
1470  * Then reschedule this function to be called again once more is available.
1471  *
1472  * @param cls the plugin handle
1473  * @param tc the scheduling context (for rescheduling this function again)
1474  */
1475 static void
1476 udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1477 {
1478   struct Plugin *plugin = cls;
1479
1480   plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
1481   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1482     return;
1483   if ((NULL != plugin->sockv4) &&
1484       (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4)))
1485     udp_read (plugin, plugin->sockv4);
1486   if ((NULL != plugin->sockv6) &&
1487       (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)))
1488     udp_read (plugin, plugin->sockv6);
1489   plugin->select_task =
1490       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1491                                    GNUNET_SCHEDULER_NO_TASK,
1492                                    GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1493                                    NULL, &udp_plugin_select, plugin);
1494
1495 }
1496
1497
1498 void
1499 broadcast_ipv4_mst_cb (void *cls, void *client,
1500                        const struct GNUNET_MessageHeader *message)
1501 {
1502   struct Plugin *plugin = cls;
1503   struct Mstv4Context *mc = client;
1504   const struct GNUNET_MessageHeader *hello;
1505   struct UDP_Beacon_Message *msg;
1506
1507   msg = (struct UDP_Beacon_Message *) message;
1508
1509   if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
1510       ntohs (msg->header.type))
1511     return;
1512
1513   LOG (GNUNET_ERROR_TYPE_DEBUG,
1514        "Received beacon with %u bytes from peer `%s' via address `%s'\n",
1515        ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
1516        udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
1517
1518   struct GNUNET_ATS_Information ats;
1519
1520   ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
1521   ats.value = htonl (1);
1522
1523   hello = (struct GNUNET_MessageHeader *) &msg[1];
1524   plugin->env->receive (plugin->env->cls, &msg->sender, hello, &ats, 1, NULL,
1525                         (const char *) &mc->addr, sizeof (mc->addr));
1526
1527   GNUNET_STATISTICS_update (plugin->env->stats,
1528                             _
1529                             ("# IPv4 broadcast HELLO beacons received via udp"),
1530                             1, GNUNET_NO);
1531   GNUNET_free (mc);
1532 }
1533
1534
1535 void
1536 broadcast_ipv6_mst_cb (void *cls, void *client,
1537                        const struct GNUNET_MessageHeader *message)
1538 {
1539
1540   struct Plugin *plugin = cls;
1541   struct Mstv6Context *mc = client;
1542   const struct GNUNET_MessageHeader *hello;
1543   struct UDP_Beacon_Message *msg;
1544
1545   msg = (struct UDP_Beacon_Message *) message;
1546
1547   if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
1548       ntohs (msg->header.type))
1549     return;
1550
1551   LOG (GNUNET_ERROR_TYPE_DEBUG,
1552        "Received beacon with %u bytes from peer `%s' via address `%s'\n",
1553        ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
1554        udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
1555
1556   struct GNUNET_ATS_Information ats;
1557
1558   ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
1559   ats.value = htonl (1);
1560
1561   hello = (struct GNUNET_MessageHeader *) &msg[1];
1562   plugin->env->receive (plugin->env->cls, &msg->sender, hello, &ats, 1, NULL,
1563                         (const char *) &mc->addr, sizeof (mc->addr));
1564
1565   GNUNET_STATISTICS_update (plugin->env->stats,
1566                             _
1567                             ("# IPv6 multicast HELLO beacons received via udp"),
1568                             1, GNUNET_NO);
1569   GNUNET_free (mc);
1570 }
1571
1572
1573 static void
1574 udp_ipv4_broadcast_send (void *cls,
1575                          const struct GNUNET_SCHEDULER_TaskContext *tc)
1576 {
1577   struct Plugin *plugin = cls;
1578   int sent;
1579   uint16_t msg_size;
1580   uint16_t hello_size;
1581   char buf[65536];
1582
1583   const struct GNUNET_MessageHeader *hello;
1584   struct UDP_Beacon_Message *msg;
1585   struct BroadcastAddress *baddr;
1586
1587   plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
1588
1589   hello = plugin->env->get_our_hello ();
1590   hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
1591   msg_size = hello_size + sizeof (struct UDP_Beacon_Message);
1592
1593   if (hello_size < (sizeof (struct GNUNET_MessageHeader)) ||
1594       (msg_size > (UDP_MTU)))
1595     return;
1596
1597   msg = (struct UDP_Beacon_Message *) buf;
1598   msg->sender = *(plugin->env->my_identity);
1599   msg->header.size = ntohs (msg_size);
1600   msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON);
1601   memcpy (&msg[1], hello, hello_size);
1602   sent = 0;
1603
1604   baddr = plugin->ipv4_broadcast_head;
1605   /* just IPv4 */
1606   while ((baddr != NULL) && (baddr->addrlen == sizeof (struct sockaddr_in)))
1607   {
1608     struct sockaddr_in *addr = (struct sockaddr_in *) baddr->addr;
1609
1610     addr->sin_port = htons (plugin->port);
1611
1612     sent =
1613         GNUNET_NETWORK_socket_sendto (plugin->sockv4, msg, msg_size,
1614                                       (const struct sockaddr *) addr,
1615                                       baddr->addrlen);
1616     if (sent == GNUNET_SYSERR)
1617       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
1618     else
1619       LOG (GNUNET_ERROR_TYPE_DEBUG,
1620            "Sent HELLO beacon broadcast with  %i bytes to address %s\n", sent,
1621            GNUNET_a2s (baddr->addr, baddr->addrlen));
1622     baddr = baddr->next;
1623   }
1624
1625   plugin->send_ipv4_broadcast_task =
1626       GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
1627                                     &udp_ipv4_broadcast_send, plugin);
1628 }
1629
1630 static void
1631 udp_ipv6_broadcast_send (void *cls,
1632                          const struct GNUNET_SCHEDULER_TaskContext *tc)
1633 {
1634   struct Plugin *plugin = cls;
1635   int sent;
1636   uint16_t msg_size;
1637   uint16_t hello_size;
1638   char buf[65536];
1639
1640   const struct GNUNET_MessageHeader *hello;
1641   struct UDP_Beacon_Message *msg;
1642
1643   plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
1644
1645   hello = plugin->env->get_our_hello ();
1646   hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
1647   msg_size = hello_size + sizeof (struct UDP_Beacon_Message);
1648
1649   if (hello_size < (sizeof (struct GNUNET_MessageHeader)) ||
1650       (msg_size > (UDP_MTU)))
1651     return;
1652
1653   msg = (struct UDP_Beacon_Message *) buf;
1654   msg->sender = *(plugin->env->my_identity);
1655   msg->header.size = ntohs (msg_size);
1656   msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON);
1657   memcpy (&msg[1], hello, hello_size);
1658   sent = 0;
1659
1660   sent =
1661       GNUNET_NETWORK_socket_sendto (plugin->sockv6, msg, msg_size,
1662                                     (const struct sockaddr *)
1663                                     &plugin->ipv6_multicast_address,
1664                                     sizeof (struct sockaddr_in6));
1665   if (sent == GNUNET_SYSERR)
1666     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
1667   else
1668     LOG (GNUNET_ERROR_TYPE_DEBUG,
1669          "Sending IPv6 HELLO beacon broadcast with  %i bytes to address %s\n",
1670          sent,
1671          GNUNET_a2s ((const struct sockaddr *) &plugin->ipv6_multicast_address,
1672                      sizeof (struct sockaddr_in6)));
1673
1674
1675
1676   plugin->send_ipv6_broadcast_task =
1677       GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
1678                                     &udp_ipv6_broadcast_send, plugin);
1679 }
1680
1681 /**
1682  * Check if the given port is plausible (must be either our listen
1683  * port or our advertised port).  If it is neither, we return
1684  * GNUNET_SYSERR.
1685  *
1686  * @param plugin global variables
1687  * @param in_port port number to check
1688  * @return GNUNET_OK if port is either open_port or adv_port
1689  */
1690 static int
1691 check_port (struct Plugin *plugin, uint16_t in_port)
1692 {
1693   if ((in_port == plugin->port) || (in_port == plugin->aport))
1694     return GNUNET_OK;
1695   return GNUNET_SYSERR;
1696 }
1697
1698
1699 /**
1700  * Function that will be called to check if a binary address for this
1701  * plugin is well-formed and corresponds to an address for THIS peer
1702  * (as per our configuration).  Naturally, if absolutely necessary,
1703  * plugins can be a bit conservative in their answer, but in general
1704  * plugins should make sure that the address does not redirect
1705  * traffic to a 3rd party that might try to man-in-the-middle our
1706  * traffic.
1707  *
1708  * @param cls closure, should be our handle to the Plugin
1709  * @param addr pointer to the address
1710  * @param addrlen length of addr
1711  * @return GNUNET_OK if this is a plausible address for this peer
1712  *         and transport, GNUNET_SYSERR if not
1713  *
1714  */
1715 static int
1716 udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
1717 {
1718   struct Plugin *plugin = cls;
1719   struct IPv4UdpAddress *v4;
1720   struct IPv6UdpAddress *v6;
1721
1722   if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
1723       (addrlen != sizeof (struct IPv6UdpAddress)))
1724   {
1725     GNUNET_break_op (0);
1726     return GNUNET_SYSERR;
1727   }
1728   if (addrlen == sizeof (struct IPv4UdpAddress))
1729   {
1730     v4 = (struct IPv4UdpAddress *) addr;
1731     if (GNUNET_OK != check_port (plugin, ntohs (v4->u4_port)))
1732       return GNUNET_SYSERR;
1733     if (GNUNET_OK !=
1734         GNUNET_NAT_test_address (plugin->nat, &v4->ipv4_addr,
1735                                  sizeof (struct in_addr)))
1736       return GNUNET_SYSERR;
1737   }
1738   else
1739   {
1740     v6 = (struct IPv6UdpAddress *) addr;
1741     if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
1742     {
1743       GNUNET_break_op (0);
1744       return GNUNET_SYSERR;
1745     }
1746     if (GNUNET_OK != check_port (plugin, ntohs (v6->u6_port)))
1747       return GNUNET_SYSERR;
1748     if (GNUNET_OK !=
1749         GNUNET_NAT_test_address (plugin->nat, &v6->ipv6_addr,
1750                                  sizeof (struct in6_addr)))
1751       return GNUNET_SYSERR;
1752   }
1753   return GNUNET_OK;
1754 }
1755
1756
1757 /**
1758  * Function called for a quick conversion of the binary address to
1759  * a numeric address.  Note that the caller must not free the
1760  * address and that the next call to this function is allowed
1761  * to override the address again.
1762  *
1763  * @param cls closure
1764  * @param addr binary address
1765  * @param addrlen length of the address
1766  * @return string representing the same address
1767  */
1768 static const char *
1769 udp_address_to_string (void *cls, const void *addr, size_t addrlen)
1770 {
1771   static char rbuf[INET6_ADDRSTRLEN + 10];
1772   char buf[INET6_ADDRSTRLEN];
1773   const void *sb;
1774   struct in_addr a4;
1775   struct in6_addr a6;
1776   const struct IPv4UdpAddress *t4;
1777   const struct IPv6UdpAddress *t6;
1778   int af;
1779   uint16_t port;
1780
1781   if (addrlen == sizeof (struct IPv6UdpAddress))
1782   {
1783     t6 = addr;
1784     af = AF_INET6;
1785     port = ntohs (t6->u6_port);
1786     memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
1787     sb = &a6;
1788   }
1789   else if (addrlen == sizeof (struct IPv4UdpAddress))
1790   {
1791     t4 = addr;
1792     af = AF_INET;
1793     port = ntohs (t4->u4_port);
1794     memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
1795     sb = &a4;
1796   }
1797   else
1798   {
1799     GNUNET_break_op (0);
1800     return NULL;
1801   }
1802   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
1803   GNUNET_snprintf (rbuf, sizeof (rbuf), (af == AF_INET6) ? "[%s]:%u" : "%s:%u",
1804                    buf, port);
1805   return rbuf;
1806 }
1807
1808
1809 /**
1810  * Closure for 'append_port'.
1811  */
1812 struct PrettyPrinterContext
1813 {
1814   /**
1815    * Function to call with the result.
1816    */
1817   GNUNET_TRANSPORT_AddressStringCallback asc;
1818
1819   /**
1820    * Clsoure for 'asc'.
1821    */
1822   void *asc_cls;
1823
1824   /**
1825    * Port to add after the IP address.
1826    */
1827   uint16_t port;
1828 };
1829
1830
1831 /**
1832  * Append our port and forward the result.
1833  *
1834  * @param cls a 'struct PrettyPrinterContext'
1835  * @param hostname result from DNS resolver
1836  */
1837 static void
1838 append_port (void *cls, const char *hostname)
1839 {
1840   struct PrettyPrinterContext *ppc = cls;
1841   char *ret;
1842
1843   if (hostname == NULL)
1844   {
1845     ppc->asc (ppc->asc_cls, NULL);
1846     GNUNET_free (ppc);
1847     return;
1848   }
1849   GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
1850   ppc->asc (ppc->asc_cls, ret);
1851   GNUNET_free (ret);
1852 }
1853
1854
1855 /**
1856  * Convert the transports address to a nice, human-readable
1857  * format.
1858  *
1859  * @param cls closure
1860  * @param type name of the transport that generated the address
1861  * @param addr one of the addresses of the host, NULL for the last address
1862  *        the specific address format depends on the transport
1863  * @param addrlen length of the address
1864  * @param numeric should (IP) addresses be displayed in numeric form?
1865  * @param timeout after how long should we give up?
1866  * @param asc function to call on each string
1867  * @param asc_cls closure for asc
1868  */
1869 static void
1870 udp_plugin_address_pretty_printer (void *cls, const char *type,
1871                                    const void *addr, size_t addrlen,
1872                                    int numeric,
1873                                    struct GNUNET_TIME_Relative timeout,
1874                                    GNUNET_TRANSPORT_AddressStringCallback asc,
1875                                    void *asc_cls)
1876 {
1877   struct PrettyPrinterContext *ppc;
1878   const void *sb;
1879   size_t sbs;
1880   struct sockaddr_in a4;
1881   struct sockaddr_in6 a6;
1882   const struct IPv4UdpAddress *u4;
1883   const struct IPv6UdpAddress *u6;
1884   uint16_t port;
1885
1886   if (addrlen == sizeof (struct IPv6UdpAddress))
1887   {
1888     u6 = addr;
1889     memset (&a6, 0, sizeof (a6));
1890     a6.sin6_family = AF_INET6;
1891 #if HAVE_SOCKADDR_IN_SIN_LEN
1892     a6.sin6_len = sizeof (a6);
1893 #endif
1894     a6.sin6_port = u6->u6_port;
1895     memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof (struct in6_addr));
1896     port = ntohs (u6->u6_port);
1897     sb = &a6;
1898     sbs = sizeof (a6);
1899   }
1900   else if (addrlen == sizeof (struct IPv4UdpAddress))
1901   {
1902     u4 = addr;
1903     memset (&a4, 0, sizeof (a4));
1904     a4.sin_family = AF_INET;
1905 #if HAVE_SOCKADDR_IN_SIN_LEN
1906     a4.sin_len = sizeof (a4);
1907 #endif
1908     a4.sin_port = u4->u4_port;
1909     a4.sin_addr.s_addr = u4->ipv4_addr;
1910     port = ntohs (u4->u4_port);
1911     sb = &a4;
1912     sbs = sizeof (a4);
1913   }
1914   else
1915   {
1916     /* invalid address */
1917     GNUNET_break_op (0);
1918     asc (asc_cls, NULL);
1919     return;
1920   }
1921   ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
1922   ppc->asc = asc;
1923   ppc->asc_cls = asc_cls;
1924   ppc->port = port;
1925   GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
1926 }
1927
1928
1929 /**
1930  * Our external IP address/port mapping has changed.
1931  *
1932  * @param cls closure, the 'struct LocalAddrList'
1933  * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean
1934  *     the previous (now invalid) one
1935  * @param addr either the previous or the new public IP address
1936  * @param addrlen actual lenght of the address
1937  */
1938 static void
1939 udp_nat_port_map_callback (void *cls, int add_remove,
1940                            const struct sockaddr *addr, socklen_t addrlen)
1941 {
1942   struct Plugin *plugin = cls;
1943   struct IPv4UdpAddress u4;
1944   struct IPv6UdpAddress u6;
1945   void *arg;
1946   size_t args;
1947
1948   /* convert 'addr' to our internal format */
1949   switch (addr->sa_family)
1950   {
1951   case AF_INET:
1952     GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
1953     u4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
1954     u4.u4_port = ((struct sockaddr_in *) addr)->sin_port;
1955     arg = &u4;
1956     args = sizeof (u4);
1957     break;
1958   case AF_INET6:
1959     GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
1960     memcpy (&u6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr,
1961             sizeof (struct in6_addr));
1962     u6.u6_port = ((struct sockaddr_in6 *) addr)->sin6_port;
1963     arg = &u6;
1964     args = sizeof (u6);
1965     break;
1966   default:
1967     GNUNET_break (0);
1968     return;
1969   }
1970   /* modify our published address list */
1971   plugin->env->notify_address (plugin->env->cls, add_remove, arg, args);
1972 }
1973
1974
1975 static int
1976 iface_proc (void *cls, const char *name, int isDefault,
1977             const struct sockaddr *addr, const struct sockaddr *broadcast_addr,
1978             const struct sockaddr *netmask, socklen_t addrlen)
1979 {
1980   struct Plugin *plugin = cls;
1981
1982   if (addr != NULL)
1983   {
1984     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address %s for interface %s %p\n ",
1985                 GNUNET_a2s (addr, addrlen), name, addr);
1986     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1987                 "broadcast address %s for interface %s %p\n ",
1988                 GNUNET_a2s (broadcast_addr, addrlen), name, broadcast_addr);
1989     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ",
1990                 GNUNET_a2s (netmask, addrlen), name, netmask);
1991
1992
1993     /* Collecting broadcast addresses */
1994     if (broadcast_addr != NULL)
1995     {
1996       struct BroadcastAddress *ba =
1997           GNUNET_malloc (sizeof (struct BroadcastAddress));
1998       ba->addr = GNUNET_malloc (addrlen);
1999       memcpy (ba->addr, broadcast_addr, addrlen);
2000       ba->addrlen = addrlen;
2001       GNUNET_CONTAINER_DLL_insert (plugin->ipv4_broadcast_head,
2002                                    plugin->ipv4_broadcast_tail, ba);
2003     }
2004   }
2005   return GNUNET_OK;
2006 }
2007
2008
2009 /**
2010  * The exported method. Makes the core api available via a global and
2011  * returns the udp transport API.
2012  *
2013  * @param cls our 'struct GNUNET_TRANSPORT_PluginEnvironment'
2014  * @return our 'struct GNUNET_TRANSPORT_PluginFunctions'
2015  */
2016 void *
2017 libgnunet_plugin_transport_udp_init (void *cls)
2018 {
2019   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
2020   unsigned long long port;
2021   unsigned long long aport;
2022   struct GNUNET_TRANSPORT_PluginFunctions *api;
2023   struct Plugin *plugin;
2024   int sockets_created;
2025   int broadcast;
2026   struct GNUNET_TIME_Relative interval;
2027   struct sockaddr_in serverAddrv4;
2028   struct sockaddr_in6 serverAddrv6;
2029   struct sockaddr *serverAddr;
2030   struct sockaddr *addrs[2];
2031   socklen_t addrlens[2];
2032   socklen_t addrlen;
2033   unsigned int tries;
2034   unsigned long long udp_max_bps;
2035
2036   if (GNUNET_OK !=
2037       GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", "PORT",
2038                                              &port))
2039     port = 2086;
2040
2041   broadcast =
2042       GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "transport-udp",
2043                                             "BROADCAST");
2044   if (broadcast == GNUNET_SYSERR)
2045     broadcast = GNUNET_NO;
2046
2047   if (GNUNET_SYSERR ==
2048       GNUNET_CONFIGURATION_get_value_time (env->cfg, "transport-udp",
2049                                            "BROADCAST_INTERVAL", &interval))
2050     interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10);
2051
2052   if (GNUNET_OK !=
2053       GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp",
2054                                              "MAX_BPS", &udp_max_bps))
2055     udp_max_bps = 1024 * 1024 * 50;     /* 50 MB/s == infinity for practical purposes */
2056   if (GNUNET_OK !=
2057       GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp",
2058                                              "ADVERTISED_PORT", &aport))
2059     aport = port;
2060   if (port > 65535)
2061   {
2062     LOG (GNUNET_ERROR_TYPE_WARNING,
2063          _("Given `%s' option is out of range: %llu > %u\n"), "PORT", port,
2064          65535);
2065     return NULL;
2066   }
2067   memset (&serverAddrv6, 0, sizeof (serverAddrv6));
2068   memset (&serverAddrv4, 0, sizeof (serverAddrv4));
2069
2070   plugin = GNUNET_malloc (sizeof (struct Plugin));
2071   GNUNET_BANDWIDTH_tracker_init (&plugin->tracker,
2072                                  GNUNET_BANDWIDTH_value_init ((uint32_t)
2073                                                               udp_max_bps), 30);
2074   plugin->last_expected_delay = GNUNET_TIME_UNIT_SECONDS;
2075   plugin->port = port;
2076   plugin->aport = aport;
2077   plugin->env = env;
2078   plugin->broadcast_interval = interval;
2079   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2080   api->cls = plugin;
2081
2082   api->send = &udp_plugin_send;
2083   api->disconnect = &udp_disconnect;
2084   api->address_pretty_printer = &udp_plugin_address_pretty_printer;
2085   api->address_to_string = &udp_address_to_string;
2086   api->check_address = &udp_plugin_check_address;
2087
2088   if (GNUNET_YES ==
2089       GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp",
2090                                              "BINDTO", &plugin->bind4_address))
2091   {
2092     LOG (GNUNET_ERROR_TYPE_DEBUG,
2093          "Binding udp plugin to specific address: `%s'\n",
2094          plugin->bind4_address);
2095     if (1 != inet_pton (AF_INET, plugin->bind4_address, &serverAddrv4.sin_addr))
2096     {
2097       GNUNET_free (plugin->bind4_address);
2098       GNUNET_free (plugin);
2099       GNUNET_free (api);
2100       return NULL;
2101     }
2102   }
2103
2104   if (GNUNET_YES ==
2105       GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp",
2106                                              "BINDTO6", &plugin->bind6_address))
2107   {
2108     LOG (GNUNET_ERROR_TYPE_DEBUG,
2109          "Binding udp plugin to specific address: `%s'\n",
2110          plugin->bind6_address);
2111     if (1 !=
2112         inet_pton (AF_INET6, plugin->bind6_address, &serverAddrv6.sin6_addr))
2113     {
2114       LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid IPv6 address: `%s'\n"),
2115            plugin->bind6_address);
2116       GNUNET_free_non_null (plugin->bind4_address);
2117       GNUNET_free (plugin->bind6_address);
2118       GNUNET_free (plugin);
2119       GNUNET_free (api);
2120       return NULL;
2121     }
2122   }
2123
2124   plugin->defrags =
2125       GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2126   plugin->sessions =
2127       GNUNET_CONTAINER_multihashmap_create (UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG
2128                                             * 2);
2129   plugin->inbound_sessions =
2130       GNUNET_CONTAINER_multihashmap_create (UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG
2131                                             * 2);
2132   sockets_created = 0;
2133   if ((GNUNET_YES !=
2134        GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "nat",
2135                                              "DISABLEV6")))
2136   {
2137     plugin->sockv6 = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0);
2138     if (NULL == plugin->sockv6)
2139     {
2140       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
2141     }
2142     else
2143     {
2144 #if HAVE_SOCKADDR_IN_SIN_LEN
2145       serverAddrv6.sin6_len = sizeof (serverAddrv6);
2146 #endif
2147       serverAddrv6.sin6_family = AF_INET6;
2148       serverAddrv6.sin6_addr = in6addr_any;
2149       serverAddrv6.sin6_port = htons (plugin->port);
2150       addrlen = sizeof (serverAddrv6);
2151       serverAddr = (struct sockaddr *) &serverAddrv6;
2152 #if DEBUG_UDP
2153       LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv6 port %d\n",
2154            ntohs (serverAddrv6.sin6_port));
2155 #endif
2156       tries = 0;
2157       while (GNUNET_NETWORK_socket_bind (plugin->sockv6, serverAddr, addrlen) !=
2158              GNUNET_OK)
2159       {
2160         serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);        /* Find a good, non-root port */
2161 #if DEBUG_UDP
2162         LOG (GNUNET_ERROR_TYPE_DEBUG,
2163              "IPv6 Binding failed, trying new port %d\n",
2164              ntohs (serverAddrv6.sin6_port));
2165 #endif
2166         tries++;
2167         if (tries > 10)
2168         {
2169           GNUNET_NETWORK_socket_close (plugin->sockv6);
2170           plugin->sockv6 = NULL;
2171           break;
2172         }
2173       }
2174       if (plugin->sockv6 != NULL)
2175       {
2176         addrs[sockets_created] = (struct sockaddr *) &serverAddrv6;
2177         addrlens[sockets_created] = sizeof (serverAddrv6);
2178         sockets_created++;
2179       }
2180     }
2181   }
2182
2183   plugin->mst =
2184       GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, plugin);
2185   plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
2186   if (NULL == plugin->sockv4)
2187   {
2188     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
2189   }
2190   else
2191   {
2192 #if HAVE_SOCKADDR_IN_SIN_LEN
2193     serverAddrv4.sin_len = sizeof (serverAddrv4);
2194 #endif
2195     serverAddrv4.sin_family = AF_INET;
2196     serverAddrv4.sin_addr.s_addr = INADDR_ANY;
2197     serverAddrv4.sin_port = htons (plugin->port);
2198     addrlen = sizeof (serverAddrv4);
2199     serverAddr = (struct sockaddr *) &serverAddrv4;
2200 #if DEBUG_UDP
2201     LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv4 port %d\n",
2202          ntohs (serverAddrv4.sin_port));
2203 #endif
2204     tries = 0;
2205     while (GNUNET_NETWORK_socket_bind (plugin->sockv4, serverAddr, addrlen) !=
2206            GNUNET_OK)
2207     {
2208       serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);   /* Find a good, non-root port */
2209 #if DEBUG_UDP
2210       LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv4 Binding failed, trying new port %d\n",
2211            ntohs (serverAddrv4.sin_port));
2212 #endif
2213       tries++;
2214       if (tries > 10)
2215       {
2216         GNUNET_NETWORK_socket_close (plugin->sockv4);
2217         plugin->sockv4 = NULL;
2218         break;
2219       }
2220     }
2221     if (plugin->sockv4 != NULL)
2222     {
2223       addrs[sockets_created] = (struct sockaddr *) &serverAddrv4;
2224       addrlens[sockets_created] = sizeof (serverAddrv4);
2225       sockets_created++;
2226     }
2227   }
2228
2229   plugin->rs = GNUNET_NETWORK_fdset_create ();
2230   GNUNET_NETWORK_fdset_zero (plugin->rs);
2231   if (NULL != plugin->sockv4)
2232     GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv4);
2233   if (NULL != plugin->sockv6)
2234     GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv6);
2235
2236   plugin->select_task =
2237       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
2238                                    GNUNET_SCHEDULER_NO_TASK,
2239                                    GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
2240                                    NULL, &udp_plugin_select, plugin);
2241
2242
2243
2244   if (broadcast)
2245   {
2246     /* create IPv4 broadcast socket */
2247     plugin->broadcast_ipv4 = GNUNET_NO;
2248     if (plugin->sockv4 != NULL)
2249     {
2250       int yes = 1;
2251
2252       if (GNUNET_NETWORK_socket_setsockopt
2253           (plugin->sockv4, SOL_SOCKET, SO_BROADCAST, &yes,
2254            sizeof (int)) != GNUNET_OK)
2255       {
2256         LOG (GNUNET_ERROR_TYPE_WARNING,
2257              _
2258              ("Failed to set IPv4 broadcast option for broadcast socket on port %d\n"),
2259              ntohs (serverAddrv4.sin_port));
2260       }
2261       else
2262       {
2263         GNUNET_OS_network_interfaces_list (iface_proc, plugin);
2264         plugin->send_ipv4_broadcast_task =
2265             GNUNET_SCHEDULER_add_now (&udp_ipv4_broadcast_send, plugin);
2266
2267         plugin->broadcast_ipv4_mst =
2268             GNUNET_SERVER_mst_create (broadcast_ipv4_mst_cb, plugin);
2269
2270         LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv4 Broadcasting running\n");
2271         plugin->broadcast_ipv4 = GNUNET_YES;
2272       }
2273     }
2274
2275     plugin->broadcast_ipv6 = GNUNET_NO;
2276     if (plugin->sockv6 != NULL)
2277     {
2278       memset (&plugin->ipv6_multicast_address, 0, sizeof (struct sockaddr_in6));
2279       GNUNET_assert (1 ==
2280                      inet_pton (AF_INET6, "FF05::13B",
2281                                 &plugin->ipv6_multicast_address.sin6_addr));
2282
2283       plugin->ipv6_multicast_address.sin6_family = AF_INET6;
2284       plugin->ipv6_multicast_address.sin6_port = htons (plugin->port);
2285
2286       plugin->broadcast_ipv6_mst =
2287           GNUNET_SERVER_mst_create (broadcast_ipv6_mst_cb, plugin);
2288
2289       /* Create IPv6 multicast request */
2290       struct ipv6_mreq multicastRequest;
2291
2292       multicastRequest.ipv6mr_multiaddr =
2293           plugin->ipv6_multicast_address.sin6_addr;
2294       /* TODO: 0 selects the "best" interface, tweak to use all interfaces
2295        *
2296        * http://tools.ietf.org/html/rfc2553#section-5.2:
2297        *
2298        * IPV6_JOIN_GROUP
2299        *
2300        * Join a multicast group on a specified local interface.  If the
2301        * interface index is specified as 0, the kernel chooses the local
2302        * interface.  For example, some kernels look up the multicast
2303        * group in the normal IPv6 routing table and using the resulting
2304        * interface.
2305        * */
2306       multicastRequest.ipv6mr_interface = 0;
2307
2308       /* Join the multicast group */
2309       if (GNUNET_NETWORK_socket_setsockopt
2310           (plugin->sockv6, IPPROTO_IPV6, IPV6_JOIN_GROUP,
2311            (char *) &multicastRequest, sizeof (multicastRequest)) == GNUNET_OK)
2312       {
2313         LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 broadcasting running\n");
2314
2315         plugin->send_ipv6_broadcast_task =
2316             GNUNET_SCHEDULER_add_now (&udp_ipv6_broadcast_send, plugin);
2317         plugin->broadcast_ipv6 = GNUNET_YES;
2318       }
2319       else
2320         LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 broadcasting not running\n");
2321     }
2322   }
2323
2324   if (sockets_created == 0)
2325     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n"));
2326   plugin->nat =
2327       GNUNET_NAT_register (env->cfg, GNUNET_NO, port, sockets_created,
2328                            (const struct sockaddr **) addrs, addrlens,
2329                            &udp_nat_port_map_callback, NULL, plugin);
2330   return api;
2331 }
2332
2333 /**
2334  * Shutdown the plugin.
2335  *
2336  * @param cls our 'struct GNUNET_TRANSPORT_PluginFunctions'
2337  * @return NULL
2338  */
2339 void *
2340 libgnunet_plugin_transport_udp_done (void *cls)
2341 {
2342   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2343   struct Plugin *plugin = api->cls;
2344   struct ReceiveContext *rc;
2345
2346   /* FIXME: clean up heap and hashmap */
2347   GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, &destroy_session,
2348                                          NULL);
2349   GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions);
2350   plugin->sessions = NULL;
2351   GNUNET_CONTAINER_multihashmap_iterate (plugin->inbound_sessions,
2352                                          &destroy_inbound_session, NULL);
2353   GNUNET_CONTAINER_multihashmap_destroy (plugin->inbound_sessions);
2354   plugin->inbound_sessions = NULL;
2355   while (NULL != (rc = GNUNET_CONTAINER_heap_remove_root (plugin->defrags)))
2356   {
2357     GNUNET_DEFRAGMENT_context_destroy (rc->defrag);
2358     GNUNET_free (rc);
2359   }
2360   GNUNET_CONTAINER_heap_destroy (plugin->defrags);
2361
2362   if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
2363   {
2364     GNUNET_SCHEDULER_cancel (plugin->select_task);
2365     plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
2366   }
2367
2368   if (plugin->broadcast_ipv4)
2369   {
2370     if (plugin->send_ipv4_broadcast_task != GNUNET_SCHEDULER_NO_TASK)
2371     {
2372       GNUNET_SCHEDULER_cancel (plugin->send_ipv4_broadcast_task);
2373       plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
2374     }
2375
2376     if (plugin->broadcast_ipv4_mst != NULL)
2377       GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv4_mst);
2378
2379     while (plugin->ipv4_broadcast_head != NULL)
2380     {
2381       struct BroadcastAddress *p = plugin->ipv4_broadcast_head;
2382
2383       GNUNET_CONTAINER_DLL_remove (plugin->ipv4_broadcast_head,
2384                                    plugin->ipv4_broadcast_tail, p);
2385       GNUNET_free (p->addr);
2386       GNUNET_free (p);
2387     }
2388   }
2389
2390   if (plugin->broadcast_ipv6)
2391   {
2392     /* Create IPv6 multicast request */
2393     struct ipv6_mreq multicastRequest;
2394
2395     multicastRequest.ipv6mr_multiaddr =
2396         plugin->ipv6_multicast_address.sin6_addr;
2397     multicastRequest.ipv6mr_interface = 0;
2398
2399     /* Join the multicast address */
2400     if (GNUNET_NETWORK_socket_setsockopt
2401         (plugin->sockv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
2402          (char *) &multicastRequest, sizeof (multicastRequest)) == 0)
2403     {
2404       LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 Broadcasting stopped\n");
2405     }
2406     else
2407       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, setsockopt);
2408
2409     if (plugin->send_ipv6_broadcast_task != GNUNET_SCHEDULER_NO_TASK)
2410     {
2411       GNUNET_SCHEDULER_cancel (plugin->send_ipv6_broadcast_task);
2412       plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
2413     }
2414     if (plugin->broadcast_ipv6_mst != NULL)
2415       GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv6_mst);
2416   }
2417
2418
2419   if (plugin->sockv4 != NULL)
2420   {
2421     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4));
2422     plugin->sockv4 = NULL;
2423   }
2424   if (plugin->sockv6 != NULL)
2425   {
2426     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv6));
2427     plugin->sockv6 = NULL;
2428   }
2429
2430   GNUNET_SERVER_mst_destroy (plugin->mst);
2431   GNUNET_NETWORK_fdset_destroy (plugin->rs);
2432
2433   GNUNET_NAT_unregister (plugin->nat);
2434   plugin->nat = NULL;
2435   GNUNET_free (plugin);
2436   GNUNET_free (api);
2437   return NULL;
2438 }
2439
2440 /* end of plugin_transport_udp.c */