d15bbe349c4b6ed136e599525553cbdf7e6bd9a2
[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  * @return NULL if we have no session
465  */
466 static struct Session *
467 find_inbound_session (struct Plugin *plugin,
468                       const struct GNUNET_PeerIdentity *peer, const void *addr,
469                       size_t addrlen)
470 {
471   struct PeerSessionIteratorContext psc;
472
473   psc.result = NULL;
474   psc.addrlen = addrlen;
475   psc.addr = addr;
476
477   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->inbound_sessions,
478                                               &peer->hashPubKey,
479                                               &inbound_session_iterator, &psc);
480   return psc.result;
481 }
482
483
484 static int
485 inbound_session_by_addr_iterator (void *cls, const GNUNET_HashCode * key,
486                                   void *value)
487 {
488   struct PeerSessionIteratorContext *psc = cls;
489   struct Session *s = value;
490
491   if (s->addrlen == psc->addrlen)
492   {
493     if (0 == memcmp (&s[1], psc->addr, s->addrlen))
494       psc->result = s;
495   }
496   if (psc->result != NULL)
497     return GNUNET_NO;
498   else
499     return GNUNET_YES;
500 };
501
502 /**
503  * Lookup the session for the given peer just by address.
504  *
505  * @param plugin the plugin
506  * @param addr address
507  * @param addrlen address length
508  * @return NULL if we have no session
509  */
510 static struct Session *
511 find_inbound_session_by_addr (struct Plugin *plugin, const void *addr,
512                               size_t addrlen)
513 {
514   struct PeerSessionIteratorContext psc;
515
516   psc.result = NULL;
517   psc.addrlen = addrlen;
518   psc.addr = addr;
519
520   GNUNET_CONTAINER_multihashmap_iterate (plugin->inbound_sessions,
521                                          &inbound_session_by_addr_iterator,
522                                          &psc);
523   return psc.result;
524 }
525
526
527 /**
528  * Destroy a session, plugin is being unloaded.
529  *
530  * @param cls unused
531  * @param key hash of public key of target peer
532  * @param value a 'struct PeerSession*' to clean up
533  * @return GNUNET_OK (continue to iterate)
534  */
535 static int
536 destroy_session (void *cls, const GNUNET_HashCode * key, void *value)
537 {
538   struct Session *peer_session = value;
539
540   GNUNET_assert (GNUNET_YES ==
541                  GNUNET_CONTAINER_multihashmap_remove (peer_session->plugin->sessions, 
542                                                        &peer_session->target.hashPubKey, peer_session));
543   if (peer_session->frag != NULL)
544     GNUNET_FRAGMENT_context_destroy (peer_session->frag);
545   if (GNUNET_SCHEDULER_NO_TASK != peer_session->delayed_cont_task)
546     GNUNET_SCHEDULER_cancel (peer_session->delayed_cont_task);
547   GNUNET_free (peer_session);
548   return GNUNET_OK;
549 }
550
551
552 /**
553  * Destroy a session, plugin is being unloaded.
554  *
555  * @param cls unused
556  * @param key hash of public key of target peer
557  * @param value a 'struct PeerSession*' to clean up
558  * @return GNUNET_OK (continue to iterate)
559  */
560 static int
561 destroy_inbound_session (void *cls, const GNUNET_HashCode * key, void *value)
562 {
563   struct Session *s = value;
564
565   if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK)
566     GNUNET_SCHEDULER_cancel (s->invalidation_task);
567   if (GNUNET_SCHEDULER_NO_TASK != s->delayed_cont_task)
568     GNUNET_SCHEDULER_cancel (s->delayed_cont_task);
569   GNUNET_CONTAINER_multihashmap_remove (s->plugin->inbound_sessions, &s->target.hashPubKey, s);
570   GNUNET_free (s);
571   return GNUNET_OK;
572 }
573
574
575 /**
576  * Disconnect from a remote node.  Clean up session if we have one for this peer
577  *
578  * @param cls closure for this call (should be handle to Plugin)
579  * @param target the peeridentity of the peer to disconnect
580  * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
581  */
582 static void
583 udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
584 {
585   struct Plugin *plugin = cls;
586   struct Session *session;
587
588   session = find_session (plugin, target);
589   if (NULL == session)
590     return;
591   GNUNET_assert (GNUNET_OK ==
592                  GNUNET_CONTAINER_multihashmap_remove (plugin->sessions,
593                                                        &target->hashPubKey,
594                                                        session));
595
596   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->inbound_sessions,
597                                               &target->hashPubKey,
598                                               &destroy_inbound_session, NULL);
599   plugin->last_expected_delay = GNUNET_FRAGMENT_context_destroy (session->frag);
600   if (GNUNET_SCHEDULER_NO_TASK != session->delayed_cont_task)
601     GNUNET_SCHEDULER_cancel (session->delayed_cont_task);
602   if (session->cont != NULL)
603     session->cont (session->cont_cls, target, GNUNET_SYSERR);
604   GNUNET_free (session);
605 }
606
607
608 /**
609  * Actually send out the message.
610  *
611  * @param plugin the plugin
612  * @param sa the address to send the message to
613  * @param msg message to transmit
614  * @return the number of bytes written
615  */
616 static ssize_t
617 udp_send (struct Plugin *plugin, const struct sockaddr *sa,
618           const struct GNUNET_MessageHeader *msg)
619 {
620   ssize_t sent;
621   size_t slen;
622
623   switch (sa->sa_family)
624   {
625   case AF_INET:
626     if (NULL == plugin->sockv4)
627       return 0;
628     sent =
629         GNUNET_NETWORK_socket_sendto (plugin->sockv4, msg, ntohs (msg->size),
630                                       sa, slen = sizeof (struct sockaddr_in));
631     break;
632   case AF_INET6:
633     if (NULL == plugin->sockv6)
634       return 0;
635     sent =
636         GNUNET_NETWORK_socket_sendto (plugin->sockv6, msg, ntohs (msg->size),
637                                       sa, slen = sizeof (struct sockaddr_in6));
638     break;
639   default:
640     GNUNET_break (0);
641     return 0;
642   }
643   if (GNUNET_SYSERR == sent)
644   {
645     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
646     LOG (GNUNET_ERROR_TYPE_ERROR,
647          "UDP transmited %u-byte message to %s (%d: %s)\n",
648          (unsigned int) ntohs (msg->size), GNUNET_a2s (sa, slen), (int) sent,
649          (sent < 0) ? STRERROR (errno) : "ok");
650
651   }
652   LOG (GNUNET_ERROR_TYPE_DEBUG,
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   return sent;
657 }
658
659
660 /**
661  * Function that is called with messages created by the fragmentation
662  * module.  In the case of the 'proc' callback of the
663  * GNUNET_FRAGMENT_context_create function, this function must
664  * eventually call 'GNUNET_FRAGMENT_context_transmission_done'.
665  *
666  * @param cls closure, the 'struct PeerSession'
667  * @param msg the message that was created
668  */
669 static void
670 send_fragment (void *cls, const struct GNUNET_MessageHeader *msg)
671 {
672   struct Session *session = cls;
673
674   udp_send (session->plugin, session->sock_addr, msg);
675   GNUNET_FRAGMENT_context_transmission_done (session->frag);
676 }
677
678
679 static struct Session *
680 create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
681                 const void *addr, size_t addrlen,
682                 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
683 {
684   struct Session *peer_session;
685   const struct IPv4UdpAddress *t4;
686   const struct IPv6UdpAddress *t6;
687   struct sockaddr_in *v4;
688   struct sockaddr_in6 *v6;
689   size_t len;
690
691   switch (addrlen)
692   {
693   case sizeof (struct IPv4UdpAddress):
694     if (NULL == plugin->sockv4)
695     {
696       return NULL;
697     }
698     t4 = addr;
699     peer_session =
700         GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in));
701     len = sizeof (struct sockaddr_in);
702     v4 = (struct sockaddr_in *) &peer_session[1];
703     v4->sin_family = AF_INET;
704 #if HAVE_SOCKADDR_IN_SIN_LEN
705     v4->sin_len = sizeof (struct sockaddr_in);
706 #endif
707     v4->sin_port = t4->u4_port;
708     v4->sin_addr.s_addr = t4->ipv4_addr;
709     break;
710   case sizeof (struct IPv6UdpAddress):
711     if (NULL == plugin->sockv6)
712     {
713       return NULL;
714     }
715     t6 = addr;
716     peer_session =
717         GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in6));
718     len = sizeof (struct sockaddr_in6);
719     v6 = (struct sockaddr_in6 *) &peer_session[1];
720     v6->sin6_family = AF_INET6;
721 #if HAVE_SOCKADDR_IN_SIN_LEN
722     v6->sin6_len = sizeof (struct sockaddr_in6);
723 #endif
724     v6->sin6_port = t6->u6_port;
725     v6->sin6_addr = t6->ipv6_addr;
726     break;
727   default:
728     /* Must have a valid address to send to */
729     GNUNET_break_op (0);
730     return NULL;
731   }
732
733   peer_session->valid_until = GNUNET_TIME_absolute_get_zero ();
734   peer_session->invalidation_task = GNUNET_SCHEDULER_NO_TASK;
735   peer_session->addrlen = len;
736   peer_session->target = *target;
737   peer_session->plugin = plugin;
738   peer_session->sock_addr = (const struct sockaddr *) &peer_session[1];
739   peer_session->cont = cont;
740   peer_session->cont_cls = cont_cls;
741
742   return peer_session;
743 }
744
745 static const char *
746 udp_address_to_string (void *cls, const void *addr, size_t addrlen);
747
748
749 static void
750 udp_call_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
751 {
752   struct Session *s = cls;
753   GNUNET_TRANSPORT_TransmitContinuation cont = s->cont;
754
755   s->delayed_cont_task = GNUNET_SCHEDULER_NO_TASK;
756   s->cont = NULL;
757   cont (s->cont_cls, &s->target, GNUNET_OK);
758 }
759
760
761 /**
762  * Function that can be used by the transport service to transmit
763  * a message using the plugin.
764  *
765  * @param cls closure
766  * @param target who should receive this message (ignored by UDP)
767  * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
768  * @param msgbuf_size the size of the msgbuf to send
769  * @param priority how important is the message (ignored by UDP)
770  * @param timeout when should we time out (give up) if we can not transmit?
771  * @param session identifier used for this session (NULL for UDP)
772  * @param addr the addr to send the message to
773  * @param addrlen the len of addr
774  * @param force_address not used, we had better have an address to send to
775  *        because we are stateless!!
776  * @param cont continuation to call once the message has
777  *        been transmitted (or if the transport is ready
778  *        for the next transmission call; or if the
779  *        peer disconnected...)
780  * @param cont_cls closure for cont
781  *
782  * @return the number of bytes written (may return 0 and the message can
783  *         still be transmitted later!)
784  */
785 static ssize_t
786 udp_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
787                  const char *msgbuf, size_t msgbuf_size, unsigned int priority,
788                  struct GNUNET_TIME_Relative timeout, struct Session *session,
789                  const void *addr, size_t addrlen, int force_address,
790                  GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
791 {
792   struct Plugin *plugin = cls;
793   struct Session *peer_session;
794   struct Session *s;
795   const struct IPv4UdpAddress *t4;
796   const struct IPv6UdpAddress *t6;
797   size_t mlen = msgbuf_size + sizeof (struct UDPMessage);
798   char mbuf[mlen];
799   struct UDPMessage *udp;
800   struct GNUNET_TIME_Relative delta;
801
802   if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
803   {
804     GNUNET_break (0);
805     return GNUNET_SYSERR;
806   }
807
808   LOG (GNUNET_ERROR_TYPE_DEBUG,
809        "UDP transmits %u-byte message to `%s' using address `%s' session 0x%X mode %i\n",
810        msgbuf_size, GNUNET_i2s (target), udp_address_to_string (NULL, addr,
811                                                                 addrlen),
812        session, force_address);
813
814   if ((force_address == GNUNET_SYSERR) && (session == NULL))
815     return GNUNET_SYSERR;
816
817   s = NULL;
818   /* safety check: comparing address to address stored in session */
819   if ((session != NULL) && (addr != NULL) && (addrlen != 0))
820   {
821     s = session;
822     GNUNET_assert (GNUNET_YES ==
823                    GNUNET_CONTAINER_multihashmap_contains_value
824                    (plugin->inbound_sessions, &target->hashPubKey, s));
825
826     if (0 != memcmp (&s->target, target, sizeof (struct GNUNET_PeerIdentity)))
827       return GNUNET_SYSERR;
828     switch (addrlen)
829     {
830     case sizeof (struct IPv4UdpAddress):
831       if (NULL == plugin->sockv4)
832       {
833         if (cont != NULL)
834           cont (cont_cls, target, GNUNET_SYSERR);
835         return GNUNET_SYSERR;
836       }
837       t4 = addr;
838       if (s->addrlen != (sizeof (struct sockaddr_in)))
839         return GNUNET_SYSERR;
840       struct sockaddr_in *a4 = (struct sockaddr_in *) s->sock_addr;
841
842       GNUNET_assert (a4->sin_port == t4->u4_port);
843       GNUNET_assert (0 ==
844                      memcmp (&a4->sin_addr, &t4->ipv4_addr,
845                              sizeof (struct in_addr)));
846       LOG (GNUNET_ERROR_TYPE_DEBUG, "Session 0x%X successfully checked!\n",
847            session);
848       break;
849     case sizeof (struct IPv6UdpAddress):
850       if (NULL == plugin->sockv6)
851       {
852         if (cont != NULL)
853           cont (cont_cls, target, GNUNET_SYSERR);
854         return GNUNET_SYSERR;
855       }
856       t6 = addr;
857       GNUNET_assert (s->addrlen == sizeof (struct sockaddr_in6));
858       struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) s->sock_addr;
859
860       GNUNET_assert (a6->sin6_port == t6->u6_port);
861       GNUNET_assert (0 ==
862                      memcmp (&a6->sin6_addr, &t6->ipv6_addr,
863                              sizeof (struct in6_addr)));
864       LOG (GNUNET_ERROR_TYPE_DEBUG, "Session 0x%X successfully checked!\n",
865            session);
866       break;
867     default:
868       /* Must have a valid address to send to */
869       GNUNET_break_op (0);
870     }
871   }
872 //session_invalid:
873   if ((addr == NULL) || (addrlen == 0))
874     return GNUNET_SYSERR;
875   peer_session = create_session (plugin, target, addr, addrlen, cont, cont_cls);
876   if (peer_session == NULL)
877   {
878     if (cont != NULL)
879       cont (cont_cls, target, GNUNET_SYSERR);
880     return GNUNET_SYSERR;;
881   }
882
883   /* Message */
884   udp = (struct UDPMessage *) mbuf;
885   udp->header.size = htons (mlen);
886   udp->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE);
887   udp->reserved = htonl (0);
888   udp->sender = *plugin->env->my_identity;
889   memcpy (&udp[1], msgbuf, msgbuf_size);
890
891   if (s != NULL)
892     delta = GNUNET_TIME_absolute_get_remaining (s->flow_delay_from_other_peer);
893   else
894     delta = GNUNET_TIME_UNIT_ZERO;
895   if (mlen <= UDP_MTU)
896   {
897     mlen = udp_send (plugin, peer_session->sock_addr, &udp->header);
898     if (cont != NULL)
899     {
900       if ((delta.rel_value > 0) && (mlen > 0))
901       {
902         s->cont = cont;
903         s->cont_cls = cont_cls;
904         s->delayed_cont_task =
905             GNUNET_SCHEDULER_add_delayed (delta, &udp_call_continuation, s);
906       }
907       else
908         cont (cont_cls, target, (mlen > 0) ? GNUNET_OK : GNUNET_SYSERR);
909     }
910     GNUNET_free_non_null (peer_session);
911   }
912   else
913   {
914     GNUNET_assert (GNUNET_OK ==
915                    GNUNET_CONTAINER_multihashmap_put (plugin->sessions,
916                                                       &target->hashPubKey,
917                                                       peer_session,
918                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
919     peer_session->frag =
920         GNUNET_FRAGMENT_context_create (plugin->env->stats, UDP_MTU,
921                                         &plugin->tracker,
922                                         plugin->last_expected_delay,
923                                         &udp->header, &send_fragment,
924                                         peer_session);
925   }
926   return mlen;
927 }
928
929
930 /**
931  * Closure for 'process_inbound_tokenized_messages'
932  */
933 struct SourceInformation
934 {
935   /**
936    * Sender identity.
937    */
938   struct GNUNET_PeerIdentity sender;
939
940   /**
941    * Source address.
942    */
943   const void *arg;
944
945   /**
946    * Number of bytes in source address.
947    */
948   size_t args;
949
950   struct Session *session;
951 };
952
953
954 /**
955  * Message tokenizer has broken up an incomming message. Pass it on
956  * to the service.
957  *
958  * @param cls the 'struct Plugin'
959  * @param client the 'struct SourceInformation'
960  * @param hdr the actual message
961  */
962 static void
963 process_inbound_tokenized_messages (void *cls, void *client,
964                                     const struct GNUNET_MessageHeader *hdr)
965 {
966   struct Plugin *plugin = cls;
967   struct SourceInformation *si = client;
968   struct GNUNET_ATS_Information distance;
969   struct GNUNET_TIME_Relative delay;
970
971   /* setup ATS */
972   distance.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
973   distance.value = htonl (1);
974
975   LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving Session %X %s  to transport\n",
976        si->session, GNUNET_i2s (&si->session->target));
977   delay =
978       plugin->env->receive (plugin->env->cls, &si->sender, hdr, &distance, 1,
979                             si->session, si->arg, si->args);
980   si->session->flow_delay_for_other_peer = delay;
981 }
982
983 static void
984 invalidation_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
985 {
986   struct Session *s = cls;
987
988   s->invalidation_task = GNUNET_SCHEDULER_NO_TASK;
989   LOG (GNUNET_ERROR_TYPE_DEBUG, "Session %X (`%s') is now invalid\n", s,
990        GNUNET_a2s (s->sock_addr, s->addrlen));
991
992   s->plugin->env->session_end (s->plugin->env->cls, &s->target, s);
993   GNUNET_assert (GNUNET_YES ==
994                  GNUNET_CONTAINER_multihashmap_remove (s->
995                                                        plugin->inbound_sessions,
996                                                        &s->target.hashPubKey,
997                                                        s));
998   GNUNET_free (s);
999 }
1000
1001
1002 /**
1003  * We've received a UDP Message.  Process it (pass contents to main service).
1004  *
1005  * @param plugin plugin context
1006  * @param msg the message
1007  * @param sender_addr sender address
1008  * @param sender_addr_len number of bytes in sender_addr
1009  */
1010 static void
1011 process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
1012                      const struct sockaddr *sender_addr,
1013                      socklen_t sender_addr_len)
1014 {
1015   struct SourceInformation si;
1016   struct IPv4UdpAddress u4;
1017   struct IPv6UdpAddress u6;
1018   const void *arg;
1019   size_t args;
1020
1021   if (0 != ntohl (msg->reserved))
1022   {
1023     GNUNET_break_op (0);
1024     return;
1025   }
1026   if (ntohs (msg->header.size) <
1027       sizeof (struct GNUNET_MessageHeader) + sizeof (struct UDPMessage))
1028   {
1029     GNUNET_break_op (0);
1030     return;
1031   }
1032
1033   /* convert address */
1034   switch (sender_addr->sa_family)
1035   {
1036   case AF_INET:
1037     GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in));
1038     u4.ipv4_addr = ((struct sockaddr_in *) sender_addr)->sin_addr.s_addr;
1039     u4.u4_port = ((struct sockaddr_in *) sender_addr)->sin_port;
1040     arg = &u4;
1041     args = sizeof (u4);
1042     break;
1043   case AF_INET6:
1044     GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in6));
1045     u6.ipv6_addr = ((struct sockaddr_in6 *) sender_addr)->sin6_addr;
1046     u6.u6_port = ((struct sockaddr_in6 *) sender_addr)->sin6_port;
1047     arg = &u6;
1048     args = sizeof (u6);
1049     break;
1050   default:
1051     GNUNET_break (0);
1052     return;
1053   }
1054 #if DEBUG_UDP
1055   LOG (GNUNET_ERROR_TYPE_DEBUG,
1056        "Received message with %u bytes from peer `%s' at `%s'\n",
1057        (unsigned int) ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
1058        GNUNET_a2s (sender_addr, sender_addr_len));
1059 #endif
1060
1061   /* create a session for inbound connections */
1062   const struct UDPMessage *udp_msg = (const struct UDPMessage *) msg;
1063
1064   LOG (GNUNET_ERROR_TYPE_DEBUG,
1065        "Lookup inbound UDP sessions for peer `%s' address `%s'\n",
1066        GNUNET_i2s (&udp_msg->sender), udp_address_to_string (NULL, arg, args));
1067
1068   struct Session *s = NULL;
1069
1070   s = find_inbound_session (plugin, &udp_msg->sender, sender_addr,
1071                             sender_addr_len);
1072
1073   if (s != NULL)
1074   {
1075     LOG (GNUNET_ERROR_TYPE_DEBUG,
1076          "Found existing inbound UDP sessions 0x%X for peer `%s' address `%s'\n",
1077          s, GNUNET_i2s (&s->target), udp_address_to_string (NULL, arg, args));
1078   }
1079   else
1080   {
1081     s = create_session (plugin, &udp_msg->sender, arg, args, NULL, NULL);
1082     LOG (GNUNET_ERROR_TYPE_DEBUG,
1083          "Creating inbound UDP sessions 0x%X for peer `%s' address `%s'\n", s,
1084          GNUNET_i2s (&s->target), udp_address_to_string (NULL, arg, args));
1085
1086     GNUNET_assert (GNUNET_OK ==
1087                    GNUNET_CONTAINER_multihashmap_put (plugin->inbound_sessions,
1088                                                       &s->target.hashPubKey, s,
1089                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1090   }
1091   s->valid_until =
1092       GNUNET_TIME_relative_to_absolute
1093       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1094   if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK)
1095   {
1096     GNUNET_SCHEDULER_cancel (s->invalidation_task);
1097     s->invalidation_task = GNUNET_SCHEDULER_NO_TASK;
1098     LOG (GNUNET_ERROR_TYPE_DEBUG, "Rescheduling %X' `%s'\n", s,
1099          udp_address_to_string (NULL, arg, args));
1100   }
1101   s->invalidation_task =
1102       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1103                                     &invalidation_task, s);
1104   /* iterate over all embedded messages */
1105   si.sender = msg->sender;
1106   si.arg = arg;
1107   si.args = args;
1108   si.session = s;
1109   GNUNET_SERVER_mst_receive (plugin->mst, &si, (const char *) &msg[1],
1110                              ntohs (msg->header.size) -
1111                              sizeof (struct UDPMessage), GNUNET_YES, GNUNET_NO);
1112 }
1113
1114
1115 /**
1116  * Process a defragmented message.
1117  *
1118  * @param cls the 'struct ReceiveContext'
1119  * @param msg the message
1120  */
1121 static void
1122 fragment_msg_proc (void *cls, const struct GNUNET_MessageHeader *msg)
1123 {
1124   struct ReceiveContext *rc = cls;
1125
1126   if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE)
1127   {
1128     GNUNET_break (0);
1129     return;
1130   }
1131   if (ntohs (msg->size) < sizeof (struct UDPMessage))
1132   {
1133     GNUNET_break (0);
1134     return;
1135   }
1136   process_udp_message (rc->plugin, (const struct UDPMessage *) msg,
1137                        rc->src_addr, rc->addr_len);
1138 }
1139
1140
1141 /**
1142  * Transmit an acknowledgement.
1143  *
1144  * @param cls the 'struct ReceiveContext'
1145  * @param id message ID (unused)
1146  * @param msg ack to transmit
1147  */
1148 static void
1149 ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
1150 {
1151   struct ReceiveContext *rc = cls;
1152
1153   size_t msize = sizeof (struct UDP_ACK_Message) + ntohs (msg->size);
1154   char buf[msize];
1155   struct UDP_ACK_Message *udp_ack;
1156   uint32_t delay = 0;
1157
1158   struct Session *s;
1159
1160   s = find_inbound_session_by_addr (rc->plugin, rc->src_addr, rc->addr_len);
1161   if (s != NULL)
1162   {
1163     if (s->flow_delay_for_other_peer.rel_value <= UINT32_MAX)
1164       delay = s->flow_delay_for_other_peer.rel_value;
1165     else
1166       delay = UINT32_MAX;
1167   }
1168
1169
1170 #if DEBUG_UDP
1171   LOG (GNUNET_ERROR_TYPE_DEBUG,
1172        "Sending ACK to `%s' including delay of %u ms\n",
1173        GNUNET_a2s (rc->src_addr,
1174                    (rc->src_addr->sa_family ==
1175                     AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct
1176                                                                      sockaddr_in6)),
1177        delay);
1178 #endif
1179   udp_ack = (struct UDP_ACK_Message *) buf;
1180   udp_ack->header.size = htons ((uint16_t) msize);
1181   udp_ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK);
1182   udp_ack->delay = htonl (delay);
1183   udp_ack->sender = *rc->plugin->env->my_identity;
1184   memcpy (&udp_ack[1], msg, ntohs (msg->size));
1185   (void) udp_send (rc->plugin, rc->src_addr, &udp_ack->header);
1186 }
1187
1188
1189 /**
1190  * Closure for 'find_receive_context'.
1191  */
1192 struct FindReceiveContext
1193 {
1194   /**
1195    * Where to store the result.
1196    */
1197   struct ReceiveContext *rc;
1198
1199   /**
1200    * Address to find.
1201    */
1202   const struct sockaddr *addr;
1203
1204   /**
1205    * Number of bytes in 'addr'.
1206    */
1207   socklen_t addr_len;
1208
1209   struct Session *session;
1210 };
1211
1212
1213 /**
1214  * Scan the heap for a receive context with the given address.
1215  *
1216  * @param cls the 'struct FindReceiveContext'
1217  * @param node internal node of the heap
1218  * @param element value stored at the node (a 'struct ReceiveContext')
1219  * @param cost cost associated with the node
1220  * @return GNUNET_YES if we should continue to iterate,
1221  *         GNUNET_NO if not.
1222  */
1223 static int
1224 find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
1225                       void *element, GNUNET_CONTAINER_HeapCostType cost)
1226 {
1227   struct FindReceiveContext *frc = cls;
1228   struct ReceiveContext *e = element;
1229
1230   if ((frc->addr_len == e->addr_len) &&
1231       (0 == memcmp (frc->addr, e->src_addr, frc->addr_len)))
1232   {
1233     frc->rc = e;
1234     return GNUNET_NO;
1235   }
1236   return GNUNET_YES;
1237 }
1238
1239 struct Mstv4Context
1240 {
1241   struct Plugin *plugin;
1242
1243   struct IPv4UdpAddress addr;
1244 };
1245
1246 struct Mstv6Context
1247 {
1248   struct Plugin *plugin;
1249
1250   struct IPv6UdpAddress addr;
1251 };
1252
1253
1254 /**
1255  * Read and process a message from the given socket.
1256  *
1257  * @param plugin the overall plugin
1258  * @param rsock socket to read from
1259  */
1260 static void
1261 udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
1262 {
1263   socklen_t fromlen;
1264   char addr[32];
1265   char buf[65536];
1266   ssize_t ret;
1267   const struct GNUNET_MessageHeader *msg;
1268   const struct GNUNET_MessageHeader *ack;
1269   struct Session *peer_session;
1270   const struct UDP_ACK_Message *udp_ack;
1271   struct ReceiveContext *rc;
1272   struct GNUNET_TIME_Absolute now;
1273   struct FindReceiveContext frc;
1274   struct Session *s = NULL;
1275   struct GNUNET_TIME_Relative flow_delay;
1276
1277   fromlen = sizeof (addr);
1278   memset (&addr, 0, sizeof (addr));
1279   ret =
1280       GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof (buf),
1281                                       (struct sockaddr *) &addr, &fromlen);
1282   if (ret < sizeof (struct GNUNET_MessageHeader))
1283   {
1284     GNUNET_break_op (0);
1285     return;
1286   }
1287   msg = (const struct GNUNET_MessageHeader *) buf;
1288
1289   LOG (GNUNET_ERROR_TYPE_DEBUG,
1290        "UDP received %u-byte message from `%s' type %i\n", (unsigned int) ret,
1291        GNUNET_a2s ((const struct sockaddr *) addr, fromlen), ntohs (msg->type));
1292
1293   if (ret != ntohs (msg->size))
1294   {
1295     GNUNET_break_op (0);
1296     return;
1297   }
1298   switch (ntohs (msg->type))
1299   {
1300   case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON:
1301     {
1302       if (fromlen == sizeof (struct sockaddr_in))
1303       {
1304         LOG (GNUNET_ERROR_TYPE_DEBUG, "Received IPv4 HELLO beacon broadcast with %i bytes from address %s\n",
1305             ret, GNUNET_a2s((const struct sockaddr *) &addr, fromlen));
1306
1307         struct Mstv4Context *mc;
1308         mc = GNUNET_malloc (sizeof (struct Mstv4Context));
1309         struct sockaddr_in *av4 = (struct sockaddr_in *) &addr;
1310
1311         mc->addr.ipv4_addr = av4->sin_addr.s_addr;
1312         mc->addr.u4_port = av4->sin_port;
1313         if (GNUNET_OK !=
1314           GNUNET_SERVER_mst_receive (plugin->broadcast_ipv4_mst, mc, buf, ret, GNUNET_NO,
1315                                      GNUNET_NO))
1316         GNUNET_free (mc);
1317       }
1318       else if (fromlen == sizeof (struct sockaddr_in6))
1319       {
1320         LOG (GNUNET_ERROR_TYPE_DEBUG, "Received IPv6 HELLO beacon broadcast with %i bytes from address %s\n",
1321             ret, GNUNET_a2s((const struct sockaddr *) &addr, fromlen));
1322
1323         struct Mstv6Context *mc;
1324         mc = GNUNET_malloc (sizeof (struct Mstv6Context));
1325         struct sockaddr_in6 *av6 = (struct sockaddr_in6 *) &addr;
1326
1327         mc->addr.ipv6_addr = av6->sin6_addr;
1328         mc->addr.u6_port = av6->sin6_port;
1329
1330         if (GNUNET_OK !=
1331             GNUNET_SERVER_mst_receive (plugin->broadcast_ipv6_mst, mc, buf, ret, GNUNET_NO,
1332                                        GNUNET_NO))
1333           GNUNET_free (mc);
1334       }
1335       return;
1336     }
1337   case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE:
1338     if (ntohs (msg->size) < sizeof (struct UDPMessage))
1339     {
1340       GNUNET_break_op (0);
1341       return;
1342     }
1343     process_udp_message (plugin, (const struct UDPMessage *) msg,
1344                          (const struct sockaddr *) addr, fromlen);
1345     return;
1346   case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK:
1347
1348     if (ntohs (msg->size) <
1349         sizeof (struct UDP_ACK_Message) + sizeof (struct GNUNET_MessageHeader))
1350     {
1351       GNUNET_break_op (0);
1352       return;
1353     }
1354     udp_ack = (const struct UDP_ACK_Message *) msg;
1355     s = find_inbound_session (plugin, &udp_ack->sender, addr, fromlen);
1356     if (s != NULL)
1357     {
1358       flow_delay.rel_value = (uint64_t) ntohl (udp_ack->delay);
1359
1360       LOG (GNUNET_ERROR_TYPE_DEBUG, "We received a sending delay of %llu\n",
1361            flow_delay.rel_value);
1362
1363       s->flow_delay_from_other_peer =
1364           GNUNET_TIME_relative_to_absolute (flow_delay);
1365     }
1366     ack = (const struct GNUNET_MessageHeader *) &udp_ack[1];
1367     if (ntohs (ack->size) !=
1368         ntohs (msg->size) - sizeof (struct UDP_ACK_Message))
1369     {
1370       GNUNET_break_op (0);
1371       return;
1372     }
1373 #if DEBUG_UDP
1374     LOG (GNUNET_ERROR_TYPE_DEBUG,
1375          "UDP processes %u-byte acknowledgement from `%s' at `%s'\n",
1376          (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender),
1377          GNUNET_a2s ((const struct sockaddr *) addr, fromlen));
1378 #endif
1379
1380     peer_session = find_session (plugin, &udp_ack->sender);
1381     if (NULL == peer_session)
1382     {
1383 #if DEBUG_UDP
1384       LOG (GNUNET_ERROR_TYPE_DEBUG,
1385            "Session for ACK not found, dropping ACK!\n");
1386 #endif
1387       return;
1388     }
1389     if (GNUNET_OK != GNUNET_FRAGMENT_process_ack (peer_session->frag, ack))
1390       return;
1391     GNUNET_assert (GNUNET_OK ==
1392                    GNUNET_CONTAINER_multihashmap_remove (plugin->sessions,
1393                                                          &udp_ack->
1394                                                          sender.hashPubKey,
1395                                                          peer_session));
1396     plugin->last_expected_delay =
1397         GNUNET_FRAGMENT_context_destroy (peer_session->frag);
1398     if (peer_session->cont != NULL)
1399       peer_session->cont (peer_session->cont_cls, &udp_ack->sender, GNUNET_OK);
1400     GNUNET_free (peer_session);
1401     return;
1402   case GNUNET_MESSAGE_TYPE_FRAGMENT:
1403     frc.rc = NULL;
1404     frc.addr = (const struct sockaddr *) addr;
1405     frc.addr_len = fromlen;
1406     GNUNET_CONTAINER_heap_iterate (plugin->defrags, &find_receive_context,
1407                                    &frc);
1408     now = GNUNET_TIME_absolute_get ();
1409     rc = frc.rc;
1410     if (rc == NULL)
1411     {
1412       /* need to create a new RC */
1413       rc = GNUNET_malloc (sizeof (struct ReceiveContext) + fromlen);
1414       memcpy (&rc[1], addr, fromlen);
1415       rc->src_addr = (const struct sockaddr *) &rc[1];
1416       rc->addr_len = fromlen;
1417       rc->plugin = plugin;
1418       rc->defrag =
1419           GNUNET_DEFRAGMENT_context_create (plugin->env->stats, UDP_MTU,
1420                                             UDP_MAX_MESSAGES_IN_DEFRAG, rc,
1421                                             &fragment_msg_proc, &ack_proc);
1422       rc->hnode =
1423           GNUNET_CONTAINER_heap_insert (plugin->defrags, rc,
1424                                         (GNUNET_CONTAINER_HeapCostType)
1425                                         now.abs_value);
1426     }
1427 #if DEBUG_UDP
1428     LOG (GNUNET_ERROR_TYPE_DEBUG, "UDP processes %u-byte fragment from `%s'\n",
1429          (unsigned int) ntohs (msg->size),
1430          GNUNET_a2s ((const struct sockaddr *) addr, fromlen));
1431 #endif
1432
1433     if (GNUNET_OK == GNUNET_DEFRAGMENT_process_fragment (rc->defrag, msg))
1434     {
1435       /* keep this 'rc' from expiring */
1436       GNUNET_CONTAINER_heap_update_cost (plugin->defrags, rc->hnode,
1437                                          (GNUNET_CONTAINER_HeapCostType)
1438                                          now.abs_value);
1439     }
1440     if (GNUNET_CONTAINER_heap_get_size (plugin->defrags) >
1441         UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG)
1442     {
1443       /* remove 'rc' that was inactive the longest */
1444       rc = GNUNET_CONTAINER_heap_remove_root (plugin->defrags);
1445       GNUNET_assert (NULL != rc);
1446       GNUNET_DEFRAGMENT_context_destroy (rc->defrag);
1447       GNUNET_free (rc);
1448     }
1449     return;
1450   default:
1451     GNUNET_break_op (0);
1452     return;
1453   }
1454 }
1455
1456
1457 /**
1458  * We have been notified that our writeset has something to read.  We don't
1459  * know which socket needs to be read, so we have to check each one
1460  * Then reschedule this function to be called again once more is available.
1461  *
1462  * @param cls the plugin handle
1463  * @param tc the scheduling context (for rescheduling this function again)
1464  */
1465 static void
1466 udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1467 {
1468   struct Plugin *plugin = cls;
1469
1470   plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
1471   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1472     return;
1473   if ((NULL != plugin->sockv4) &&
1474       (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4)))
1475     udp_read (plugin, plugin->sockv4);
1476   if ((NULL != plugin->sockv6) &&
1477       (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)))
1478     udp_read (plugin, plugin->sockv6);
1479   plugin->select_task =
1480       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1481                                    GNUNET_SCHEDULER_NO_TASK,
1482                                    GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1483                                    NULL, &udp_plugin_select, plugin);
1484
1485 }
1486
1487
1488 void
1489 broadcast_ipv4_mst_cb (void *cls, void *client,
1490                       const struct GNUNET_MessageHeader *message)
1491 {
1492   struct Plugin *plugin = cls;
1493   struct Mstv4Context *mc = client;
1494   const struct GNUNET_MessageHeader *hello;
1495   struct UDP_Beacon_Message *msg;
1496
1497   msg = (struct UDP_Beacon_Message *) message;
1498
1499   if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
1500       ntohs (msg->header.type))
1501     return;
1502
1503   LOG (GNUNET_ERROR_TYPE_DEBUG,
1504        "Received beacon with %u bytes from peer `%s' via address `%s'\n",
1505        ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
1506        udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
1507
1508   struct GNUNET_ATS_Information ats;
1509
1510   ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
1511   ats.value = htonl (1);
1512
1513   hello = (struct GNUNET_MessageHeader *) &msg[1];
1514   plugin->env->receive (plugin->env->cls, &msg->sender, hello, &ats, 1, NULL,
1515                         (const char *) &mc->addr, sizeof (mc->addr));
1516
1517   GNUNET_STATISTICS_update (plugin->env->stats,
1518                             _("# IPv4 broadcast HELLO beacons received via udp"), 1,
1519                             GNUNET_NO);
1520   GNUNET_free (mc);
1521 }
1522
1523
1524 void
1525 broadcast_ipv6_mst_cb (void *cls, void *client,
1526                       const struct GNUNET_MessageHeader *message)
1527 {
1528
1529   struct Plugin *plugin = cls;
1530   struct Mstv6Context *mc = client;
1531   const struct GNUNET_MessageHeader *hello;
1532   struct UDP_Beacon_Message *msg;
1533
1534   msg = (struct UDP_Beacon_Message *) message;
1535
1536   if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
1537       ntohs (msg->header.type))
1538     return;
1539
1540   LOG (GNUNET_ERROR_TYPE_DEBUG,
1541        "Received beacon with %u bytes from peer `%s' via address `%s'\n",
1542        ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
1543        udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
1544
1545   struct GNUNET_ATS_Information ats;
1546
1547   ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
1548   ats.value = htonl (1);
1549
1550   hello = (struct GNUNET_MessageHeader *) &msg[1];
1551   plugin->env->receive (plugin->env->cls, &msg->sender, hello, &ats, 1, NULL,
1552                         (const char *) &mc->addr, sizeof (mc->addr));
1553
1554   GNUNET_STATISTICS_update (plugin->env->stats,
1555                             _("# IPv6 multicast HELLO beacons received via udp"), 1,
1556                             GNUNET_NO);
1557   GNUNET_free (mc);
1558 }
1559
1560
1561 static void
1562 udp_ipv4_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1563 {
1564   struct Plugin *plugin = cls;
1565   int sent;
1566   uint16_t msg_size;
1567   uint16_t hello_size;
1568   char buf[65536];
1569
1570   const struct GNUNET_MessageHeader *hello;
1571   struct UDP_Beacon_Message *msg;
1572   struct BroadcastAddress * baddr;
1573
1574   plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
1575
1576   hello = plugin->env->get_our_hello ();
1577   hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
1578   msg_size = hello_size + sizeof (struct UDP_Beacon_Message);
1579
1580   if (hello_size < (sizeof (struct GNUNET_MessageHeader)) ||
1581       (msg_size > (UDP_MTU)))
1582     return;
1583
1584   msg = (struct UDP_Beacon_Message *) buf;
1585   msg->sender = *(plugin->env->my_identity);
1586   msg->header.size = ntohs (msg_size);
1587   msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON);
1588   memcpy (&msg[1], hello, hello_size);
1589   sent = 0;
1590
1591   baddr = plugin->ipv4_broadcast_head;
1592   /* just IPv4 */
1593   while ((baddr != NULL) && (baddr->addrlen == sizeof (struct sockaddr_in)))
1594   {
1595     struct sockaddr_in * addr = (struct sockaddr_in * ) baddr->addr;
1596     addr->sin_port = htons (plugin->port);
1597
1598     sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4, msg, msg_size,
1599                                         (const struct sockaddr *) addr,
1600                                         baddr->addrlen);
1601     if (sent == GNUNET_SYSERR)
1602       GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "sendto");
1603     else
1604       LOG (GNUNET_ERROR_TYPE_DEBUG, "Sent HELLO beacon broadcast with  %i bytes to address %s\n",
1605            sent, GNUNET_a2s(baddr->addr, baddr->addrlen));
1606       baddr = baddr->next;
1607   }
1608
1609   plugin->send_ipv4_broadcast_task =
1610       GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
1611                                     &udp_ipv4_broadcast_send, plugin);
1612 }
1613
1614 static void
1615 udp_ipv6_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1616 {
1617   struct Plugin *plugin = cls;
1618   int sent;
1619   uint16_t msg_size;
1620   uint16_t hello_size;
1621   char buf[65536];
1622
1623   const struct GNUNET_MessageHeader *hello;
1624   struct UDP_Beacon_Message *msg;
1625
1626   plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
1627
1628   hello = plugin->env->get_our_hello ();
1629   hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
1630   msg_size = hello_size + sizeof (struct UDP_Beacon_Message);
1631
1632   if (hello_size < (sizeof (struct GNUNET_MessageHeader)) ||
1633       (msg_size > (UDP_MTU)))
1634     return;
1635
1636   msg = (struct UDP_Beacon_Message *) buf;
1637   msg->sender = *(plugin->env->my_identity);
1638   msg->header.size = ntohs (msg_size);
1639   msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON);
1640   memcpy (&msg[1], hello, hello_size);
1641   sent = 0;
1642
1643   sent = GNUNET_NETWORK_socket_sendto (plugin->sockv6, msg, msg_size,
1644                                       (const struct sockaddr *) &plugin->ipv6_multicast_address,
1645                                       sizeof(struct sockaddr_in6));
1646   if (sent == GNUNET_SYSERR)
1647     GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "sendto");
1648   else
1649     LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending IPv6 HELLO beacon broadcast with  %i bytes to address %s\n",
1650        sent, GNUNET_a2s((const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof(struct sockaddr_in6)));
1651
1652
1653
1654   plugin->send_ipv6_broadcast_task =
1655       GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
1656                                     &udp_ipv6_broadcast_send, plugin);
1657 }
1658
1659 /**
1660  * Check if the given port is plausible (must be either our listen
1661  * port or our advertised port).  If it is neither, we return
1662  * GNUNET_SYSERR.
1663  *
1664  * @param plugin global variables
1665  * @param in_port port number to check
1666  * @return GNUNET_OK if port is either open_port or adv_port
1667  */
1668 static int
1669 check_port (struct Plugin *plugin, uint16_t in_port)
1670 {
1671   if ((in_port == plugin->port) || (in_port == plugin->aport))
1672     return GNUNET_OK;
1673   return GNUNET_SYSERR;
1674 }
1675
1676
1677 /**
1678  * Function that will be called to check if a binary address for this
1679  * plugin is well-formed and corresponds to an address for THIS peer
1680  * (as per our configuration).  Naturally, if absolutely necessary,
1681  * plugins can be a bit conservative in their answer, but in general
1682  * plugins should make sure that the address does not redirect
1683  * traffic to a 3rd party that might try to man-in-the-middle our
1684  * traffic.
1685  *
1686  * @param cls closure, should be our handle to the Plugin
1687  * @param addr pointer to the address
1688  * @param addrlen length of addr
1689  * @return GNUNET_OK if this is a plausible address for this peer
1690  *         and transport, GNUNET_SYSERR if not
1691  *
1692  */
1693 static int
1694 udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
1695 {
1696   struct Plugin *plugin = cls;
1697   struct IPv4UdpAddress *v4;
1698   struct IPv6UdpAddress *v6;
1699
1700   if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
1701       (addrlen != sizeof (struct IPv6UdpAddress)))
1702   {
1703     GNUNET_break_op (0);
1704     return GNUNET_SYSERR;
1705   }
1706   if (addrlen == sizeof (struct IPv4UdpAddress))
1707   {
1708     v4 = (struct IPv4UdpAddress *) addr;
1709     if (GNUNET_OK != check_port (plugin, ntohs (v4->u4_port)))
1710       return GNUNET_SYSERR;
1711     if (GNUNET_OK !=
1712         GNUNET_NAT_test_address (plugin->nat, &v4->ipv4_addr,
1713                                  sizeof (struct in_addr)))
1714       return GNUNET_SYSERR;
1715   }
1716   else
1717   {
1718     v6 = (struct IPv6UdpAddress *) addr;
1719     if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
1720     {
1721       GNUNET_break_op (0);
1722       return GNUNET_SYSERR;
1723     }
1724     if (GNUNET_OK != check_port (plugin, ntohs (v6->u6_port)))
1725       return GNUNET_SYSERR;
1726     if (GNUNET_OK !=
1727         GNUNET_NAT_test_address (plugin->nat, &v6->ipv6_addr,
1728                                  sizeof (struct in6_addr)))
1729       return GNUNET_SYSERR;
1730   }
1731   return GNUNET_OK;
1732 }
1733
1734
1735 /**
1736  * Function called for a quick conversion of the binary address to
1737  * a numeric address.  Note that the caller must not free the
1738  * address and that the next call to this function is allowed
1739  * to override the address again.
1740  *
1741  * @param cls closure
1742  * @param addr binary address
1743  * @param addrlen length of the address
1744  * @return string representing the same address
1745  */
1746 static const char *
1747 udp_address_to_string (void *cls, const void *addr, size_t addrlen)
1748 {
1749   static char rbuf[INET6_ADDRSTRLEN + 10];
1750   char buf[INET6_ADDRSTRLEN];
1751   const void *sb;
1752   struct in_addr a4;
1753   struct in6_addr a6;
1754   const struct IPv4UdpAddress *t4;
1755   const struct IPv6UdpAddress *t6;
1756   int af;
1757   uint16_t port;
1758
1759   if (addrlen == sizeof (struct IPv6UdpAddress))
1760   {
1761     t6 = addr;
1762     af = AF_INET6;
1763     port = ntohs (t6->u6_port);
1764     memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
1765     sb = &a6;
1766   }
1767   else if (addrlen == sizeof (struct IPv4UdpAddress))
1768   {
1769     t4 = addr;
1770     af = AF_INET;
1771     port = ntohs (t4->u4_port);
1772     memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
1773     sb = &a4;
1774   }
1775   else
1776   {
1777     GNUNET_break_op (0);
1778     return NULL;
1779   }
1780   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
1781   GNUNET_snprintf (rbuf, sizeof (rbuf), (af == AF_INET6) ? "[%s]:%u" : "%s:%u",
1782                    buf, port);
1783   return rbuf;
1784 }
1785
1786
1787 /**
1788  * Closure for 'append_port'.
1789  */
1790 struct PrettyPrinterContext
1791 {
1792   /**
1793    * Function to call with the result.
1794    */
1795   GNUNET_TRANSPORT_AddressStringCallback asc;
1796
1797   /**
1798    * Clsoure for 'asc'.
1799    */
1800   void *asc_cls;
1801
1802   /**
1803    * Port to add after the IP address.
1804    */
1805   uint16_t port;
1806 };
1807
1808
1809 /**
1810  * Append our port and forward the result.
1811  *
1812  * @param cls a 'struct PrettyPrinterContext'
1813  * @param hostname result from DNS resolver
1814  */
1815 static void
1816 append_port (void *cls, const char *hostname)
1817 {
1818   struct PrettyPrinterContext *ppc = cls;
1819   char *ret;
1820
1821   if (hostname == NULL)
1822   {
1823     ppc->asc (ppc->asc_cls, NULL);
1824     GNUNET_free (ppc);
1825     return;
1826   }
1827   GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
1828   ppc->asc (ppc->asc_cls, ret);
1829   GNUNET_free (ret);
1830 }
1831
1832
1833 /**
1834  * Convert the transports address to a nice, human-readable
1835  * format.
1836  *
1837  * @param cls closure
1838  * @param type name of the transport that generated the address
1839  * @param addr one of the addresses of the host, NULL for the last address
1840  *        the specific address format depends on the transport
1841  * @param addrlen length of the address
1842  * @param numeric should (IP) addresses be displayed in numeric form?
1843  * @param timeout after how long should we give up?
1844  * @param asc function to call on each string
1845  * @param asc_cls closure for asc
1846  */
1847 static void
1848 udp_plugin_address_pretty_printer (void *cls, const char *type,
1849                                    const void *addr, size_t addrlen,
1850                                    int numeric,
1851                                    struct GNUNET_TIME_Relative timeout,
1852                                    GNUNET_TRANSPORT_AddressStringCallback asc,
1853                                    void *asc_cls)
1854 {
1855   struct PrettyPrinterContext *ppc;
1856   const void *sb;
1857   size_t sbs;
1858   struct sockaddr_in a4;
1859   struct sockaddr_in6 a6;
1860   const struct IPv4UdpAddress *u4;
1861   const struct IPv6UdpAddress *u6;
1862   uint16_t port;
1863
1864   if (addrlen == sizeof (struct IPv6UdpAddress))
1865   {
1866     u6 = addr;
1867     memset (&a6, 0, sizeof (a6));
1868     a6.sin6_family = AF_INET6;
1869 #if HAVE_SOCKADDR_IN_SIN_LEN
1870     a6.sin6_len = sizeof (a6);
1871 #endif
1872     a6.sin6_port = u6->u6_port;
1873     memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof (struct in6_addr));
1874     port = ntohs (u6->u6_port);
1875     sb = &a6;
1876     sbs = sizeof (a6);
1877   }
1878   else if (addrlen == sizeof (struct IPv4UdpAddress))
1879   {
1880     u4 = addr;
1881     memset (&a4, 0, sizeof (a4));
1882     a4.sin_family = AF_INET;
1883 #if HAVE_SOCKADDR_IN_SIN_LEN
1884     a4.sin_len = sizeof (a4);
1885 #endif
1886     a4.sin_port = u4->u4_port;
1887     a4.sin_addr.s_addr = u4->ipv4_addr;
1888     port = ntohs (u4->u4_port);
1889     sb = &a4;
1890     sbs = sizeof (a4);
1891   }
1892   else
1893   {
1894     /* invalid address */
1895     GNUNET_break_op (0);
1896     asc (asc_cls, NULL);
1897     return;
1898   }
1899   ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
1900   ppc->asc = asc;
1901   ppc->asc_cls = asc_cls;
1902   ppc->port = port;
1903   GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
1904 }
1905
1906
1907 /**
1908  * Our external IP address/port mapping has changed.
1909  *
1910  * @param cls closure, the 'struct LocalAddrList'
1911  * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean
1912  *     the previous (now invalid) one
1913  * @param addr either the previous or the new public IP address
1914  * @param addrlen actual lenght of the address
1915  */
1916 static void
1917 udp_nat_port_map_callback (void *cls, int add_remove,
1918                            const struct sockaddr *addr, socklen_t addrlen)
1919 {
1920   struct Plugin *plugin = cls;
1921   struct IPv4UdpAddress u4;
1922   struct IPv6UdpAddress u6;
1923   void *arg;
1924   size_t args;
1925
1926   /* convert 'addr' to our internal format */
1927   switch (addr->sa_family)
1928   {
1929   case AF_INET:
1930     GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
1931     u4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
1932     u4.u4_port = ((struct sockaddr_in *) addr)->sin_port;
1933     arg = &u4;
1934     args = sizeof (u4);
1935     break;
1936   case AF_INET6:
1937     GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
1938     memcpy (&u6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr,
1939             sizeof (struct in6_addr));
1940     u6.u6_port = ((struct sockaddr_in6 *) addr)->sin6_port;
1941     arg = &u6;
1942     args = sizeof (u6);
1943     break;
1944   default:
1945     GNUNET_break (0);
1946     return;
1947   }
1948   /* modify our published address list */
1949   plugin->env->notify_address (plugin->env->cls, add_remove, arg, args);
1950 }
1951
1952
1953 static int
1954 iface_proc (void *cls, const char *name,
1955             int isDefault,
1956             const struct sockaddr * addr,
1957             const struct sockaddr * broadcast_addr,
1958             const struct sockaddr * netmask,
1959             socklen_t addrlen)
1960 {
1961   struct Plugin *plugin = cls;
1962
1963   if (addr != NULL)
1964   {
1965     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address %s for interface %s %p\n ",
1966         GNUNET_a2s(addr,addrlen), name, addr);
1967     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "broadcast address %s for interface %s %p\n ",
1968         GNUNET_a2s(broadcast_addr,addrlen), name, broadcast_addr);
1969     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ",
1970         GNUNET_a2s(netmask,addrlen), name, netmask);
1971
1972     if (broadcast_addr != NULL)
1973     {
1974       struct BroadcastAddress * ba = GNUNET_malloc(sizeof (struct BroadcastAddress));
1975       ba->addr = GNUNET_malloc(addrlen);
1976       memcpy(ba->addr, broadcast_addr, addrlen);
1977       ba->addrlen = addrlen;
1978       GNUNET_CONTAINER_DLL_insert(plugin->ipv4_broadcast_head, plugin->ipv4_broadcast_tail, ba);
1979     }
1980   }
1981   return GNUNET_OK;
1982 }
1983
1984
1985 /**
1986  * The exported method. Makes the core api available via a global and
1987  * returns the udp transport API.
1988  *
1989  * @param cls our 'struct GNUNET_TRANSPORT_PluginEnvironment'
1990  * @return our 'struct GNUNET_TRANSPORT_PluginFunctions'
1991  */
1992 void *
1993 libgnunet_plugin_transport_udp_init (void *cls)
1994 {
1995   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
1996   unsigned long long port;
1997   unsigned long long aport;
1998   struct GNUNET_TRANSPORT_PluginFunctions *api;
1999   struct Plugin *plugin;
2000   int sockets_created;
2001   int broadcast;
2002   struct GNUNET_TIME_Relative interval;
2003   struct sockaddr_in serverAddrv4;
2004   struct sockaddr_in6 serverAddrv6;
2005   struct sockaddr *serverAddr;
2006   struct sockaddr *addrs[2];
2007   socklen_t addrlens[2];
2008   socklen_t addrlen;
2009   unsigned int tries;
2010   unsigned long long udp_max_bps;
2011
2012   if (GNUNET_OK !=
2013       GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", "PORT",
2014                                              &port))
2015     port = 2086;
2016
2017   broadcast =
2018       GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "transport-udp",
2019                                             "BROADCAST");
2020   if (broadcast == GNUNET_SYSERR)
2021     broadcast = GNUNET_NO;
2022
2023   if (GNUNET_SYSERR ==
2024       GNUNET_CONFIGURATION_get_value_time (env->cfg, "transport-udp",
2025                                            "BROADCAST_INTERVAL", &interval))
2026     interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10);
2027
2028   if (GNUNET_OK !=
2029       GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp",
2030                                              "MAX_BPS", &udp_max_bps))
2031     udp_max_bps = 1024 * 1024 * 50;     /* 50 MB/s == infinity for practical purposes */
2032   if (GNUNET_OK !=
2033       GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp",
2034                                              "ADVERTISED_PORT", &aport))
2035     aport = port;
2036   if (port > 65535)
2037   {
2038     LOG (GNUNET_ERROR_TYPE_WARNING,
2039          _("Given `%s' option is out of range: %llu > %u\n"), "PORT", port,
2040          65535);
2041     return NULL;
2042   }
2043   memset (&serverAddrv6, 0, sizeof (serverAddrv6));
2044   memset (&serverAddrv4, 0, sizeof (serverAddrv4));
2045
2046   plugin = GNUNET_malloc (sizeof (struct Plugin));
2047   GNUNET_BANDWIDTH_tracker_init (&plugin->tracker,
2048                                  GNUNET_BANDWIDTH_value_init ((uint32_t)
2049                                                               udp_max_bps), 30);
2050   plugin->last_expected_delay = GNUNET_TIME_UNIT_SECONDS;
2051   plugin->port = port;
2052   plugin->aport = aport;
2053   plugin->env = env;
2054   plugin->broadcast_interval = interval;
2055   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2056   api->cls = plugin;
2057
2058   api->send = &udp_plugin_send;
2059   api->disconnect = &udp_disconnect;
2060   api->address_pretty_printer = &udp_plugin_address_pretty_printer;
2061   api->address_to_string = &udp_address_to_string;
2062   api->check_address = &udp_plugin_check_address;
2063
2064   if (GNUNET_YES ==
2065       GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp",
2066                                              "BINDTO", &plugin->bind4_address))
2067   {
2068     LOG (GNUNET_ERROR_TYPE_DEBUG,
2069          "Binding udp plugin to specific address: `%s'\n",
2070          plugin->bind4_address);
2071     if (1 != inet_pton (AF_INET, plugin->bind4_address, &serverAddrv4.sin_addr))
2072     {
2073       GNUNET_free (plugin->bind4_address);
2074       GNUNET_free (plugin);
2075       GNUNET_free (api);
2076       return NULL;
2077     }
2078   }
2079
2080   if (GNUNET_YES ==
2081       GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp",
2082                                              "BINDTO6", &plugin->bind6_address))
2083   {
2084     LOG (GNUNET_ERROR_TYPE_DEBUG,
2085          "Binding udp plugin to specific address: `%s'\n",
2086          plugin->bind6_address);
2087     if (1 !=
2088         inet_pton (AF_INET6, plugin->bind6_address, &serverAddrv6.sin6_addr))
2089     {
2090       LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid IPv6 address: `%s'\n"),
2091            plugin->bind6_address);
2092       GNUNET_free_non_null (plugin->bind4_address);
2093       GNUNET_free (plugin->bind6_address);
2094       GNUNET_free (plugin);
2095       GNUNET_free (api);
2096       return NULL;
2097     }
2098   }
2099
2100   plugin->defrags =
2101       GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2102   plugin->sessions =
2103       GNUNET_CONTAINER_multihashmap_create (UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG
2104                                             * 2);
2105   plugin->inbound_sessions =
2106       GNUNET_CONTAINER_multihashmap_create (UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG
2107                                             * 2);
2108   sockets_created = 0;
2109   if ((GNUNET_YES !=
2110        GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "nat",
2111                                              "DISABLEV6")))
2112   {
2113     plugin->sockv6 = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0);
2114     if (NULL == plugin->sockv6)
2115     {
2116       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
2117     }
2118     else
2119     {
2120 #if HAVE_SOCKADDR_IN_SIN_LEN
2121       serverAddrv6.sin6_len = sizeof (serverAddrv6);
2122 #endif
2123       serverAddrv6.sin6_family = AF_INET6;
2124       serverAddrv6.sin6_addr = in6addr_any;
2125       serverAddrv6.sin6_port = htons (plugin->port);
2126       addrlen = sizeof (serverAddrv6);
2127       serverAddr = (struct sockaddr *) &serverAddrv6;
2128 #if DEBUG_UDP
2129       LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv6 port %d\n",
2130            ntohs (serverAddrv6.sin6_port));
2131 #endif
2132       tries = 0;
2133       while (GNUNET_NETWORK_socket_bind (plugin->sockv6, serverAddr, addrlen) !=
2134              GNUNET_OK)
2135       {
2136         serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);        /* Find a good, non-root port */
2137 #if DEBUG_UDP
2138         LOG (GNUNET_ERROR_TYPE_DEBUG,
2139              "IPv6 Binding failed, trying new port %d\n",
2140              ntohs (serverAddrv6.sin6_port));
2141 #endif
2142         tries++;
2143         if (tries > 10)
2144         {
2145           GNUNET_NETWORK_socket_close (plugin->sockv6);
2146           plugin->sockv6 = NULL;
2147           break;
2148         }
2149       }
2150       if (plugin->sockv6 != NULL)
2151       {
2152         addrs[sockets_created] = (struct sockaddr *) &serverAddrv6;
2153         addrlens[sockets_created] = sizeof (serverAddrv6);
2154         sockets_created++;
2155       }
2156     }
2157   }
2158
2159   plugin->mst =
2160       GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, plugin);
2161   plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
2162   if (NULL == plugin->sockv4)
2163   {
2164     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
2165   }
2166   else
2167   {
2168 #if HAVE_SOCKADDR_IN_SIN_LEN
2169     serverAddrv4.sin_len = sizeof (serverAddrv4);
2170 #endif
2171     serverAddrv4.sin_family = AF_INET;
2172     serverAddrv4.sin_addr.s_addr = INADDR_ANY;
2173     serverAddrv4.sin_port = htons (plugin->port);
2174     addrlen = sizeof (serverAddrv4);
2175     serverAddr = (struct sockaddr *) &serverAddrv4;
2176 #if DEBUG_UDP
2177     LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv4 port %d\n",
2178          ntohs (serverAddrv4.sin_port));
2179 #endif
2180     tries = 0;
2181     while (GNUNET_NETWORK_socket_bind (plugin->sockv4, serverAddr, addrlen) !=
2182            GNUNET_OK)
2183     {
2184       serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);   /* Find a good, non-root port */
2185 #if DEBUG_UDP
2186       LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv4 Binding failed, trying new port %d\n",
2187            ntohs (serverAddrv4.sin_port));
2188 #endif
2189       tries++;
2190       if (tries > 10)
2191       {
2192         GNUNET_NETWORK_socket_close (plugin->sockv4);
2193         plugin->sockv4 = NULL;
2194         break;
2195       }
2196     }
2197     if (plugin->sockv4 != NULL)
2198     {
2199       addrs[sockets_created] = (struct sockaddr *) &serverAddrv4;
2200       addrlens[sockets_created] = sizeof (serverAddrv4);
2201       sockets_created++;
2202     }
2203   }
2204
2205   plugin->rs = GNUNET_NETWORK_fdset_create ();
2206   GNUNET_NETWORK_fdset_zero (plugin->rs);
2207   if (NULL != plugin->sockv4)
2208     GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv4);
2209   if (NULL != plugin->sockv6)
2210     GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv6);
2211
2212   plugin->select_task =
2213       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
2214                                    GNUNET_SCHEDULER_NO_TASK,
2215                                    GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
2216                                    NULL, &udp_plugin_select, plugin);
2217
2218
2219
2220   if (broadcast)
2221   {
2222     /* create IPv4 broadcast socket */
2223     plugin->broadcast_ipv4 = GNUNET_NO;
2224       if (plugin->sockv4 != NULL)
2225       {
2226         int yes = 1;
2227
2228         if (GNUNET_NETWORK_socket_setsockopt
2229             (plugin->sockv4, SOL_SOCKET, SO_BROADCAST, &yes, sizeof (int)) != GNUNET_OK)
2230         {
2231           LOG (GNUNET_ERROR_TYPE_WARNING,
2232                _
2233                ("Failed to set IPv4 broadcast option for broadcast socket on port %d\n"),
2234                ntohs (serverAddrv4.sin_port));
2235         }
2236         else
2237         {
2238           GNUNET_OS_network_interfaces_list(iface_proc, plugin);
2239           plugin->send_ipv4_broadcast_task =
2240             GNUNET_SCHEDULER_add_now (&udp_ipv4_broadcast_send, plugin);
2241
2242           plugin->broadcast_ipv4_mst =
2243               GNUNET_SERVER_mst_create (broadcast_ipv4_mst_cb, plugin);
2244
2245           LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv4 Broadcasting running\n");
2246           plugin->broadcast_ipv4 = GNUNET_YES;
2247         }
2248       }
2249
2250       plugin->broadcast_ipv6 = GNUNET_NO;
2251       if (plugin->sockv6 != NULL)
2252       {
2253         memset (&plugin->ipv6_multicast_address, 0, sizeof (struct sockaddr_in6));
2254         GNUNET_assert (1 == inet_pton(AF_INET6, "ff02::1", &plugin->ipv6_multicast_address.sin6_addr));
2255
2256         plugin->ipv6_multicast_address.sin6_family = AF_INET6;
2257         plugin->ipv6_multicast_address.sin6_port = htons(plugin->port);
2258
2259         plugin->broadcast_ipv6_mst =
2260             GNUNET_SERVER_mst_create (broadcast_ipv6_mst_cb, plugin);
2261
2262         LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 Broadcasting running\n");
2263
2264
2265         plugin->send_ipv6_broadcast_task =
2266           GNUNET_SCHEDULER_add_now (&udp_ipv6_broadcast_send, plugin);
2267         plugin->broadcast_ipv6 = GNUNET_YES;
2268       }
2269   }
2270
2271   if (sockets_created == 0)
2272     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n"));
2273   plugin->nat =
2274       GNUNET_NAT_register (env->cfg, GNUNET_NO, port, sockets_created,
2275                            (const struct sockaddr **) addrs, addrlens,
2276                            &udp_nat_port_map_callback, NULL, plugin);
2277   return api;
2278   udp_ipv6_broadcast_send(NULL, NULL);
2279 }
2280
2281 /**
2282  * Shutdown the plugin.
2283  *
2284  * @param cls our 'struct GNUNET_TRANSPORT_PluginFunctions'
2285  * @return NULL
2286  */
2287 void *
2288 libgnunet_plugin_transport_udp_done (void *cls)
2289 {
2290   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2291   struct Plugin *plugin = api->cls;
2292   struct ReceiveContext *rc;
2293
2294   /* FIXME: clean up heap and hashmap */
2295   GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, &destroy_session,
2296                                          NULL);
2297   GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions);
2298   plugin->sessions = NULL;
2299   GNUNET_CONTAINER_multihashmap_iterate (plugin->inbound_sessions,
2300                                          &destroy_inbound_session, NULL);
2301   GNUNET_CONTAINER_multihashmap_destroy (plugin->inbound_sessions);
2302   plugin->inbound_sessions = NULL;
2303   while (NULL != (rc = GNUNET_CONTAINER_heap_remove_root (plugin->defrags)))
2304   {
2305     GNUNET_DEFRAGMENT_context_destroy (rc->defrag);
2306     GNUNET_free (rc);
2307   }
2308   GNUNET_CONTAINER_heap_destroy (plugin->defrags);
2309
2310   if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
2311   {
2312     GNUNET_SCHEDULER_cancel (plugin->select_task);
2313     plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
2314   }
2315   if (plugin->sockv4 != NULL)
2316   {
2317     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4));
2318     plugin->sockv4 = NULL;
2319   }
2320   if (plugin->sockv6 != NULL)
2321   {
2322     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv6));
2323     plugin->sockv6 = NULL;
2324   }
2325
2326   if (plugin->broadcast_ipv4)
2327   {
2328     if (plugin->send_ipv4_broadcast_task != GNUNET_SCHEDULER_NO_TASK)
2329     {
2330       GNUNET_SCHEDULER_cancel (plugin->send_ipv4_broadcast_task);
2331       plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
2332     }
2333
2334     if (plugin->broadcast_ipv4_mst != NULL)
2335       GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv4_mst);
2336
2337     while (plugin->ipv4_broadcast_head != NULL)
2338     {
2339       struct BroadcastAddress * p= plugin->ipv4_broadcast_head;
2340       GNUNET_CONTAINER_DLL_remove(plugin->ipv4_broadcast_head, plugin->ipv4_broadcast_tail, p);
2341       GNUNET_free (p->addr);
2342       GNUNET_free (p);
2343     }
2344   }
2345
2346   if (plugin->broadcast_ipv6)
2347   {
2348     if (plugin->send_ipv6_broadcast_task != GNUNET_SCHEDULER_NO_TASK)
2349     {
2350       GNUNET_SCHEDULER_cancel (plugin->send_ipv6_broadcast_task);
2351       plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
2352     }
2353
2354     if (plugin->broadcast_ipv6_mst != NULL)
2355       GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv6_mst);
2356   }
2357
2358   GNUNET_SERVER_mst_destroy (plugin->mst);
2359   GNUNET_NETWORK_fdset_destroy (plugin->rs);
2360
2361   GNUNET_NAT_unregister (plugin->nat);
2362   plugin->nat = NULL;
2363   GNUNET_free (plugin);
2364   GNUNET_free (api);
2365   return NULL;
2366 }
2367
2368 /* end of plugin_transport_udp.c */