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