safety check
[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       struct GNUNET_TRANSPORT_ATS_Information distance[2];
1478       distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
1479       distance[0].value = htonl (UDP_DIRECT_DISTANCE);
1480       distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
1481       distance[1].value = htonl (0);
1482
1483       plugin->env->receive (plugin->env->cls, sender, currhdr,
1484                     (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2,
1485                             NULL, sender_addr, fromlen);
1486   }
1487
1488 }
1489
1490
1491 /*
1492  * @param cls the plugin handle
1493  * @param tc the scheduling context (for rescheduling this function again)
1494  *
1495  * We have been notified that our writeset has something to read.  We don't
1496  * know which socket needs to be read, so we have to check each one
1497  * Then reschedule this function to be called again once more is available.
1498  *
1499  */
1500 static void
1501 udp_plugin_select (void *cls,
1502                    const struct GNUNET_SCHEDULER_TaskContext *tc)
1503 {
1504   struct Plugin *plugin = cls;
1505   char buf[65536];
1506   struct UDPMessage *msg;
1507   struct GNUNET_PeerIdentity sender;
1508   socklen_t fromlen;
1509   char addr[32];
1510   ssize_t ret;
1511   int offset;
1512   int count;
1513   int tsize;
1514   char *msgbuf;
1515   const struct GNUNET_MessageHeader *currhdr;
1516   struct IPv4UdpAddress t4;
1517   struct IPv6UdpAddress t6;
1518   const struct sockaddr_in *s4;
1519   const struct sockaddr_in6 *s6;
1520   const void *ca;
1521   size_t calen;
1522   struct UDP_Sock_Info *udp_sock;
1523
1524   plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
1525   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1526     return;
1527   udp_sock = NULL;
1528   if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1529                                   plugin->udp_sockv4.desc))
1530     udp_sock = &plugin->udp_sockv4;
1531   else if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1532                                        plugin->udp_sockv6.desc))
1533     udp_sock = &plugin->udp_sockv6;
1534   if (NULL == udp_sock)
1535     {
1536       GNUNET_break (0);
1537       return;
1538     }
1539   fromlen = sizeof (addr);
1540   memset (&addr, 0, sizeof(addr));
1541   ret =
1542     GNUNET_NETWORK_socket_recvfrom (udp_sock->desc, buf, sizeof (buf),
1543                                     (struct sockaddr *)&addr, &fromlen);
1544
1545   if (AF_INET == ((struct sockaddr *)addr)->sa_family)
1546     {
1547       s4 = (const struct sockaddr_in*) &addr;
1548       t4.u_port = s4->sin_port;
1549       t4.ipv4_addr = s4->sin_addr.s_addr;
1550       ca = &t4;
1551       calen = sizeof (t4);
1552     }
1553   else if (AF_INET6 == ((struct sockaddr *)addr)->sa_family)
1554     {
1555       s6 = (const struct sockaddr_in6*) &addr;
1556       t6.u6_port = s6->sin6_port;
1557       memcpy (&t6.ipv6_addr,
1558               &s6->sin6_addr,
1559               sizeof (struct in6_addr));
1560       ca = &t6;
1561       calen = sizeof (t6);
1562     }
1563   else
1564     {
1565       GNUNET_break (0);
1566       ca = NULL;
1567       calen = 0;
1568     }
1569   if (ret < sizeof (struct UDPMessage))
1570     {
1571       GNUNET_break_op (0);
1572       plugin->select_task =
1573         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1574                                      GNUNET_SCHEDULER_NO_TASK,
1575                                      GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1576                                      NULL, &udp_plugin_select, plugin);
1577       return;
1578     }
1579   msg = (struct UDPMessage *) buf;
1580   if (ntohs (msg->header.size) < sizeof (struct UDPMessage))
1581     {
1582       GNUNET_break_op (0);
1583       plugin->select_task =
1584         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1585                                      GNUNET_SCHEDULER_NO_TASK,
1586                                      GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1587                                      NULL, &udp_plugin_select, plugin);
1588       return;
1589     }
1590   msgbuf = (char *)&msg[1];
1591   memcpy (&sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity));
1592   offset = 0;
1593   count = 0;
1594   tsize = ntohs (msg->header.size) - sizeof(struct UDPMessage);
1595   while (offset < tsize)
1596     {
1597       currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
1598       udp_demultiplexer(plugin, &sender, currhdr, ca, calen, udp_sock);
1599       offset += ntohs(currhdr->size);
1600       count++;
1601     }
1602   plugin->select_task =
1603     GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1604                                  GNUNET_SCHEDULER_NO_TASK,
1605                                  GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1606                                  NULL, &udp_plugin_select, plugin);
1607
1608 }
1609
1610 /**
1611  * Create a slew of UDP sockets.  If possible, use IPv6 and IPv4.
1612  *
1613  * @param cls closure for server start, should be a struct Plugin *
1614  * @return number of sockets created or GNUNET_SYSERR on error
1615 */
1616 static int
1617 udp_transport_server_start (void *cls)
1618 {
1619   struct Plugin *plugin = cls;
1620   struct sockaddr_in serverAddrv4;
1621   struct sockaddr_in6 serverAddrv6;
1622   struct sockaddr *serverAddr;
1623   socklen_t addrlen;
1624   int sockets_created;
1625   int tries;
1626
1627
1628   sockets_created = 0;
1629   if (plugin->behind_nat == GNUNET_YES)
1630     {
1631       /* Pipe to read from started processes stdout (on read end) */
1632       plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES);
1633       if (plugin->server_stdout == NULL)
1634         return sockets_created;
1635 #if DEBUG_UDP
1636       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1637                   "Starting gnunet-nat-server process cmd: %s %s\n",
1638                   "gnunet-nat-server",
1639                   plugin->internal_address);
1640 #endif
1641       /* Start the server process */
1642       plugin->server_proc = GNUNET_OS_start_process(NULL,
1643                                                    plugin->server_stdout,
1644                                                    "gnunet-nat-server",
1645                                                    "gnunet-nat-server",
1646                                                    plugin->internal_address, NULL);
1647       if (plugin->server_proc == NULL)
1648         {
1649 #if DEBUG_UDP
1650           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1651                       "Failed to start gnunet-nat-server process\n");
1652 #endif
1653           return GNUNET_SYSERR;
1654         }
1655       /* Close the write end of the read pipe */
1656       GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
1657
1658       plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ);
1659       plugin->server_read_task =
1660         GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1661                                         plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1662     }
1663
1664   if ( (GNUNET_YES !=
1665         GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "transport-udp",
1666                                               "DISABLEV6")))
1667     {
1668       plugin->udp_sockv6.desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0);
1669       if (NULL == plugin->udp_sockv6.desc)
1670         {
1671           GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket");
1672         }
1673       else
1674         {
1675           memset (&serverAddrv6, 0, sizeof (serverAddrv6));
1676 #if HAVE_SOCKADDR_IN_SIN_LEN
1677           serverAddrv6.sin6_len = sizeof (serverAddrv6);
1678 #endif
1679
1680           serverAddrv6.sin6_family = AF_INET6;
1681           serverAddrv6.sin6_addr = in6addr_any;
1682           if (plugin->bind6_address != NULL)
1683             {
1684               if (1 != inet_pton(AF_INET6, plugin->bind6_address, &serverAddrv6.sin6_addr))
1685                 return 0;
1686             }
1687
1688           serverAddrv6.sin6_port = htons (plugin->port);
1689           addrlen = sizeof (serverAddrv6);
1690           serverAddr = (struct sockaddr *) &serverAddrv6;
1691 #if DEBUG_UDP
1692           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1693                            "Binding to IPv6 port %d\n",
1694                            ntohs(serverAddrv6.sin6_port));
1695 #endif
1696           tries = 0;
1697           while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv6.desc, serverAddr, addrlen) !=
1698                  GNUNET_OK)
1699             {
1700               serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */
1701 #if DEBUG_UDP
1702               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1703                                "IPv6 Binding failed, trying new port %d\n",
1704                                ntohs(serverAddrv6.sin6_port));
1705 #endif
1706               tries++;
1707               if (tries > 10)
1708                 {
1709                   GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc);
1710                   plugin->udp_sockv6.desc = NULL;
1711                   break;
1712                 }       
1713             }
1714           if (plugin->udp_sockv6.desc != NULL)
1715             {
1716               plugin->udp_sockv6.port = ntohs(serverAddrv6.sin6_port);
1717               sockets_created++;
1718             }
1719         }
1720     }
1721
1722   plugin->udp_sockv4.desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
1723   if (NULL == plugin->udp_sockv4.desc)
1724     {
1725       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket");
1726     }
1727   else
1728     {
1729       memset (&serverAddrv4, 0, sizeof (serverAddrv4));
1730 #if HAVE_SOCKADDR_IN_SIN_LEN
1731       serverAddrv4.sin_len = sizeof (serverAddrv4);
1732 #endif
1733       serverAddrv4.sin_family = AF_INET;
1734       serverAddrv4.sin_addr.s_addr = INADDR_ANY;
1735       if (plugin->bind_address != NULL)
1736         {
1737           if (1 != inet_pton(AF_INET, plugin->bind_address, &serverAddrv4.sin_addr))
1738             return 0;
1739         }
1740       serverAddrv4.sin_port = htons (plugin->port);
1741       addrlen = sizeof (serverAddrv4);
1742       serverAddr = (struct sockaddr *) &serverAddrv4;
1743 #if DEBUG_UDP
1744       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1745                        "Binding to IPv4 port %d\n",
1746                        ntohs(serverAddrv4.sin_port));
1747 #endif
1748       tries = 0;
1749       while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv4.desc, serverAddr, addrlen) !=
1750              GNUNET_OK)
1751         {
1752           serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */
1753 #if DEBUG_UDP
1754           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1755                            "IPv4 Binding failed, trying new port %d\n",
1756                            ntohs(serverAddrv4.sin_port));
1757 #endif
1758           tries++;
1759           if (tries > 10)
1760             {
1761               GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc);
1762               plugin->udp_sockv4.desc = NULL;
1763               break;
1764             }   
1765         }
1766       if (plugin->udp_sockv4.desc != NULL)
1767         {
1768           plugin->udp_sockv4.port = ntohs(serverAddrv4.sin_port);
1769           sockets_created++;
1770         }
1771     }
1772
1773   plugin->rs = GNUNET_NETWORK_fdset_create ();
1774   GNUNET_NETWORK_fdset_zero (plugin->rs);
1775   if (NULL != plugin->udp_sockv4.desc)
1776     GNUNET_NETWORK_fdset_set (plugin->rs,
1777                               plugin->udp_sockv4.desc);
1778   if (NULL != plugin->udp_sockv6.desc)
1779     GNUNET_NETWORK_fdset_set (plugin->rs,
1780                               plugin->udp_sockv6.desc);
1781
1782   plugin->select_task =
1783     GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1784                                  GNUNET_SCHEDULER_NO_TASK,
1785                                  GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1786                                  NULL, &udp_plugin_select, plugin);
1787   return sockets_created;
1788 }
1789
1790
1791
1792 /**
1793  * Check if the given port is plausible (must be either
1794  * our listen port or our advertised port).  If it is
1795  * neither, we return GNUNET_SYSERR.
1796  *
1797  * @param plugin global variables
1798  * @param in_port port number to check
1799  * @return GNUNET_OK if port is either open_port or adv_port
1800  */
1801 static int
1802 check_port (struct Plugin *plugin, uint16_t in_port)
1803 {
1804   if ( (plugin->behind_nat == GNUNET_YES) && (in_port == 0) )
1805     return GNUNET_OK;
1806   if ( (plugin->only_nat_addresses == GNUNET_YES) &&
1807        (plugin->behind_nat == GNUNET_YES) )
1808     return GNUNET_SYSERR; /* odd case... */
1809   if (in_port == plugin->port)
1810     return GNUNET_OK;
1811   return GNUNET_SYSERR;
1812 }
1813
1814
1815 /**
1816  * Function that will be called to check if a binary address for this
1817  * plugin is well-formed and corresponds to an address for THIS peer
1818  * (as per our configuration).  Naturally, if absolutely necessary,
1819  * plugins can be a bit conservative in their answer, but in general
1820  * plugins should make sure that the address does not redirect
1821  * traffic to a 3rd party that might try to man-in-the-middle our
1822  * traffic.
1823  *
1824  * @param cls closure, should be our handle to the Plugin
1825  * @param addr pointer to the address
1826  * @param addrlen length of addr
1827  * @return GNUNET_OK if this is a plausible address for this peer
1828  *         and transport, GNUNET_SYSERR if not
1829  *
1830  */
1831 static int
1832 udp_check_address (void *cls,
1833                    const void *addr,
1834                    size_t addrlen)
1835 {
1836   struct Plugin *plugin = cls;
1837   char buf[INET6_ADDRSTRLEN];
1838   const void *sb;
1839   struct in_addr a4;
1840   struct in6_addr a6;
1841   int af;
1842   uint16_t port;
1843   struct IPv4UdpAddress *v4;
1844   struct IPv6UdpAddress *v6;
1845
1846   if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
1847       (addrlen != sizeof (struct IPv6UdpAddress)))
1848     {
1849       GNUNET_break_op (0);
1850       return GNUNET_SYSERR;
1851     }
1852
1853   if (addrlen == sizeof (struct IPv4UdpAddress))
1854     {
1855       v4 = (struct IPv4UdpAddress *) addr;
1856       if (GNUNET_OK !=
1857           check_port (plugin, ntohs (v4->u_port)))
1858         return GNUNET_SYSERR;
1859       if (GNUNET_OK !=
1860           check_local_addr (plugin, &v4->ipv4_addr, sizeof (uint32_t)))
1861         return GNUNET_SYSERR;
1862
1863       af = AF_INET;
1864       port = ntohs (v4->u_port);
1865       memcpy (&a4, &v4->ipv4_addr, sizeof (a4));
1866       sb = &a4;
1867     }
1868   else
1869     {
1870       v6 = (struct IPv6UdpAddress *) addr;
1871       if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
1872         {
1873           GNUNET_break_op (0);
1874           return GNUNET_SYSERR;
1875         }
1876       if (GNUNET_OK !=
1877           check_port (plugin, ntohs (v6->u6_port)))
1878         return GNUNET_SYSERR;
1879       if (GNUNET_OK !=
1880           check_local_addr (plugin, &v6->ipv6_addr, sizeof (struct in6_addr)))
1881         return GNUNET_SYSERR;
1882
1883       af = AF_INET6;
1884       port = ntohs (v6->u6_port);
1885       memcpy (&a6, &v6->ipv6_addr, sizeof (a6));
1886       sb = &a6;
1887     }
1888
1889   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
1890
1891 #if DEBUG_UDP
1892   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1893                    "Informing transport service about my address `%s:%u'\n",
1894                    buf,
1895                    port);
1896 #endif
1897   return GNUNET_OK;
1898 }
1899
1900
1901 /**
1902  * Append our port and forward the result.
1903  */
1904 static void
1905 append_port (void *cls, const char *hostname)
1906 {
1907   struct PrettyPrinterContext *ppc = cls;
1908   char *ret;
1909
1910   if (hostname == NULL)
1911     {
1912       ppc->asc (ppc->asc_cls, NULL);
1913       GNUNET_free (ppc);
1914       return;
1915     }
1916   GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
1917   ppc->asc (ppc->asc_cls, ret);
1918   GNUNET_free (ret);
1919 }
1920
1921
1922 /**
1923  * Convert the transports address to a nice, human-readable
1924  * format.
1925  *
1926  * @param cls closure
1927  * @param type name of the transport that generated the address
1928  * @param addr one of the addresses of the host, NULL for the last address
1929  *        the specific address format depends on the transport
1930  * @param addrlen length of the address
1931  * @param numeric should (IP) addresses be displayed in numeric form?
1932  * @param timeout after how long should we give up?
1933  * @param asc function to call on each string
1934  * @param asc_cls closure for asc
1935  */
1936 static void
1937 udp_plugin_address_pretty_printer (void *cls,
1938                                    const char *type,
1939                                    const void *addr,
1940                                    size_t addrlen,
1941                                    int numeric,
1942                                    struct GNUNET_TIME_Relative timeout,
1943                                    GNUNET_TRANSPORT_AddressStringCallback asc,
1944                                    void *asc_cls)
1945 {
1946   struct Plugin *plugin = cls;
1947   struct PrettyPrinterContext *ppc;
1948   const void *sb;
1949   size_t sbs;
1950   struct sockaddr_in a4;
1951   struct sockaddr_in6 a6;
1952   const struct IPv4UdpAddress *u4;
1953   const struct IPv6UdpAddress *u6;
1954   uint16_t port;
1955
1956   if (addrlen == sizeof (struct IPv6UdpAddress))
1957     {
1958       u6 = addr;
1959       memset (&a6, 0, sizeof (a6));
1960       a6.sin6_family = AF_INET6;
1961       a6.sin6_port = u6->u6_port;
1962       memcpy (&a6.sin6_addr,
1963               &u6->ipv6_addr,
1964               sizeof (struct in6_addr));
1965       port = ntohs (u6->u6_port);
1966       sb = &a6;
1967       sbs = sizeof (a6);
1968     }
1969   else if (addrlen == sizeof (struct IPv4UdpAddress))
1970     {
1971       u4 = addr;
1972       memset (&a4, 0, sizeof (a4));
1973       a4.sin_family = AF_INET;
1974       a4.sin_port = u4->u_port;
1975       a4.sin_addr.s_addr = u4->ipv4_addr;
1976       port = ntohs (u4->u_port);
1977       sb = &a4;
1978       sbs = sizeof (a4);
1979     }
1980   else
1981     {
1982       /* invalid address */
1983       GNUNET_break_op (0);
1984       asc (asc_cls, NULL);
1985       return;
1986     }
1987   ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
1988   ppc->asc = asc;
1989   ppc->asc_cls = asc_cls;
1990   ppc->port = port;
1991   GNUNET_RESOLVER_hostname_get (plugin->env->cfg,
1992                                 sb,
1993                                 sbs,
1994                                 !numeric, timeout, &append_port, ppc);
1995 }
1996
1997 /**
1998  * Return the actual path to a file found in the current
1999  * PATH environment variable.
2000  *
2001  * @param binary the name of the file to find
2002  */
2003 static char *
2004 get_path_from_PATH (char *binary)
2005 {
2006   char *path;
2007   char *pos;
2008   char *end;
2009   char *buf;
2010   const char *p;
2011
2012   p = getenv ("PATH");
2013   if (p == NULL)
2014     return NULL;
2015   path = GNUNET_strdup (p);     /* because we write on it */
2016   buf = GNUNET_malloc (strlen (path) + 20);
2017   pos = path;
2018
2019   while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
2020     {
2021       *end = '\0';
2022       sprintf (buf, "%s/%s", pos, binary);
2023       if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
2024         {
2025           GNUNET_free (path);
2026           return buf;
2027         }
2028       pos = end + 1;
2029     }
2030   sprintf (buf, "%s/%s", pos, binary);
2031   if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
2032     {
2033       GNUNET_free (path);
2034       return buf;
2035     }
2036   GNUNET_free (buf);
2037   GNUNET_free (path);
2038   return NULL;
2039 }
2040
2041 /**
2042  * Check whether the suid bit is set on a file.
2043  * Attempts to find the file using the current
2044  * PATH environment variable as a search path.
2045  *
2046  * @param binary the name of the file to check
2047  */
2048 static int
2049 check_gnunet_nat_binary(char *binary)
2050 {
2051   struct stat statbuf;
2052   char *p;
2053 #ifdef MINGW
2054   SOCKET rawsock;
2055 #endif
2056
2057 #ifdef MINGW
2058   char *binaryexe;
2059   GNUNET_asprintf (&binaryexe, "%s.exe", binary);
2060   p = get_path_from_PATH (binaryexe);
2061   free (binaryexe);
2062 #else
2063   p = get_path_from_PATH (binary);
2064 #endif
2065   if (p == NULL)
2066     return GNUNET_NO;
2067   if (0 != STAT (p, &statbuf))
2068     {
2069       GNUNET_free (p);
2070       return GNUNET_SYSERR;
2071     }
2072   GNUNET_free (p);
2073 #ifndef MINGW
2074   if ( (0 != (statbuf.st_mode & S_ISUID)) &&
2075        (statbuf.st_uid == 0) )
2076     return GNUNET_YES;
2077   return GNUNET_NO;
2078 #else
2079   rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
2080   if (INVALID_SOCKET == rawsock)
2081   {
2082     DWORD err = GetLastError ();
2083     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err);
2084     return GNUNET_NO; /* not running as administrator */
2085   }
2086   closesocket (rawsock);
2087   return GNUNET_YES;
2088 #endif
2089 }
2090
2091 /**
2092  * Function called for a quick conversion of the binary address to
2093  * a numeric address.  Note that the caller must not free the
2094  * address and that the next call to this function is allowed
2095  * to override the address again.
2096  *
2097  * @param cls closure
2098  * @param addr binary address
2099  * @param addrlen length of the address
2100  * @return string representing the same address
2101  */
2102 static const char*
2103 udp_address_to_string (void *cls,
2104                        const void *addr,
2105                        size_t addrlen)
2106 {
2107   static char rbuf[INET6_ADDRSTRLEN + 10];
2108   char buf[INET6_ADDRSTRLEN];
2109   const void *sb;
2110   struct in_addr a4;
2111   struct in6_addr a6;
2112   const struct IPv4UdpAddress *t4;
2113   const struct IPv6UdpAddress *t6;
2114   int af;
2115   uint16_t port;
2116
2117   if (addrlen == sizeof (struct IPv6UdpAddress))
2118     {
2119       t6 = addr;
2120       af = AF_INET6;
2121       port = ntohs (t6->u6_port);
2122       memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
2123       sb = &a6;
2124     }
2125   else if (addrlen == sizeof (struct IPv4UdpAddress))
2126     {
2127       t4 = addr;
2128       af = AF_INET;
2129       port = ntohs (t4->u_port);
2130       memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
2131       sb = &a4;
2132     }
2133   else
2134     return NULL;
2135   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
2136   GNUNET_snprintf (rbuf,
2137                    sizeof (rbuf),
2138                    "%s:%u",
2139                    buf,
2140                    port);
2141   return rbuf;
2142 }
2143
2144 /**
2145  * The exported method. Makes the core api available via a global and
2146  * returns the udp transport API.
2147  */
2148 void *
2149 libgnunet_plugin_transport_udp_init (void *cls)
2150 {
2151   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
2152   unsigned long long mtu;
2153   unsigned long long port;
2154   struct GNUNET_TRANSPORT_PluginFunctions *api;
2155   struct Plugin *plugin;
2156   int sockets_created;
2157   int behind_nat;
2158   int allow_nat;
2159   int only_nat_addresses;
2160   char *internal_address;
2161   char *external_address;
2162   struct IPv4UdpAddress v4_address;
2163
2164   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2165                                                          "transport-udp",
2166                                                          "BEHIND_NAT"))
2167     {
2168       /* We are behind nat (according to the user) */
2169       if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES)
2170         behind_nat = GNUNET_YES;
2171       else
2172         {
2173           behind_nat = GNUNET_NO;
2174           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");
2175         }
2176     }
2177   else
2178     behind_nat = GNUNET_NO; /* We are not behind nat! */
2179
2180   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2181                                                          "transport-udp",
2182                                                          "ALLOW_NAT"))
2183     {
2184       if (check_gnunet_nat_binary("gnunet-nat-client") == GNUNET_YES)
2185         allow_nat = GNUNET_YES; /* We will try to connect to NAT'd peers */
2186       else
2187       {
2188         allow_nat = GNUNET_NO;
2189         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");
2190       }
2191
2192     }
2193   else
2194     allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */
2195
2196   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2197                                                            "transport-udp",
2198                                                            "ONLY_NAT_ADDRESSES"))
2199     only_nat_addresses = GNUNET_YES; /* We will only report our addresses as NAT'd */
2200   else
2201     only_nat_addresses = GNUNET_NO; /* We will report our addresses as NAT'd and non-NAT'd */
2202
2203   external_address = NULL;
2204   if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK !=
2205          GNUNET_CONFIGURATION_get_value_string (env->cfg,
2206                                                 "transport-udp",
2207                                                 "EXTERNAL_ADDRESS",
2208                                                 &external_address)))
2209     {
2210       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2211                   _("Require EXTERNAL_ADDRESS for service `%s' in configuration (either BEHIND_NAT or ALLOW_NAT set to YES)!\n"),
2212                   "transport-udp");
2213       return NULL;
2214     }
2215
2216   if ((external_address != NULL) && (inet_pton(AF_INET, external_address, &v4_address.ipv4_addr) != 1))
2217     {
2218       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed EXTERNAL_ADDRESS %s given in configuration!\n", external_address);
2219     }
2220
2221   internal_address = NULL;
2222   if ((GNUNET_YES == behind_nat) && (GNUNET_OK !=
2223          GNUNET_CONFIGURATION_get_value_string (env->cfg,
2224                                                 "transport-udp",
2225                                                 "INTERNAL_ADDRESS",
2226                                                 &internal_address)))
2227     {
2228       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2229                        _("Require INTERNAL_ADDRESS for service `%s' in configuration!\n"),
2230                        "transport-udp");
2231       GNUNET_free_non_null(external_address);
2232       return NULL;
2233     }
2234
2235   if ((internal_address != NULL) && (inet_pton(AF_INET, internal_address, &v4_address.ipv4_addr) != 1))
2236     {
2237       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed INTERNAL_ADDRESS %s given in configuration!\n", internal_address);
2238     }
2239
2240   if (GNUNET_OK !=
2241       GNUNET_CONFIGURATION_get_value_number (env->cfg,
2242                                              "transport-udp",
2243                                              "PORT",
2244                                              &port))
2245     port = UDP_NAT_DEFAULT_PORT;
2246   else if (port > 65535)
2247     {
2248       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2249                   _("Given `%s' option is out of range: %llu > %u\n"),
2250                   "PORT",
2251                   port,
2252                   65535);
2253       GNUNET_free_non_null(external_address);
2254       GNUNET_free_non_null(internal_address);
2255       return NULL;
2256     }
2257
2258   mtu = 1240;
2259   if (mtu < 1200)
2260     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2261                 _("MTU %llu for `%s' is probably too low!\n"), mtu,
2262                 "UDP");
2263
2264   plugin = GNUNET_malloc (sizeof (struct Plugin));
2265   plugin->external_address = external_address;
2266   plugin->internal_address = internal_address;
2267   plugin->port = port;
2268   plugin->behind_nat = behind_nat;
2269   plugin->allow_nat = allow_nat;
2270   plugin->only_nat_addresses = only_nat_addresses;
2271   plugin->env = env;
2272
2273   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2274   api->cls = plugin;
2275
2276   api->send = &udp_plugin_send;
2277   api->disconnect = &udp_disconnect;
2278   api->address_pretty_printer = &udp_plugin_address_pretty_printer;
2279   api->address_to_string = &udp_address_to_string;
2280   api->check_address = &udp_check_address;
2281
2282   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO", &plugin->bind_address))
2283     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind_address);
2284   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO6", &plugin->bind6_address))
2285     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind6_address);
2286
2287   if (plugin->behind_nat == GNUNET_NO)
2288     {
2289       GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
2290     }
2291
2292   plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (env->cfg,
2293                                                            AF_UNSPEC,
2294                                                            HOSTNAME_RESOLVE_TIMEOUT,
2295                                                            &process_hostname_ips,
2296                                                            plugin);
2297
2298   if ((plugin->behind_nat == GNUNET_YES) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1))
2299     {
2300       v4_address.u_port = htons(0);
2301       plugin->env->notify_address (plugin->env->cls,
2302                                   "udp",
2303                                   &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL);
2304       add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t));
2305       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying plugin of address %s:0\n", plugin->external_address);
2306     }
2307   else if ((plugin->external_address != NULL) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1))
2308     {
2309       v4_address.u_port = htons(plugin->port);
2310       plugin->env->notify_address (plugin->env->cls,
2311                                   "udp",
2312                                   &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL);
2313       add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t));
2314     }
2315
2316   sockets_created = udp_transport_server_start (plugin);
2317   if (sockets_created == 0)
2318     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2319                 _("Failed to open UDP sockets\n"));
2320   return api;
2321 }
2322
2323 void *
2324 libgnunet_plugin_transport_udp_done (void *cls)
2325 {
2326   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2327   struct Plugin *plugin = api->cls;
2328   struct LocalAddrList *lal;
2329
2330   udp_transport_server_stop (plugin);
2331   if (NULL != plugin->hostname_dns)
2332     {
2333       GNUNET_RESOLVER_request_cancel (plugin->hostname_dns);
2334       plugin->hostname_dns = NULL;
2335     }
2336
2337   GNUNET_NETWORK_fdset_destroy (plugin->rs);
2338   while (NULL != (lal = plugin->lal_head))
2339     {
2340       GNUNET_CONTAINER_DLL_remove (plugin->lal_head,
2341                                    plugin->lal_tail,
2342                                    lal);
2343       GNUNET_free (lal);
2344     }
2345   GNUNET_free (plugin);
2346   GNUNET_free (api);
2347   return NULL;
2348 }
2349
2350 /* end of plugin_transport_udp.c */