(no commit message)
[oweals/gnunet.git] / src / transport / plugin_transport_udp.c
1 /*
2      This file is part of GNUnet
3      (C) 2010 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  * The idea with this transport is to connect gnunet peers to each other
29  * when ONE is behind a NAT.  This is based on pwnat (http://samy.pl/pwnat)
30  * created by Samy Kamkar.  When configured with the PWNAT options, this
31  * transport will start a server daemon which sends dummy ICMP and UDP
32  * messages out to a predefined address (typically 1.2.3.4).
33  *
34  * When a non-NAT'd peer (the client) learns of the NAT'd peer (the server)
35  * address, it will send ICMP RESPONSES to the NAT'd peers external address.
36  * The NAT box should forward these faked responses to the server, which
37  * can then connect directly to the non-NAT'd peer.
38  */
39
40 #include "platform.h"
41 #include "gnunet_hello_lib.h"
42 #include "gnunet_connection_lib.h"
43 #include "gnunet_container_lib.h"
44 #include "gnunet_os_lib.h"
45 #include "gnunet_peerinfo_service.h"
46 #include "gnunet_protocols.h"
47 #include "gnunet_resolver_service.h"
48 #include "gnunet_server_lib.h"
49 #include "gnunet_signatures.h"
50 #include "gnunet_statistics_service.h"
51 #include "gnunet_transport_service.h"
52 #include "gnunet_transport_plugin.h"
53 #include "transport.h"
54
55 #define DEBUG_UDP GNUNET_YES
56
57 #define MAX_PROBES 20
58
59 /*
60  * Transport cost to peer, always 1 for UDP (direct connection)
61  */
62 #define UDP_DIRECT_DISTANCE 1
63
64 #define DEFAULT_NAT_PORT 0
65
66 /**
67  * How long until we give up on transmitting the welcome message?
68  */
69 #define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
70
71 /**
72  * Starting port for listening and sending, eventually a config value
73  */
74 #define UDP_NAT_DEFAULT_PORT 22086
75
76 /**
77  * UDP Message-Packet header.
78  */
79 struct UDPMessage
80 {
81   /**
82    * Message header.
83    */
84   struct GNUNET_MessageHeader header;
85
86   /**
87    * What is the identity of the sender (GNUNET_hash of public key)
88    */
89   struct GNUNET_PeerIdentity sender;
90
91 };
92
93 /**
94  * Network format for IPv4 addresses.
95  */
96 struct IPv4UdpAddress
97 {
98   /**
99    * IPv4 address, in network byte order.
100    */
101   uint32_t ipv4_addr GNUNET_PACKED;
102
103   /**
104    * Port number, in network byte order.
105    */
106   uint16_t u_port GNUNET_PACKED;
107 };
108
109
110 /**
111  * Network format for IPv6 addresses.
112  */
113 struct IPv6UdpAddress
114 {
115   /**
116    * IPv6 address.
117    */
118   struct in6_addr ipv6_addr GNUNET_PACKED;
119
120   /**
121    * Port number, in network byte order.
122    */
123   uint16_t u6_port GNUNET_PACKED;
124 };
125
126 /* Forward definition */
127 struct Plugin;
128
129 struct PrettyPrinterContext
130 {
131   GNUNET_TRANSPORT_AddressStringCallback asc;
132   void *asc_cls;
133   uint16_t port;
134 };
135
136 struct MessageQueue
137 {
138   /**
139    * Linked List
140    */
141   struct MessageQueue *next;
142
143   /**
144    * Session this message belongs to
145    */
146   struct PeerSession *session;
147
148   /**
149    * Actual message to be sent
150    */
151   char *msgbuf;
152
153   /**
154    * Size of message buffer to be sent
155    */
156   size_t msgbuf_size;
157
158   /**
159    * When to discard this message
160    */
161   struct GNUNET_TIME_Absolute timeout;
162
163   /**
164    * Continuation to call when this message goes out
165    */
166   GNUNET_TRANSPORT_TransmitContinuation cont;
167
168   /**
169    * closure for continuation
170    */
171   void *cont_cls;
172
173 };
174
175 /**
176  * UDP NAT Probe message definition
177  */
178 struct UDP_NAT_ProbeMessage
179 {
180   /**
181    * Message header
182    */
183   struct GNUNET_MessageHeader header;
184
185 };
186
187 /**
188  * UDP NAT Probe message reply definition
189  */
190 struct UDP_NAT_ProbeMessageReply
191 {
192   /**
193    * Message header
194    */
195   struct GNUNET_MessageHeader header;
196
197 };
198
199
200 /**
201  * UDP NAT Probe message confirm definition
202  */
203 struct UDP_NAT_ProbeMessageConfirmation
204 {
205   /**
206    * Message header
207    */
208   struct GNUNET_MessageHeader header;
209
210 };
211
212
213 /**
214  * Local network addresses (actual IP address follows this struct).
215  * PORT is NOT included!
216  */
217 struct LocalAddrList
218 {
219
220   /**
221    * This is a doubly linked list.
222    */
223   struct LocalAddrList *next;
224
225   /**
226    * This is a doubly linked list.
227    */
228   struct LocalAddrList *prev;
229
230   /**
231    * Number of bytes of the address that follow
232    */
233   size_t size;
234
235 };
236
237
238 /**
239  * UDP NAT "Session"
240  */
241 struct PeerSession
242 {
243
244   /**
245    * Stored in a linked list.
246    */
247   struct PeerSession *next;
248
249   /**
250    * Pointer to the global plugin struct.
251    */
252   struct Plugin *plugin;
253
254   /**
255    * To whom are we talking to (set to our identity
256    * if we are still waiting for the welcome message)
257    */
258   struct GNUNET_PeerIdentity target;
259
260   /**
261    * Address of the other peer (either based on our 'connect'
262    * call or on our 'accept' call).
263    */
264   void *connect_addr;
265
266   /**
267    * Length of connect_addr.
268    */
269   size_t connect_alen;
270
271   /**
272    * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO)
273    */
274   int expecting_welcome;
275
276   /**
277    * From which socket do we need to send to this peer?
278    */
279   struct GNUNET_NETWORK_Handle *sock;
280
281   /*
282    * Queue of messages for this peer, in the case that
283    * we have to await a connection...
284    */
285   struct MessageQueue *messages;
286
287 };
288
289 struct UDP_NAT_Probes
290 {
291
292   /**
293    * Linked list
294    */
295   struct UDP_NAT_Probes *next;
296
297   /**
298    * Address string that the server process returned to us
299    */
300   char *address_string;
301
302   /**
303    * Timeout for this set of probes
304    */
305   struct GNUNET_TIME_Absolute timeout;
306
307   /**
308    * Count of how many probes we've attempted
309    */
310   int count;
311
312   /**
313    * The plugin this probe belongs to
314    */
315   struct Plugin *plugin;
316
317   /**
318    * The task used to send these probes
319    */
320   GNUNET_SCHEDULER_TaskIdentifier task;
321
322   /**
323    * Network address (always ipv4!)
324    */
325   struct IPv4UdpAddress addr;
326
327 };
328
329
330 /**
331  * Information we keep for each of our listen sockets.
332  */
333 struct UDP_Sock_Info
334 {
335   /**
336    * The network handle
337    */
338   struct GNUNET_NETWORK_Handle *desc;
339
340   /**
341    * The port we bound to
342    */
343   uint16_t port;
344 };
345
346
347 /**
348  * Encapsulation of all of the state of the plugin.
349  */
350 struct Plugin
351 {
352   /**
353    * Our environment.
354    */
355   struct GNUNET_TRANSPORT_PluginEnvironment *env;
356
357   /*
358    * Session of peers with whom we are currently connected
359    */
360   struct PeerSession *sessions;
361
362   /**
363    * Handle for request of hostname resolution, non-NULL if pending.
364    */
365   struct GNUNET_RESOLVER_RequestHandle *hostname_dns;
366
367   /**
368    * ID of task used to update our addresses when one expires.
369    */
370   GNUNET_SCHEDULER_TaskIdentifier address_update_task;
371
372   /**
373    * ID of select task
374    */
375   GNUNET_SCHEDULER_TaskIdentifier select_task;
376
377   /**
378    * Port to listen on.
379    */
380   uint16_t port;
381
382   /**
383    * The external address given to us by the user.  Must be actual
384    * outside visible address for NAT punching to work.
385    */
386   char *external_address;
387
388   /**
389    * The internal address given to us by the user (or discovered).
390    */
391   char *internal_address;
392
393   /**
394    * Address we were told to bind to exclusively (IPv4).
395    */
396   char *bind_address;
397
398   /**
399    * Address we were told to bind to exclusively (IPv6).
400    */
401   char *bind6_address;
402
403   /**
404    * List of our IP addresses.
405    */
406   struct LocalAddrList *lal_head;
407
408   /**
409    * Tail of our IP address list.
410    */
411   struct LocalAddrList *lal_tail;
412
413   /**
414    * FD Read set
415    */
416   struct GNUNET_NETWORK_FDSet *rs;
417
418   /**
419    * stdout pipe handle for the gnunet-nat-server process
420    */
421   struct GNUNET_DISK_PipeHandle *server_stdout;
422
423   /**
424    * stdout file handle (for reading) for the gnunet-nat-server process
425    */
426   const struct GNUNET_DISK_FileHandle *server_stdout_handle;
427
428   /**
429    * Probes in flight
430    */
431   struct UDP_NAT_Probes *probes;
432
433   /**
434    * socket that we transmit all IPv4 data with
435    */
436   struct UDP_Sock_Info udp_sockv4;
437
438   /**
439    * socket that we transmit all IPv6 data with
440    */
441   struct UDP_Sock_Info udp_sockv6;
442
443   /**
444    * ID of select gnunet-nat-server stdout read task
445    */
446   GNUNET_SCHEDULER_TaskIdentifier server_read_task;
447
448   /**
449    * Is this transport configured to be behind a NAT?
450    */
451   int behind_nat;
452
453   /**
454    * Is this transport configured to allow connections to NAT'd peers?
455    */
456   int allow_nat;
457
458   /**
459    * Should this transport advertise only NAT addresses (port set to 0)?
460    * If not, all addresses will be duplicated for NAT punching and regular
461    * ports.
462    */
463   int only_nat_addresses;
464
465   /**
466    * The process id of the server process (if behind NAT)
467    */
468   struct GNUNET_OS_Process *server_proc;
469
470 };
471
472
473 /**
474  * Forward declaration.
475  */
476 void
477 udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result);
478
479
480 /**
481  * Disconnect from a remote node.  Clean up session if we have one for this peer
482  *
483  * @param cls closure for this call (should be handle to Plugin)
484  * @param target the peeridentity of the peer to disconnect
485  * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
486  */
487 void
488 udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
489 {
490   /** TODO: Implement! */
491   return;
492 }
493
494 /**
495  * Shutdown the server process (stop receiving inbound traffic). Maybe
496  * restarted later!
497  *
498  * @param cls Handle to the plugin for this transport
499  *
500  * @return returns the number of sockets successfully closed,
501  *         should equal the number of sockets successfully opened
502  */
503 static int
504 udp_transport_server_stop (void *cls)
505 {
506   struct Plugin *plugin = cls;
507
508   if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
509     {
510       GNUNET_SCHEDULER_cancel (plugin->select_task);
511       plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
512     }
513   if (plugin->udp_sockv4.desc != NULL)
514     {
515       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc));
516       plugin->udp_sockv4.desc = NULL;
517     }
518   if (plugin->udp_sockv6.desc != NULL)
519     {
520       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc));
521       plugin->udp_sockv6.desc = NULL;
522     }
523   if (plugin->behind_nat == GNUNET_YES)
524     {
525       if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM))
526         GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
527       GNUNET_OS_process_wait (plugin->server_proc);
528       GNUNET_OS_process_close (plugin->server_proc);
529       plugin->server_proc = NULL;
530     }
531   return GNUNET_OK;
532 }
533
534
535 struct PeerSession *
536 find_session (struct Plugin *plugin,
537               const struct GNUNET_PeerIdentity *peer)
538 {
539   struct PeerSession *pos;
540
541   pos = plugin->sessions;
542   while (pos != NULL)
543     {
544       if (memcmp(&pos->target, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
545         return pos;
546       pos = pos->next;
547     }
548
549   return pos;
550 }
551
552
553 /**
554  * Actually send out the message, assume we've got the address and
555  * send_handle squared away!
556  *
557  * @param cls closure
558  * @param send_handle which handle to send message on
559  * @param target who should receive this message (ignored by UDP)
560  * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
561  * @param msgbuf_size the size of the msgbuf to send
562  * @param priority how important is the message (ignored by UDP)
563  * @param timeout when should we time out (give up) if we can not transmit?
564  * @param addr the addr to send the message to, needs to be a sockaddr for us
565  * @param addrlen the len of addr
566  * @param cont continuation to call once the message has
567  *        been transmitted (or if the transport is ready
568  *        for the next transmission call; or if the
569  *        peer disconnected...)
570  * @param cont_cls closure for cont
571  * @return the number of bytes written
572  */
573 static ssize_t
574 udp_real_send (void *cls,
575                struct GNUNET_NETWORK_Handle *send_handle,
576                const struct GNUNET_PeerIdentity *target,
577                const char *msgbuf,
578                size_t msgbuf_size,
579                unsigned int priority,
580                struct GNUNET_TIME_Relative timeout,
581                const void *addr,
582                size_t addrlen,
583                GNUNET_TRANSPORT_TransmitContinuation cont,
584                void *cont_cls)
585 {
586   struct Plugin *plugin = cls;
587   struct UDPMessage *message;
588   int ssize;
589   ssize_t sent;
590   struct sockaddr_in a4;
591   struct sockaddr_in6 a6;
592   const struct IPv4UdpAddress *t4;
593   const struct IPv6UdpAddress *t6;
594   const void *sb;
595   size_t sbs;
596
597   if (send_handle == NULL)
598     {
599       /* failed to open send socket for AF */
600       if (cont != NULL)
601         cont (cont_cls, target, GNUNET_SYSERR);
602       return 0;
603     }
604   if ((addr == NULL) || (addrlen == 0))
605     {
606 #if DEBUG_UDP
607       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
608                        "udp_real_send called without address, returning!\n");
609 #endif
610       if (cont != NULL)
611         cont (cont_cls, target, GNUNET_SYSERR);
612       return 0; /* Can never send if we don't have an address!! */
613     }
614
615   /* Build the message to be sent */
616   message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size);
617   ssize = sizeof (struct UDPMessage) + msgbuf_size;
618
619   message->header.size = htons (ssize);
620   message->header.type = htons (0);
621   memcpy (&message->sender, plugin->env->my_identity,
622           sizeof (struct GNUNET_PeerIdentity));
623   memcpy (&message[1], msgbuf, msgbuf_size);
624
625   if (addrlen == sizeof (struct IPv6UdpAddress))
626     {
627       t6 = addr;
628       memset (&a6, 0, sizeof (a6));
629 #if HAVE_SOCKADDR_IN_SIN_LEN
630       a6.sin6_len = sizeof (a6);
631 #endif
632       a6.sin6_family = AF_INET6;
633       a6.sin6_port = t6->u6_port;
634       memcpy (&a6.sin6_addr,
635               &t6->ipv6_addr,
636               sizeof (struct in6_addr));
637       sb = &a6;
638       sbs = sizeof (a6);
639     }
640   else if (addrlen == sizeof (struct IPv4UdpAddress))
641     {
642       t4 = addr;
643       memset (&a4, 0, sizeof (a4));
644 #if HAVE_SOCKADDR_IN_SIN_LEN
645       a4.sin_len = sizeof (a4);
646 #endif
647       a4.sin_family = AF_INET;
648       a4.sin_port = t4->u_port;
649       a4.sin_addr.s_addr = t4->ipv4_addr;
650       sb = &a4;
651       sbs = sizeof (a4);
652     }
653   else
654     {
655       GNUNET_break_op (0);
656       GNUNET_free (message);
657       return -1;
658     }
659
660   /* Actually send the message */
661   sent =
662     GNUNET_NETWORK_socket_sendto (send_handle, message, ssize,
663                                   sb,
664                                   sbs);
665   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
666               "UDP transmit %u-byte message to %s (%d: %s)\n",
667               (unsigned int) ssize,
668               GNUNET_a2s (sb, sbs),
669               (int) sent,
670               (sent < 0) ? STRERROR (errno) : "ok");
671   if (cont != NULL)
672     {
673       if (sent == GNUNET_SYSERR)
674         cont (cont_cls, target, GNUNET_SYSERR);
675       else
676         {
677           cont (cont_cls, target, GNUNET_OK);
678         }
679     }
680
681   GNUNET_free (message);
682   return sent;
683 }
684
685 /**
686  * We learned about a peer (possibly behind NAT) so run the
687  * gnunet-nat-client to send dummy ICMP responses
688  *
689  * @param plugin the plugin for this transport
690  * @param addr the address of the peer
691  * @param addrlen the length of the address
692  */
693 void
694 run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen)
695 {
696   char addr_buf[INET_ADDRSTRLEN];
697   char *address_as_string;
698   char *port_as_string;
699   struct GNUNET_OS_Process *proc;
700   const struct IPv4UdpAddress *t4;
701
702   GNUNET_assert(addrlen == sizeof(struct IPv4UdpAddress));
703   t4 = (struct IPv4UdpAddress *)addr;
704
705   if (NULL == inet_ntop (AF_INET,
706                          &t4->ipv4_addr,
707                          addr_buf, INET_ADDRSTRLEN))
708     {
709       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
710       return;
711     }
712   address_as_string = GNUNET_strdup (addr_buf);
713   GNUNET_asprintf(&port_as_string, "%d", plugin->port);
714 #if DEBUG_UDP
715   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
716                   _("Running gnunet-nat-client with arguments: %s %s %d\n"), plugin->external_address, address_as_string, plugin->port);
717 #endif
718
719   /* Start the server process */
720   proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
721   GNUNET_free(address_as_string);
722   GNUNET_free(port_as_string);
723   if (proc != NULL)
724     {
725       GNUNET_OS_process_wait (proc);
726       GNUNET_OS_process_close (proc);
727       proc = NULL;
728     }
729 }
730
731 /**
732  * Function that can be used by the transport service to transmit
733  * a message using the plugin.
734  *
735  * @param cls closure
736  * @param target who should receive this message (ignored by UDP)
737  * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
738  * @param msgbuf_size the size of the msgbuf to send
739  * @param priority how important is the message (ignored by UDP)
740  * @param timeout when should we time out (give up) if we can not transmit?
741  * @param session identifier used for this session (can be NULL)
742  * @param addr the addr to send the message to, needs to be a sockaddr for us
743  * @param addrlen the len of addr
744  * @param force_address not used, we had better have an address to send to
745  *        because we are stateless!!
746  * @param cont continuation to call once the message has
747  *        been transmitted (or if the transport is ready
748  *        for the next transmission call; or if the
749  *        peer disconnected...)
750  * @param cont_cls closure for cont
751  *
752  * @return the number of bytes written (may return 0 and the message can
753  *         still be transmitted later!)
754  */
755 static ssize_t
756 udp_plugin_send (void *cls,
757                      const struct GNUNET_PeerIdentity *target,
758                      const char *msgbuf,
759                      size_t msgbuf_size,
760                      unsigned int priority,
761                      struct GNUNET_TIME_Relative timeout,
762                      struct Session *session,
763                      const void *addr,
764                      size_t addrlen,
765                      int force_address,
766                      GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
767 {
768   struct Plugin *plugin = cls;
769   ssize_t sent;
770   struct MessageQueue *temp_message;
771   struct PeerSession *peer_session;
772   int other_peer_natd;
773   const struct IPv4UdpAddress *t4;
774
775   if (force_address == GNUNET_SYSERR)
776     return GNUNET_SYSERR;
777   GNUNET_assert (NULL == session);
778
779   other_peer_natd = GNUNET_NO;
780   if (addrlen == sizeof(struct IPv4UdpAddress))
781     {
782       t4 = addr;
783       if (ntohs(t4->u_port) == 0)
784         other_peer_natd = GNUNET_YES;
785     }
786   else if (addrlen != sizeof(struct IPv6UdpAddress))
787     {
788       GNUNET_break_op(0);
789       return -1; /* Must have an address to send to */
790     }
791
792   sent = 0;
793   if ((other_peer_natd == GNUNET_YES) && (plugin->allow_nat == GNUNET_YES))
794     {
795       peer_session = find_session(plugin, target);
796       if (peer_session == NULL) /* We have a new peer to add */
797         {
798           /*
799            * The first time, we can assume we have no knowledge of a
800            * working port for this peer, call the ICMP/UDP message sender
801            * and wait...
802            */
803           peer_session = GNUNET_malloc(sizeof(struct PeerSession));
804           peer_session->connect_addr = GNUNET_malloc(addrlen);
805           memcpy(peer_session->connect_addr, addr, addrlen);
806           peer_session->connect_alen = addrlen;
807           peer_session->plugin = plugin;
808           peer_session->sock = NULL;
809           memcpy(&peer_session->target, target, sizeof(struct GNUNET_PeerIdentity));
810           peer_session->expecting_welcome = GNUNET_YES;
811
812           peer_session->next = plugin->sessions;
813           plugin->sessions = peer_session;
814
815           peer_session->messages = GNUNET_malloc(sizeof(struct MessageQueue));
816           peer_session->messages->msgbuf = GNUNET_malloc(msgbuf_size);
817           memcpy(peer_session->messages->msgbuf, msgbuf, msgbuf_size);
818           peer_session->messages->msgbuf_size = msgbuf_size;
819           peer_session->messages->timeout = GNUNET_TIME_relative_to_absolute(timeout);
820           peer_session->messages->cont = cont;
821           peer_session->messages->cont_cls = cont_cls;
822 #if DEBUG_UDP
823           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
824                           _("Other peer is NAT'd, set up peer session for peer %s\n"), GNUNET_i2s(target));
825 #endif
826           run_gnunet_nat_client(plugin, addr, addrlen);
827         }
828       else
829         {
830           if (peer_session->expecting_welcome == GNUNET_NO) /* We are "connected" */
831             {
832               sent = udp_real_send(cls,
833                                    peer_session->sock,
834                                    target,
835                                    msgbuf, msgbuf_size,
836                                    priority, timeout,
837                                    peer_session->connect_addr, peer_session->connect_alen,
838                                    cont, cont_cls);
839             }
840           else /* Haven't gotten a response from this peer, queue message */
841             {
842               temp_message = GNUNET_malloc(sizeof(struct MessageQueue));
843               temp_message->msgbuf = GNUNET_malloc(msgbuf_size);
844               memcpy(temp_message->msgbuf, msgbuf, msgbuf_size);
845               temp_message->msgbuf_size = msgbuf_size;
846               temp_message->timeout = GNUNET_TIME_relative_to_absolute(timeout);
847               temp_message->cont = cont;
848               temp_message->cont_cls = cont_cls;
849               temp_message->next = peer_session->messages;
850               peer_session->messages = temp_message;
851             }
852         }
853     }
854   else if (other_peer_natd == GNUNET_NO) /* Other peer not behind a NAT, so we can just send the message as is */
855     {
856       sent = udp_real_send(cls,
857                            (addrlen == sizeof (struct IPv4UdpAddress)) ? plugin->udp_sockv4.desc : plugin->udp_sockv6.desc,
858                            target,
859                            msgbuf, msgbuf_size,
860                            priority, timeout, addr, addrlen,
861                            cont, cont_cls);
862     }
863   else /* Other peer is NAT'd, but we don't want to play with them (or can't!) */
864     {
865       return GNUNET_SYSERR;
866     }
867
868   /* When GNUNET_SYSERR is returned from udp_real_send, we will still call
869    * the callback so must not return GNUNET_SYSERR!
870    * If we did, then transport context would get freed twice. */
871   if (sent == GNUNET_SYSERR)
872     return 0;
873   return sent;
874 }
875
876
877 static void
878 add_to_address_list (struct Plugin *plugin,
879                      const void *arg,
880                      size_t arg_size)
881 {
882   struct LocalAddrList *lal;
883
884   lal = plugin->lal_head;
885   while (NULL != lal)
886     {
887       if ( (lal->size == arg_size) &&
888            (0 == memcmp (&lal[1], arg, arg_size)) )
889         return;
890       lal = lal->next;
891     }
892   lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size);
893   lal->size = arg_size;
894   memcpy (&lal[1], arg, arg_size);
895   GNUNET_CONTAINER_DLL_insert (plugin->lal_head,
896                                plugin->lal_tail,
897                                lal);
898 }
899
900
901 static int
902 check_local_addr (struct Plugin *plugin,
903                   const void *arg,
904                   size_t arg_size)
905 {
906   struct LocalAddrList *lal;
907
908   lal = plugin->lal_head;
909   while (NULL != lal)
910     {
911       if ( (lal->size == arg_size) &&
912            (0 == memcmp (&lal[1], arg, arg_size)) )
913         return GNUNET_OK;
914       lal = lal->next;
915     }
916   return GNUNET_SYSERR;
917 }
918
919
920 /**
921  * Add the IP of our network interface to the list of
922  * our external IP addresses.
923  */
924 static int
925 process_interfaces (void *cls,
926                     const char *name,
927                     int isDefault,
928                     const struct sockaddr *addr, socklen_t addrlen)
929 {
930   struct Plugin *plugin = cls;
931   int af;
932   struct IPv4UdpAddress t4;
933   struct IPv6UdpAddress t6;
934   void *arg;
935   uint16_t args;
936   void *addr_nat;
937   char buf[INET6_ADDRSTRLEN];
938
939   addr_nat = NULL;
940   af = addr->sa_family;
941
942   memset(buf, 0, INET6_ADDRSTRLEN);
943   if (af == AF_INET)
944     {
945       t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
946       GNUNET_assert(NULL != inet_ntop(AF_INET, &t4.ipv4_addr, &buf[0], INET_ADDRSTRLEN));
947       if ((plugin->bind6_address != NULL) || ((plugin->bind_address != NULL) && (0 != strcmp(buf, plugin->bind_address))))
948         {
949           GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Not notifying transport of address %s\n", "UDP", GNUNET_a2s (addr, addrlen));
950           return GNUNET_OK;
951         }
952       add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t));
953       if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
954         {
955           t4.u_port = htons (DEFAULT_NAT_PORT);
956         }
957       else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */
958         {
959           addr_nat = GNUNET_malloc(sizeof(t4));
960           t4.u_port = htons (DEFAULT_NAT_PORT);
961           memcpy(addr_nat, &t4, sizeof(t4));
962           t4.u_port = plugin->port;
963         }
964       else
965         {
966           t4.u_port = htons(plugin->port);
967         }
968       arg = &t4;
969       args = sizeof (t4);
970     }
971   else if (af == AF_INET6)
972     {
973       if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
974         {
975           /* skip link local addresses */
976           return GNUNET_OK;
977         }
978       memcpy (&t6.ipv6_addr,
979               &((struct sockaddr_in6 *) addr)->sin6_addr,
980               sizeof (struct in6_addr));
981       GNUNET_assert(NULL != inet_ntop(AF_INET6, &t6.ipv6_addr, &buf[0], INET6_ADDRSTRLEN));
982       if (((plugin->bind_address != NULL) && (0 != strcmp(buf, plugin->bind_address)))
983           || ((plugin->bind6_address != NULL) && (0 != strcmp(buf, plugin->bind6_address))))
984         {
985           GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Not notifying transport of address %s\n", "UDP", GNUNET_a2s (addr, addrlen));
986           return GNUNET_OK;
987         }
988       add_to_address_list (plugin, &t6.ipv6_addr, sizeof (struct in6_addr));
989       if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
990         {
991           t6.u6_port = htons (DEFAULT_NAT_PORT);
992         }
993       else if (plugin->behind_nat == GNUNET_YES)
994         {
995           addr_nat = GNUNET_malloc(sizeof(t6));
996           t6.u6_port = htons (DEFAULT_NAT_PORT);
997           memcpy(addr_nat, &t6, sizeof(t6));
998           t6.u6_port = plugin->port;
999         }
1000       else
1001         {
1002           t6.u6_port = htons (plugin->port);
1003         }
1004
1005       arg = &t6;
1006       args = sizeof (t6);
1007     }
1008   else
1009     {
1010       GNUNET_break (0);
1011       return GNUNET_OK;
1012     }
1013
1014   GNUNET_log (GNUNET_ERROR_TYPE_INFO |
1015               GNUNET_ERROR_TYPE_BULK,
1016               _("Found address `%s' (%s)\n"),
1017               GNUNET_a2s (addr, addrlen), name);
1018
1019   if (addr_nat != NULL)
1020     {
1021       plugin->env->notify_address (plugin->env->cls,
1022                                    "udp",
1023                                    addr_nat, args, GNUNET_TIME_UNIT_FOREVER_REL);
1024       GNUNET_log (GNUNET_ERROR_TYPE_INFO |
1025                   GNUNET_ERROR_TYPE_BULK,
1026                   _("Found NAT address `%s' (%s)\n"),
1027                   GNUNET_a2s (addr_nat, args), name);
1028       GNUNET_free(addr_nat);
1029     }
1030
1031   plugin->env->notify_address (plugin->env->cls,
1032                                "udp",
1033                                arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
1034   return GNUNET_OK;
1035 }
1036
1037
1038 /**
1039  * Function called by the resolver for each address obtained from DNS
1040  * for our own hostname.  Add the addresses to the list of our
1041  * external IP addresses.
1042  *
1043  * @param cls closure
1044  * @param addr one of the addresses of the host, NULL for the last address
1045  * @param addrlen length of the address
1046  */
1047 static void
1048 process_hostname_ips (void *cls,
1049                       const struct sockaddr *addr, socklen_t addrlen)
1050 {
1051   struct Plugin *plugin = cls;
1052
1053   if (addr == NULL)
1054     {
1055       plugin->hostname_dns = NULL;
1056       return;
1057     }
1058   process_interfaces (plugin, "<hostname>", GNUNET_YES, addr, addrlen);
1059 }
1060
1061
1062 /**
1063  * Send UDP probe messages or UDP keepalive messages, depending on the
1064  * state of the connection.
1065  *
1066  * @param cls closure for this call (should be the main Plugin)
1067  * @param tc task context for running this
1068  */
1069 static void
1070 send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1071 {
1072   struct UDP_NAT_Probes *probe = cls;
1073   struct UDP_NAT_ProbeMessage message;
1074   struct Plugin *plugin = probe->plugin;
1075
1076   memset (&message, 0, sizeof (message));
1077   message.header.size = htons(sizeof(struct UDP_NAT_ProbeMessage));
1078   message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE);
1079   /* If they gave us a port, use that.  If not, try our port. */
1080   if (ntohs(probe->addr.u_port) == 0)
1081     probe->addr.u_port = htons(plugin->port);
1082
1083 #if DEBUG_UDP
1084       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1085                       _("Sending a probe to port %d\n"), ntohs(probe->addr.u_port));
1086 #endif
1087   probe->count++;
1088   udp_real_send(plugin,
1089                 plugin->udp_sockv4.desc,
1090                 NULL,
1091                 (char *)&message, ntohs(message.header.size), 0,
1092                 GNUNET_TIME_relative_get_unit(),
1093                 &probe->addr, sizeof(struct IPv4UdpAddress),
1094                 &udp_probe_continuation, probe);
1095 }
1096
1097
1098 /**
1099  * Continuation for probe sends.  If the last probe was sent
1100  * "successfully", schedule sending of another one.  If not,
1101  *
1102  */
1103 void
1104 udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result)
1105 {
1106   struct UDP_NAT_Probes *probe = cls;
1107   /*struct Plugin *plugin = probe->plugin;*/
1108
1109   if ((result == GNUNET_OK) && (probe->count < MAX_PROBES))
1110     {
1111 #if DEBUG_UDP
1112       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1113                        _("Scheduling next probe for 10000 milliseconds\n"));
1114 #endif
1115       probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 10000), &send_udp_probe_message, probe);
1116     }
1117   else /* Destroy the probe context. */
1118     {
1119 #if DEBUG_UDP
1120       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1121                       _("Sending probe didn't go well...\n"));
1122 #endif
1123     }
1124 }
1125
1126 /**
1127  * Find probe message by address
1128  *
1129  * @param plugin the plugin for this transport
1130  * @param address_string the ip address as a string
1131  */
1132 struct UDP_NAT_Probes *
1133 find_probe(struct Plugin *plugin, char * address_string)
1134 {
1135   struct UDP_NAT_Probes *pos;
1136
1137   pos = plugin->probes;
1138   while (pos != NULL)
1139     if (strcmp(pos->address_string, address_string) == 0)
1140       return pos;
1141
1142   return pos;
1143 }
1144
1145
1146 /*
1147  * @param cls the plugin handle
1148  * @param tc the scheduling context (for rescheduling this function again)
1149  *
1150  * We have been notified that gnunet-nat-server has written something to stdout.
1151  * Handle the output, then reschedule this function to be called again once
1152  * more is available.
1153  *
1154  */
1155 static void
1156 udp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1157 {
1158   struct Plugin *plugin = cls;
1159   char mybuf[40];
1160   ssize_t bytes;
1161   memset(&mybuf, 0, sizeof(mybuf));
1162   int i;
1163   struct UDP_NAT_Probes *temp_probe;
1164   int port;
1165   char *port_start;
1166   struct IPv4UdpAddress a4;
1167
1168   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1169     return;
1170
1171   bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, &mybuf, sizeof(mybuf));
1172
1173   if (bytes < 1)
1174     {
1175 #if DEBUG_UDP
1176       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1177                       _("Finished reading from server stdout with code: %d\n"), bytes);
1178 #endif
1179       return;
1180     }
1181
1182   port_start = NULL;
1183   for (i = 0; i < sizeof(mybuf); i++)
1184     {
1185       if (mybuf[i] == '\n')
1186         mybuf[i] = '\0';
1187
1188       if ((mybuf[i] == ':') && (i + 1 < sizeof(mybuf)))
1189         {
1190           mybuf[i] = '\0';
1191           port_start = &mybuf[i + 1];
1192         }
1193     }
1194
1195   if (port_start != NULL)
1196     port = atoi(port_start);
1197   else
1198     {
1199       plugin->server_read_task =
1200            GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1201                                            plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1202       return;
1203     }
1204
1205 #if DEBUG_UDP
1206   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1207                   _("nat-server-read read: %s port %d\n"), &mybuf, port);
1208 #endif
1209
1210   /**
1211    * We have received an ICMP response, ostensibly from a non-NAT'd peer
1212    *  that wants to connect to us! Send a message to establish a connection.
1213    */
1214   if (inet_pton(AF_INET, &mybuf[0], &a4.ipv4_addr) != 1)
1215     {
1216
1217       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1218                   _("nat-server-read malformed address\n"), &mybuf, port);
1219
1220       plugin->server_read_task =
1221           GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1222                                           plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1223       return;
1224     }
1225
1226   temp_probe = find_probe(plugin, &mybuf[0]);
1227
1228   if (temp_probe == NULL)
1229     {
1230       temp_probe = GNUNET_malloc(sizeof(struct UDP_NAT_Probes));
1231       temp_probe->address_string = strdup(&mybuf[0]);
1232       GNUNET_assert (1 == inet_pton(AF_INET, &mybuf[0], &temp_probe->addr.ipv4_addr));
1233       temp_probe->addr.u_port = htons(port);
1234       temp_probe->next = plugin->probes;
1235       temp_probe->plugin = plugin;
1236       temp_probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500), &send_udp_probe_message, temp_probe);
1237       plugin->probes = temp_probe;
1238     }
1239
1240   plugin->server_read_task =
1241        GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1242                                        plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1243
1244 }
1245
1246
1247 /**
1248  * Demultiplexer for UDP NAT messages
1249  *
1250  * @param plugin the main plugin for this transport
1251  * @param sender from which peer the message was received
1252  * @param currhdr pointer to the header of the message
1253  * @param sender_addr the address from which the message was received
1254  * @param fromlen the length of the address
1255  * @param sockinfo which socket did we receive the message on
1256  */
1257 static void
1258 udp_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
1259                   const struct GNUNET_MessageHeader *currhdr,
1260                   const void *sender_addr,
1261                   size_t fromlen, struct UDP_Sock_Info *sockinfo)
1262 {
1263   struct UDP_NAT_ProbeMessageReply *outgoing_probe_reply;
1264   struct UDP_NAT_ProbeMessageConfirmation *outgoing_probe_confirmation;
1265
1266   char addr_buf[INET_ADDRSTRLEN];
1267   struct UDP_NAT_Probes *outgoing_probe;
1268   struct PeerSession *peer_session;
1269   struct MessageQueue *pending_message;
1270   struct MessageQueue *pending_message_temp;
1271   uint16_t incoming_port;
1272
1273   if (memcmp(sender, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)) == 0)
1274     {
1275 #if DEBUG_UDP
1276       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp",
1277                       _("Received a message from myself, dropping!!!\n"));
1278 #endif
1279       return;
1280     }
1281
1282   incoming_port = 0;
1283   GNUNET_assert(sender_addr != NULL); /* Can recvfrom have a NULL address? */
1284   if (fromlen == sizeof(struct IPv4UdpAddress))
1285     {
1286       incoming_port = ntohs(((struct IPv4UdpAddress *)sender_addr)->u_port);
1287     }
1288   else if (fromlen == sizeof(struct IPv6UdpAddress))
1289     {
1290       incoming_port = ntohs(((struct IPv6UdpAddress *)sender_addr)->u6_port);
1291     }
1292
1293   switch (ntohs(currhdr->type))
1294   {
1295     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE:
1296       /* Send probe reply */
1297       outgoing_probe_reply = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageReply));
1298       outgoing_probe_reply->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageReply));
1299       outgoing_probe_reply->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_REPLY);
1300
1301 #if DEBUG_UDP
1302       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1303                   _("Received a probe on listen port %d, sent_from port %d\n"),
1304                    sockinfo->port, incoming_port);
1305 #endif
1306
1307       udp_real_send(plugin, sockinfo->desc, NULL,
1308                     (char *)outgoing_probe_reply,
1309                     ntohs(outgoing_probe_reply->header.size), 0,
1310                     GNUNET_TIME_relative_get_unit(),
1311                     sender_addr, fromlen,
1312                     NULL, NULL);
1313
1314 #if DEBUG_UDP
1315       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1316                   _("Sent PROBE REPLY to port %d on outgoing port %d\n"),
1317                    incoming_port, sockinfo->port);
1318 #endif
1319       GNUNET_free(outgoing_probe_reply);
1320       break;
1321     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_REPLY:
1322       /* Check for existing probe, check ports returned, send confirmation if all is well */
1323 #if DEBUG_UDP
1324       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1325                   _("Received PROBE REPLY from port %d on incoming port %d\n"), incoming_port, sockinfo->port);
1326 #endif
1327       if (fromlen == sizeof(struct IPv4UdpAddress))
1328         {
1329           memset(&addr_buf, 0, sizeof(addr_buf));
1330           if (NULL == inet_ntop (AF_INET,
1331                                  &((struct IPv4UdpAddress *) sender_addr)->ipv4_addr, addr_buf,
1332                                  INET_ADDRSTRLEN))
1333             {
1334               GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
1335               return;
1336             }
1337           outgoing_probe = find_probe(plugin, &addr_buf[0]);
1338           if (outgoing_probe != NULL)
1339             {
1340 #if DEBUG_UDP
1341               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1342                           _("Sending confirmation that we were reached!\n"));
1343 #endif
1344               outgoing_probe_confirmation = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageConfirmation));
1345               outgoing_probe_confirmation->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageConfirmation));
1346               outgoing_probe_confirmation->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM);
1347               udp_real_send(plugin, sockinfo->desc, NULL,
1348                             (char *)outgoing_probe_confirmation,
1349                             ntohs(outgoing_probe_confirmation->header.size), 0,
1350                             GNUNET_TIME_relative_get_unit(),
1351                             sender_addr, fromlen, NULL, NULL);
1352
1353               if (outgoing_probe->task != GNUNET_SCHEDULER_NO_TASK)
1354                 {
1355                   GNUNET_SCHEDULER_cancel(outgoing_probe->task);
1356                   outgoing_probe->task = GNUNET_SCHEDULER_NO_TASK;
1357                   /* Schedule task to timeout and remove probe if confirmation not received */
1358                 }
1359               GNUNET_free(outgoing_probe_confirmation);
1360             }
1361           else
1362             {
1363 #if DEBUG_UDP
1364               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1365                           _("Received a probe reply, but have no record of a sent probe!\n"));
1366 #endif
1367             }
1368         }
1369       else
1370         {
1371 #if DEBUG_UDP
1372           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1373                       _("Received a probe reply, but sender address size is WRONG (should be %d, is %d)!\n"), sizeof(struct IPv4UdpAddress), fromlen);
1374 #endif
1375         }
1376       break;
1377     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM:
1378       peer_session = find_session(plugin, sender);
1379 #if DEBUG_UDP
1380           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1381                       _("Looking up peer session for peer %s\n"), GNUNET_i2s(sender));
1382 #endif
1383       if (peer_session == NULL) /* Shouldn't this NOT happen? */
1384         {
1385 #if DEBUG_UDP
1386           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1387                       _("Peer not in list, adding (THIS MAY BE A MISTAKE) %s\n"), GNUNET_i2s(sender));
1388 #endif
1389           peer_session = GNUNET_malloc(sizeof(struct PeerSession));
1390           peer_session->connect_addr = GNUNET_malloc(fromlen);
1391           memcpy(peer_session->connect_addr, sender_addr, fromlen);
1392           peer_session->connect_alen = fromlen;
1393           peer_session->plugin = plugin;
1394           peer_session->sock = sockinfo->desc;
1395           memcpy(&peer_session->target, sender, sizeof(struct GNUNET_PeerIdentity));
1396           peer_session->expecting_welcome = GNUNET_NO;
1397
1398           peer_session->next = plugin->sessions;
1399           plugin->sessions = peer_session;
1400
1401           peer_session->messages = NULL;
1402         }
1403       else if (peer_session->expecting_welcome == GNUNET_YES)
1404         {
1405           peer_session->expecting_welcome = GNUNET_NO;
1406           peer_session->sock = sockinfo->desc;
1407           if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress))
1408             {
1409               ((struct IPv4UdpAddress *)peer_session->connect_addr)->u_port = htons(incoming_port);
1410             }
1411           else if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress))
1412             {
1413               ((struct IPv6UdpAddress *)peer_session->connect_addr)->u6_port = htons(incoming_port);
1414             }
1415
1416 #if DEBUG_UDP
1417               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1418                           _("Received a probe confirmation, will send to peer on port %d\n"), incoming_port);
1419 #endif
1420           if (peer_session->messages != NULL)
1421             {
1422 #if DEBUG_UDP
1423               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1424                           _("Received a probe confirmation, sending queued messages.\n"));
1425 #endif
1426               pending_message = peer_session->messages;
1427               int count = 0;
1428               while (pending_message != NULL)
1429                 {
1430 #if DEBUG_UDP
1431                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1432                               _("sending queued message %d\n"), count);
1433 #endif
1434                   udp_real_send(plugin,
1435                                 peer_session->sock,
1436                                 &peer_session->target,
1437                                 pending_message->msgbuf,
1438                                 pending_message->msgbuf_size, 0,
1439                                 GNUNET_TIME_relative_get_unit(),
1440                                 peer_session->connect_addr,
1441                                 peer_session->connect_alen,
1442                                 pending_message->cont,
1443                                 pending_message->cont_cls);
1444
1445                   pending_message_temp = pending_message;
1446                   pending_message = pending_message->next;
1447                   GNUNET_free(pending_message_temp->msgbuf);
1448                   GNUNET_free(pending_message_temp);
1449 #if DEBUG_UDP
1450                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1451                               _("finished sending queued message %d\n"), count);
1452 #endif
1453                   count++;
1454                 }
1455             }
1456
1457         }
1458       else
1459         {
1460 #if DEBUG_UDP
1461           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1462                       _("Received probe confirmation for already confirmed peer!\n"));
1463 #endif
1464         }
1465       /* Received confirmation, add peer with address/port specified */
1466       break;
1467     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_KEEPALIVE:
1468       /* Once we've sent NAT_PROBE_CONFIRM change to sending keepalives */
1469       /* If we receive these just ignore! */
1470       break;
1471     default:
1472 #if DEBUG_UDP
1473       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1474                   "Sending message type %d to transport!\n",
1475                   ntohs(currhdr->type));
1476 #endif
1477       plugin->env->receive (plugin->env->cls, sender, currhdr, UDP_DIRECT_DISTANCE,
1478                             NULL, sender_addr, fromlen);
1479   }
1480
1481 }
1482
1483
1484 /*
1485  * @param cls the plugin handle
1486  * @param tc the scheduling context (for rescheduling this function again)
1487  *
1488  * We have been notified that our writeset has something to read.  We don't
1489  * know which socket needs to be read, so we have to check each one
1490  * Then reschedule this function to be called again once more is available.
1491  *
1492  */
1493 static void
1494 udp_plugin_select (void *cls,
1495                    const struct GNUNET_SCHEDULER_TaskContext *tc)
1496 {
1497   struct Plugin *plugin = cls;
1498   char buf[65536];
1499   struct UDPMessage *msg;
1500   struct GNUNET_PeerIdentity sender;
1501   socklen_t fromlen;
1502   char addr[32];
1503   ssize_t ret;
1504   int offset;
1505   int count;
1506   int tsize;
1507   char *msgbuf;
1508   const struct GNUNET_MessageHeader *currhdr;
1509   struct IPv4UdpAddress t4;
1510   struct IPv6UdpAddress t6;
1511   const struct sockaddr_in *s4;
1512   const struct sockaddr_in6 *s6;
1513   const void *ca;
1514   size_t calen;
1515   struct UDP_Sock_Info *udp_sock;
1516
1517   plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
1518   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1519     return;
1520   udp_sock = NULL;
1521   if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1522                                   plugin->udp_sockv4.desc))
1523     udp_sock = &plugin->udp_sockv4;
1524   else if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1525                                        plugin->udp_sockv6.desc))
1526     udp_sock = &plugin->udp_sockv6;
1527   if (NULL == udp_sock)
1528     {
1529       GNUNET_break (0);
1530       return;
1531     }
1532   fromlen = sizeof (addr);
1533   memset (&addr, 0, sizeof(addr));
1534   ret =
1535     GNUNET_NETWORK_socket_recvfrom (udp_sock->desc, buf, sizeof (buf),
1536                                     (struct sockaddr *)&addr, &fromlen);
1537
1538   if (AF_INET == ((struct sockaddr *)addr)->sa_family)
1539     {
1540       s4 = (const struct sockaddr_in*) &addr;
1541       t4.u_port = s4->sin_port;
1542       t4.ipv4_addr = s4->sin_addr.s_addr;
1543       ca = &t4;
1544       calen = sizeof (t4);
1545     }
1546   else if (AF_INET6 == ((struct sockaddr *)addr)->sa_family)
1547     {
1548       s6 = (const struct sockaddr_in6*) &addr;
1549       t6.u6_port = s6->sin6_port;
1550       memcpy (&t6.ipv6_addr,
1551               &s6->sin6_addr,
1552               sizeof (struct in6_addr));
1553       ca = &t6;
1554       calen = sizeof (t6);
1555     }
1556   else
1557     {
1558       GNUNET_break (0);
1559       ca = NULL;
1560       calen = 0;
1561     }
1562   if (ret < sizeof (struct UDPMessage))
1563     {
1564       GNUNET_break_op (0);
1565       plugin->select_task =
1566         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1567                                      GNUNET_SCHEDULER_NO_TASK,
1568                                      GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1569                                      NULL, &udp_plugin_select, plugin);
1570       return;
1571     }
1572   msg = (struct UDPMessage *) buf;
1573   if (ntohs (msg->header.size) < sizeof (struct UDPMessage))
1574     {
1575       GNUNET_break_op (0);
1576       plugin->select_task =
1577         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1578                                      GNUNET_SCHEDULER_NO_TASK,
1579                                      GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1580                                      NULL, &udp_plugin_select, plugin);
1581       return;
1582     }
1583   msgbuf = (char *)&msg[1];
1584   memcpy (&sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity));
1585   offset = 0;
1586   count = 0;
1587   tsize = ntohs (msg->header.size) - sizeof(struct UDPMessage);
1588   while (offset < tsize)
1589     {
1590       currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
1591       udp_demultiplexer(plugin, &sender, currhdr, ca, calen, udp_sock);
1592       offset += ntohs(currhdr->size);
1593       count++;
1594     }
1595   plugin->select_task =
1596     GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1597                                  GNUNET_SCHEDULER_NO_TASK,
1598                                  GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1599                                  NULL, &udp_plugin_select, plugin);
1600
1601 }
1602
1603 /**
1604  * Create a slew of UDP sockets.  If possible, use IPv6 and IPv4.
1605  *
1606  * @param cls closure for server start, should be a struct Plugin *
1607  * @return number of sockets created or GNUNET_SYSERR on error
1608 */
1609 static int
1610 udp_transport_server_start (void *cls)
1611 {
1612   struct Plugin *plugin = cls;
1613   struct sockaddr_in serverAddrv4;
1614   struct sockaddr_in6 serverAddrv6;
1615   struct sockaddr *serverAddr;
1616   socklen_t addrlen;
1617   int sockets_created;
1618   int tries;
1619
1620
1621   sockets_created = 0;
1622   if (plugin->behind_nat == GNUNET_YES)
1623     {
1624       /* Pipe to read from started processes stdout (on read end) */
1625       plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES);
1626       if (plugin->server_stdout == NULL)
1627         return sockets_created;
1628 #if DEBUG_UDP
1629       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1630                   "Starting gnunet-nat-server process cmd: %s %s\n",
1631                   "gnunet-nat-server",
1632                   plugin->internal_address);
1633 #endif
1634       /* Start the server process */
1635       plugin->server_proc = GNUNET_OS_start_process(NULL,
1636                                                    plugin->server_stdout,
1637                                                    "gnunet-nat-server",
1638                                                    "gnunet-nat-server",
1639                                                    plugin->internal_address, NULL);
1640       if (plugin->server_proc == NULL)
1641         {
1642 #if DEBUG_UDP
1643           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1644                       "Failed to start gnunet-nat-server process\n");
1645 #endif
1646           return GNUNET_SYSERR;
1647         }
1648       /* Close the write end of the read pipe */
1649       GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
1650
1651       plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ);
1652       plugin->server_read_task =
1653         GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1654                                         plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1655     }
1656
1657   if ( (GNUNET_YES !=
1658         GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "transport-udp",
1659                                               "DISABLEV6")))
1660     {
1661       plugin->udp_sockv6.desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0);
1662       if (NULL == plugin->udp_sockv6.desc)
1663         {
1664           GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket");
1665         }
1666       else
1667         {
1668           memset (&serverAddrv6, 0, sizeof (serverAddrv6));
1669 #if HAVE_SOCKADDR_IN_SIN_LEN
1670           serverAddrv6.sin6_len = sizeof (serverAddrv6);
1671 #endif
1672
1673           serverAddrv6.sin6_family = AF_INET6;
1674           serverAddrv6.sin6_addr = in6addr_any;
1675           if (plugin->bind6_address != NULL)
1676             {
1677               if (1 != inet_pton(AF_INET6, plugin->bind6_address, &serverAddrv6.sin6_addr))
1678                 return 0;
1679             }
1680
1681           serverAddrv6.sin6_port = htons (plugin->port);
1682           addrlen = sizeof (serverAddrv6);
1683           serverAddr = (struct sockaddr *) &serverAddrv6;
1684 #if DEBUG_UDP
1685           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1686                            "Binding to IPv6 port %d\n",
1687                            ntohs(serverAddrv6.sin6_port));
1688 #endif
1689           tries = 0;
1690           while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv6.desc, serverAddr, addrlen) !=
1691                  GNUNET_OK)
1692             {
1693               serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */
1694 #if DEBUG_UDP
1695               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1696                                "IPv6 Binding failed, trying new port %d\n",
1697                                ntohs(serverAddrv6.sin6_port));
1698 #endif
1699               tries++;
1700               if (tries > 10)
1701                 {
1702                   GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc);
1703                   plugin->udp_sockv6.desc = NULL;
1704                   break;
1705                 }       
1706             }
1707           if (plugin->udp_sockv6.desc != NULL)
1708             {
1709               plugin->udp_sockv6.port = ntohs(serverAddrv6.sin6_port);
1710               sockets_created++;
1711             }
1712         }
1713     }
1714
1715   plugin->udp_sockv4.desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
1716   if (NULL == plugin->udp_sockv4.desc)
1717     {
1718       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket");
1719     }
1720   else
1721     {
1722       memset (&serverAddrv4, 0, sizeof (serverAddrv4));
1723 #if HAVE_SOCKADDR_IN_SIN_LEN
1724       serverAddrv4.sin_len = sizeof (serverAddrv4);
1725 #endif
1726       serverAddrv4.sin_family = AF_INET;
1727       serverAddrv4.sin_addr.s_addr = INADDR_ANY;
1728       if (plugin->bind_address != NULL)
1729         {
1730           if (1 != inet_pton(AF_INET, plugin->bind_address, &serverAddrv4.sin_addr))
1731             return 0;
1732         }
1733       serverAddrv4.sin_port = htons (plugin->port);
1734       addrlen = sizeof (serverAddrv4);
1735       serverAddr = (struct sockaddr *) &serverAddrv4;
1736 #if DEBUG_UDP
1737       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1738                        "Binding to IPv4 port %d\n",
1739                        ntohs(serverAddrv4.sin_port));
1740 #endif
1741       tries = 0;
1742       while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv4.desc, serverAddr, addrlen) !=
1743              GNUNET_OK)
1744         {
1745           serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */
1746 #if DEBUG_UDP
1747           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1748                            "IPv4 Binding failed, trying new port %d\n",
1749                            ntohs(serverAddrv4.sin_port));
1750 #endif
1751           tries++;
1752           if (tries > 10)
1753             {
1754               GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc);
1755               plugin->udp_sockv4.desc = NULL;
1756               break;
1757             }   
1758         }
1759       if (plugin->udp_sockv4.desc != NULL)
1760         {
1761           plugin->udp_sockv4.port = ntohs(serverAddrv4.sin_port);
1762           sockets_created++;
1763         }
1764     }
1765
1766   plugin->rs = GNUNET_NETWORK_fdset_create ();
1767   GNUNET_NETWORK_fdset_zero (plugin->rs);
1768   if (NULL != plugin->udp_sockv4.desc)
1769     GNUNET_NETWORK_fdset_set (plugin->rs,
1770                               plugin->udp_sockv4.desc);
1771   if (NULL != plugin->udp_sockv6.desc)
1772     GNUNET_NETWORK_fdset_set (plugin->rs,
1773                               plugin->udp_sockv6.desc);
1774
1775   plugin->select_task =
1776     GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1777                                  GNUNET_SCHEDULER_NO_TASK,
1778                                  GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1779                                  NULL, &udp_plugin_select, plugin);
1780   return sockets_created;
1781 }
1782
1783
1784
1785 /**
1786  * Check if the given port is plausible (must be either
1787  * our listen port or our advertised port).  If it is
1788  * neither, we return GNUNET_SYSERR.
1789  *
1790  * @param plugin global variables
1791  * @param in_port port number to check
1792  * @return GNUNET_OK if port is either open_port or adv_port
1793  */
1794 static int
1795 check_port (struct Plugin *plugin, uint16_t in_port)
1796 {
1797   if ( (plugin->behind_nat == GNUNET_YES) && (in_port == 0) )
1798     return GNUNET_OK;
1799   if ( (plugin->only_nat_addresses == GNUNET_YES) &&
1800        (plugin->behind_nat == GNUNET_YES) )
1801     return GNUNET_SYSERR; /* odd case... */
1802   if (in_port == plugin->port)
1803     return GNUNET_OK;
1804   return GNUNET_SYSERR;
1805 }
1806
1807
1808 /**
1809  * Function that will be called to check if a binary address for this
1810  * plugin is well-formed and corresponds to an address for THIS peer
1811  * (as per our configuration).  Naturally, if absolutely necessary,
1812  * plugins can be a bit conservative in their answer, but in general
1813  * plugins should make sure that the address does not redirect
1814  * traffic to a 3rd party that might try to man-in-the-middle our
1815  * traffic.
1816  *
1817  * @param cls closure, should be our handle to the Plugin
1818  * @param addr pointer to the address
1819  * @param addrlen length of addr
1820  * @return GNUNET_OK if this is a plausible address for this peer
1821  *         and transport, GNUNET_SYSERR if not
1822  *
1823  */
1824 static int
1825 udp_check_address (void *cls,
1826                    const void *addr,
1827                    size_t addrlen)
1828 {
1829   struct Plugin *plugin = cls;
1830   char buf[INET6_ADDRSTRLEN];
1831   const void *sb;
1832   struct in_addr a4;
1833   struct in6_addr a6;
1834   int af;
1835   uint16_t port;
1836   struct IPv4UdpAddress *v4;
1837   struct IPv6UdpAddress *v6;
1838
1839   if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
1840       (addrlen != sizeof (struct IPv6UdpAddress)))
1841     {
1842       GNUNET_break_op (0);
1843       return GNUNET_SYSERR;
1844     }
1845
1846   if (addrlen == sizeof (struct IPv4UdpAddress))
1847     {
1848       v4 = (struct IPv4UdpAddress *) addr;
1849       if (GNUNET_OK !=
1850           check_port (plugin, ntohs (v4->u_port)))
1851         return GNUNET_SYSERR;
1852       if (GNUNET_OK !=
1853           check_local_addr (plugin, &v4->ipv4_addr, sizeof (uint32_t)))
1854         return GNUNET_SYSERR;
1855
1856       af = AF_INET;
1857       port = ntohs (v4->u_port);
1858       memcpy (&a4, &v4->ipv4_addr, sizeof (a4));
1859       sb = &a4;
1860     }
1861   else
1862     {
1863       v6 = (struct IPv6UdpAddress *) addr;
1864       if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
1865         {
1866           GNUNET_break_op (0);
1867           return GNUNET_SYSERR;
1868         }
1869       if (GNUNET_OK !=
1870           check_port (plugin, ntohs (v6->u6_port)))
1871         return GNUNET_SYSERR;
1872       if (GNUNET_OK !=
1873           check_local_addr (plugin, &v6->ipv6_addr, sizeof (struct in6_addr)))
1874         return GNUNET_SYSERR;
1875
1876       af = AF_INET6;
1877       port = ntohs (v6->u6_port);
1878       memcpy (&a6, &v6->ipv6_addr, sizeof (a6));
1879       sb = &a6;
1880     }
1881
1882   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
1883
1884 #if DEBUG_UDP
1885   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1886                    "Informing transport service about my address `%s:%u'\n",
1887                    buf,
1888                    port);
1889 #endif
1890   return GNUNET_OK;
1891 }
1892
1893
1894 /**
1895  * Append our port and forward the result.
1896  */
1897 static void
1898 append_port (void *cls, const char *hostname)
1899 {
1900   struct PrettyPrinterContext *ppc = cls;
1901   char *ret;
1902
1903   if (hostname == NULL)
1904     {
1905       ppc->asc (ppc->asc_cls, NULL);
1906       GNUNET_free (ppc);
1907       return;
1908     }
1909   GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
1910   ppc->asc (ppc->asc_cls, ret);
1911   GNUNET_free (ret);
1912 }
1913
1914
1915 /**
1916  * Convert the transports address to a nice, human-readable
1917  * format.
1918  *
1919  * @param cls closure
1920  * @param type name of the transport that generated the address
1921  * @param addr one of the addresses of the host, NULL for the last address
1922  *        the specific address format depends on the transport
1923  * @param addrlen length of the address
1924  * @param numeric should (IP) addresses be displayed in numeric form?
1925  * @param timeout after how long should we give up?
1926  * @param asc function to call on each string
1927  * @param asc_cls closure for asc
1928  */
1929 static void
1930 udp_plugin_address_pretty_printer (void *cls,
1931                                    const char *type,
1932                                    const void *addr,
1933                                    size_t addrlen,
1934                                    int numeric,
1935                                    struct GNUNET_TIME_Relative timeout,
1936                                    GNUNET_TRANSPORT_AddressStringCallback asc,
1937                                    void *asc_cls)
1938 {
1939   struct Plugin *plugin = cls;
1940   struct PrettyPrinterContext *ppc;
1941   const void *sb;
1942   size_t sbs;
1943   struct sockaddr_in a4;
1944   struct sockaddr_in6 a6;
1945   const struct IPv4UdpAddress *u4;
1946   const struct IPv6UdpAddress *u6;
1947   uint16_t port;
1948
1949   if (addrlen == sizeof (struct IPv6UdpAddress))
1950     {
1951       u6 = addr;
1952       memset (&a6, 0, sizeof (a6));
1953       a6.sin6_family = AF_INET6;
1954       a6.sin6_port = u6->u6_port;
1955       memcpy (&a6.sin6_addr,
1956               &u6->ipv6_addr,
1957               sizeof (struct in6_addr));
1958       port = ntohs (u6->u6_port);
1959       sb = &a6;
1960       sbs = sizeof (a6);
1961     }
1962   else if (addrlen == sizeof (struct IPv4UdpAddress))
1963     {
1964       u4 = addr;
1965       memset (&a4, 0, sizeof (a4));
1966       a4.sin_family = AF_INET;
1967       a4.sin_port = u4->u_port;
1968       a4.sin_addr.s_addr = u4->ipv4_addr;
1969       port = ntohs (u4->u_port);
1970       sb = &a4;
1971       sbs = sizeof (a4);
1972     }
1973   else
1974     {
1975       /* invalid address */
1976       GNUNET_break_op (0);
1977       asc (asc_cls, NULL);
1978       return;
1979     }
1980   ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
1981   ppc->asc = asc;
1982   ppc->asc_cls = asc_cls;
1983   ppc->port = port;
1984   GNUNET_RESOLVER_hostname_get (plugin->env->cfg,
1985                                 sb,
1986                                 sbs,
1987                                 !numeric, timeout, &append_port, ppc);
1988 }
1989
1990 /**
1991  * Return the actual path to a file found in the current
1992  * PATH environment variable.
1993  *
1994  * @param binary the name of the file to find
1995  */
1996 static char *
1997 get_path_from_PATH (char *binary)
1998 {
1999   char *path;
2000   char *pos;
2001   char *end;
2002   char *buf;
2003   const char *p;
2004
2005   p = getenv ("PATH");
2006   if (p == NULL)
2007     return NULL;
2008   path = GNUNET_strdup (p);     /* because we write on it */
2009   buf = GNUNET_malloc (strlen (path) + 20);
2010   pos = path;
2011
2012   while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
2013     {
2014       *end = '\0';
2015       sprintf (buf, "%s/%s", pos, binary);
2016       if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
2017         {
2018           GNUNET_free (path);
2019           return buf;
2020         }
2021       pos = end + 1;
2022     }
2023   sprintf (buf, "%s/%s", pos, binary);
2024   if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
2025     {
2026       GNUNET_free (path);
2027       return buf;
2028     }
2029   GNUNET_free (buf);
2030   GNUNET_free (path);
2031   return NULL;
2032 }
2033
2034 /**
2035  * Check whether the suid bit is set on a file.
2036  * Attempts to find the file using the current
2037  * PATH environment variable as a search path.
2038  *
2039  * @param binary the name of the file to check
2040  */
2041 static int
2042 check_gnunet_nat_binary(char *binary)
2043 {
2044   struct stat statbuf;
2045   char *p;
2046 #ifdef MINGW
2047   SOCKET rawsock;
2048 #endif
2049
2050 #ifdef MINGW
2051   char *binaryexe;
2052   GNUNET_asprintf (&binaryexe, "%s.exe", binary);
2053   p = get_path_from_PATH (binaryexe);
2054   free (binaryexe);
2055 #else
2056   p = get_path_from_PATH (binary);
2057 #endif
2058   if (p == NULL)
2059     return GNUNET_NO;
2060   if (0 != STAT (p, &statbuf))
2061     {
2062       GNUNET_free (p);
2063       return GNUNET_SYSERR;
2064     }
2065   GNUNET_free (p);
2066 #ifndef MINGW
2067   if ( (0 != (statbuf.st_mode & S_ISUID)) &&
2068        (statbuf.st_uid == 0) )
2069     return GNUNET_YES;
2070   return GNUNET_NO;
2071 #else
2072   rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
2073   if (INVALID_SOCKET == rawsock)
2074   {
2075     DWORD err = GetLastError ();
2076     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err);
2077     return GNUNET_NO; /* not running as administrator */
2078   }
2079   closesocket (rawsock);
2080   return GNUNET_YES;
2081 #endif
2082 }
2083
2084 /**
2085  * Function called for a quick conversion of the binary address to
2086  * a numeric address.  Note that the caller must not free the
2087  * address and that the next call to this function is allowed
2088  * to override the address again.
2089  *
2090  * @param cls closure
2091  * @param addr binary address
2092  * @param addrlen length of the address
2093  * @return string representing the same address
2094  */
2095 static const char*
2096 udp_address_to_string (void *cls,
2097                        const void *addr,
2098                        size_t addrlen)
2099 {
2100   static char rbuf[INET6_ADDRSTRLEN + 10];
2101   char buf[INET6_ADDRSTRLEN];
2102   const void *sb;
2103   struct in_addr a4;
2104   struct in6_addr a6;
2105   const struct IPv4UdpAddress *t4;
2106   const struct IPv6UdpAddress *t6;
2107   int af;
2108   uint16_t port;
2109
2110   if (addrlen == sizeof (struct IPv6UdpAddress))
2111     {
2112       t6 = addr;
2113       af = AF_INET6;
2114       port = ntohs (t6->u6_port);
2115       memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
2116       sb = &a6;
2117     }
2118   else if (addrlen == sizeof (struct IPv4UdpAddress))
2119     {
2120       t4 = addr;
2121       af = AF_INET;
2122       port = ntohs (t4->u_port);
2123       memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
2124       sb = &a4;
2125     }
2126   else
2127     return NULL;
2128   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
2129   GNUNET_snprintf (rbuf,
2130                    sizeof (rbuf),
2131                    "%s:%u",
2132                    buf,
2133                    port);
2134   return rbuf;
2135 }
2136
2137 /**
2138  * The exported method. Makes the core api available via a global and
2139  * returns the udp transport API.
2140  */
2141 void *
2142 libgnunet_plugin_transport_udp_init (void *cls)
2143 {
2144   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
2145   unsigned long long mtu;
2146   unsigned long long port;
2147   struct GNUNET_TRANSPORT_PluginFunctions *api;
2148   struct Plugin *plugin;
2149   int sockets_created;
2150   int behind_nat;
2151   int allow_nat;
2152   int only_nat_addresses;
2153   char *internal_address;
2154   char *external_address;
2155   struct IPv4UdpAddress v4_address;
2156
2157   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2158                                                          "transport-udp",
2159                                                          "BEHIND_NAT"))
2160     {
2161       /* We are behind nat (according to the user) */
2162       if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES)
2163         behind_nat = GNUNET_YES;
2164       else
2165         {
2166           behind_nat = GNUNET_NO;
2167           GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Configuration specified you are behind a NAT, but gnunet-nat-server is not installed properly (suid bit not set)!\n");
2168         }
2169     }
2170   else
2171     behind_nat = GNUNET_NO; /* We are not behind nat! */
2172
2173   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2174                                                          "transport-udp",
2175                                                          "ALLOW_NAT"))
2176     {
2177       if (check_gnunet_nat_binary("gnunet-nat-client") == GNUNET_YES)
2178         allow_nat = GNUNET_YES; /* We will try to connect to NAT'd peers */
2179       else
2180       {
2181         allow_nat = GNUNET_NO;
2182         GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Configuration specified you want to connect to NAT'd peers, but gnunet-nat-client is not installed properly (suid bit not set)!\n");
2183       }
2184
2185     }
2186   else
2187     allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */
2188
2189   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2190                                                            "transport-udp",
2191                                                            "ONLY_NAT_ADDRESSES"))
2192     only_nat_addresses = GNUNET_YES; /* We will only report our addresses as NAT'd */
2193   else
2194     only_nat_addresses = GNUNET_NO; /* We will report our addresses as NAT'd and non-NAT'd */
2195
2196   external_address = NULL;
2197   if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK !=
2198          GNUNET_CONFIGURATION_get_value_string (env->cfg,
2199                                                 "transport-udp",
2200                                                 "EXTERNAL_ADDRESS",
2201                                                 &external_address)))
2202     {
2203       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2204                   _("Require EXTERNAL_ADDRESS for service `%s' in configuration (either BEHIND_NAT or ALLOW_NAT set to YES)!\n"),
2205                   "transport-udp");
2206       return NULL;
2207     }
2208
2209   if ((external_address != NULL) && (inet_pton(AF_INET, external_address, &v4_address.ipv4_addr) != 1))
2210     {
2211       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed EXTERNAL_ADDRESS %s given in configuration!\n", external_address);
2212     }
2213
2214   internal_address = NULL;
2215   if ((GNUNET_YES == behind_nat) && (GNUNET_OK !=
2216          GNUNET_CONFIGURATION_get_value_string (env->cfg,
2217                                                 "transport-udp",
2218                                                 "INTERNAL_ADDRESS",
2219                                                 &internal_address)))
2220     {
2221       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2222                        _("Require INTERNAL_ADDRESS for service `%s' in configuration!\n"),
2223                        "transport-udp");
2224       GNUNET_free_non_null(external_address);
2225       return NULL;
2226     }
2227
2228   if ((internal_address != NULL) && (inet_pton(AF_INET, internal_address, &v4_address.ipv4_addr) != 1))
2229     {
2230       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed INTERNAL_ADDRESS %s given in configuration!\n", internal_address);
2231     }
2232
2233   if (GNUNET_OK !=
2234       GNUNET_CONFIGURATION_get_value_number (env->cfg,
2235                                              "transport-udp",
2236                                              "PORT",
2237                                              &port))
2238     port = UDP_NAT_DEFAULT_PORT;
2239   else if (port > 65535)
2240     {
2241       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2242                   _("Given `%s' option is out of range: %llu > %u\n"),
2243                   "PORT",
2244                   port,
2245                   65535);
2246       GNUNET_free_non_null(external_address);
2247       GNUNET_free_non_null(internal_address);
2248       return NULL;
2249     }
2250
2251   mtu = 1240;
2252   if (mtu < 1200)
2253     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2254                 _("MTU %llu for `%s' is probably too low!\n"), mtu,
2255                 "UDP");
2256
2257   plugin = GNUNET_malloc (sizeof (struct Plugin));
2258   plugin->external_address = external_address;
2259   plugin->internal_address = internal_address;
2260   plugin->port = port;
2261   plugin->behind_nat = behind_nat;
2262   plugin->allow_nat = allow_nat;
2263   plugin->only_nat_addresses = only_nat_addresses;
2264   plugin->env = env;
2265
2266   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2267   api->cls = plugin;
2268
2269   api->send = &udp_plugin_send;
2270   api->disconnect = &udp_disconnect;
2271   api->address_pretty_printer = &udp_plugin_address_pretty_printer;
2272   api->address_to_string = &udp_address_to_string;
2273   api->check_address = &udp_check_address;
2274
2275   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO", &plugin->bind_address))
2276     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind_address);
2277   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO6", &plugin->bind6_address))
2278     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind6_address);
2279
2280   if (plugin->behind_nat == GNUNET_NO)
2281     {
2282       GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
2283     }
2284
2285   plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (env->cfg,
2286                                                            AF_UNSPEC,
2287                                                            HOSTNAME_RESOLVE_TIMEOUT,
2288                                                            &process_hostname_ips,
2289                                                            plugin);
2290
2291   if ((plugin->behind_nat == GNUNET_YES) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1))
2292     {
2293       v4_address.u_port = htons(0);
2294       plugin->env->notify_address (plugin->env->cls,
2295                                   "udp",
2296                                   &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL);
2297       add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t));
2298       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying plugin of address %s:0\n", plugin->external_address);
2299     }
2300   else if ((plugin->external_address != NULL) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1))
2301     {
2302       v4_address.u_port = htons(plugin->port);
2303       plugin->env->notify_address (plugin->env->cls,
2304                                   "udp",
2305                                   &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL);
2306       add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t));
2307     }
2308
2309   sockets_created = udp_transport_server_start (plugin);
2310   if (sockets_created == 0)
2311     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2312                 _("Failed to open UDP sockets\n"));
2313   return api;
2314 }
2315
2316 void *
2317 libgnunet_plugin_transport_udp_done (void *cls)
2318 {
2319   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2320   struct Plugin *plugin = api->cls;
2321   struct LocalAddrList *lal;
2322
2323   udp_transport_server_stop (plugin);
2324   if (NULL != plugin->hostname_dns)
2325     {
2326       GNUNET_RESOLVER_request_cancel (plugin->hostname_dns);
2327       plugin->hostname_dns = NULL;
2328     }
2329
2330   GNUNET_NETWORK_fdset_destroy (plugin->rs);
2331   while (NULL != (lal = plugin->lal_head))
2332     {
2333       GNUNET_CONTAINER_DLL_remove (plugin->lal_head,
2334                                    plugin->lal_tail,
2335                                    lal);
2336       GNUNET_free (lal);
2337     }
2338   GNUNET_free (plugin);
2339   GNUNET_free (api);
2340   return NULL;
2341 }
2342
2343 /* end of plugin_transport_udp.c */