this code made no sense in this context
[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_NO
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    * use local addresses?
467    */
468   int use_localaddresses;
469
470   /**
471    * The process id of the server process (if behind NAT)
472    */
473   struct GNUNET_OS_Process *server_proc;
474
475 };
476
477
478 /**
479  * Forward declaration.
480  */
481 void
482 udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result);
483
484
485 /**
486  * Disconnect from a remote node.  Clean up session if we have one for this peer
487  *
488  * @param cls closure for this call (should be handle to Plugin)
489  * @param target the peeridentity of the peer to disconnect
490  * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
491  */
492 void
493 udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
494 {
495   /** TODO: Implement! */
496   return;
497 }
498
499 /**
500  * Shutdown the server process (stop receiving inbound traffic). Maybe
501  * restarted later!
502  *
503  * @param cls Handle to the plugin for this transport
504  *
505  * @return returns the number of sockets successfully closed,
506  *         should equal the number of sockets successfully opened
507  */
508 static int
509 udp_transport_server_stop (void *cls)
510 {
511   struct Plugin *plugin = cls;
512
513   if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
514     {
515       GNUNET_SCHEDULER_cancel (plugin->select_task);
516       plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
517     }
518   if (plugin->udp_sockv4.desc != NULL)
519     {
520       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc));
521       plugin->udp_sockv4.desc = NULL;
522     }
523   if (plugin->udp_sockv6.desc != NULL)
524     {
525       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc));
526       plugin->udp_sockv6.desc = NULL;
527     }
528   if (plugin->behind_nat == GNUNET_YES)
529     {
530       if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM))
531         GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
532       GNUNET_OS_process_wait (plugin->server_proc);
533       GNUNET_OS_process_close (plugin->server_proc);
534       plugin->server_proc = NULL;
535     }
536   return GNUNET_OK;
537 }
538
539
540 struct PeerSession *
541 find_session (struct Plugin *plugin,
542               const struct GNUNET_PeerIdentity *peer)
543 {
544   struct PeerSession *pos;
545
546   pos = plugin->sessions;
547   while (pos != NULL)
548     {
549       if (memcmp(&pos->target, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
550         return pos;
551       pos = pos->next;
552     }
553
554   return pos;
555 }
556
557
558 /**
559  * Actually send out the message, assume we've got the address and
560  * send_handle squared away!
561  *
562  * @param cls closure
563  * @param send_handle which handle to send message on
564  * @param target who should receive this message (ignored by UDP)
565  * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
566  * @param msgbuf_size the size of the msgbuf to send
567  * @param priority how important is the message (ignored by UDP)
568  * @param timeout when should we time out (give up) if we can not transmit?
569  * @param addr the addr to send the message to, needs to be a sockaddr for us
570  * @param addrlen the len of addr
571  * @param cont continuation to call once the message has
572  *        been transmitted (or if the transport is ready
573  *        for the next transmission call; or if the
574  *        peer disconnected...)
575  * @param cont_cls closure for cont
576  * @return the number of bytes written
577  */
578 static ssize_t
579 udp_real_send (void *cls,
580                struct GNUNET_NETWORK_Handle *send_handle,
581                const struct GNUNET_PeerIdentity *target,
582                const char *msgbuf,
583                size_t msgbuf_size,
584                unsigned int priority,
585                struct GNUNET_TIME_Relative timeout,
586                const void *addr,
587                size_t addrlen,
588                GNUNET_TRANSPORT_TransmitContinuation cont,
589                void *cont_cls)
590 {
591   struct Plugin *plugin = cls;
592   struct UDPMessage *message;
593   int ssize;
594   ssize_t sent;
595   struct sockaddr_in a4;
596   struct sockaddr_in6 a6;
597   const struct IPv4UdpAddress *t4;
598   const struct IPv6UdpAddress *t6;
599   const void *sb;
600   size_t sbs;
601
602   if (send_handle == NULL)
603     {
604       /* failed to open send socket for AF */
605       if (cont != NULL)
606         cont (cont_cls, target, GNUNET_SYSERR);
607       return 0;
608     }
609   if ((addr == NULL) || (addrlen == 0))
610     {
611 #if DEBUG_UDP
612       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
613                        "udp_real_send called without address, returning!\n");
614 #endif
615       if (cont != NULL)
616         cont (cont_cls, target, GNUNET_SYSERR);
617       return 0; /* Can never send if we don't have an address!! */
618     }
619
620   /* Build the message to be sent */
621   message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size);
622   ssize = sizeof (struct UDPMessage) + msgbuf_size;
623
624   message->header.size = htons (ssize);
625   message->header.type = htons (0);
626   memcpy (&message->sender, plugin->env->my_identity,
627           sizeof (struct GNUNET_PeerIdentity));
628   memcpy (&message[1], msgbuf, msgbuf_size);
629
630   if (addrlen == sizeof (struct IPv6UdpAddress))
631     {
632       t6 = addr;
633       memset (&a6, 0, sizeof (a6));
634 #if HAVE_SOCKADDR_IN_SIN_LEN
635       a6.sin6_len = sizeof (a6);
636 #endif
637       a6.sin6_family = AF_INET6;
638       a6.sin6_port = t6->u6_port;
639       memcpy (&a6.sin6_addr,
640               &t6->ipv6_addr,
641               sizeof (struct in6_addr));
642       sb = &a6;
643       sbs = sizeof (a6);
644     }
645   else if (addrlen == sizeof (struct IPv4UdpAddress))
646     {
647       t4 = addr;
648       memset (&a4, 0, sizeof (a4));
649 #if HAVE_SOCKADDR_IN_SIN_LEN
650       a4.sin_len = sizeof (a4);
651 #endif
652       a4.sin_family = AF_INET;
653       a4.sin_port = t4->u_port;
654       a4.sin_addr.s_addr = t4->ipv4_addr;
655       sb = &a4;
656       sbs = sizeof (a4);
657     }
658   else
659     {
660       GNUNET_break_op (0);
661       GNUNET_free (message);
662       return -1;
663     }
664
665   /* Actually send the message */
666   sent =
667     GNUNET_NETWORK_socket_sendto (send_handle, message, ssize,
668                                   sb,
669                                   sbs);
670   if (GNUNET_SYSERR == sent)
671     GNUNET_log_strerror(GNUNET_ERROR_TYPE_DEBUG, "sendto");
672   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
673               "UDP transmit %u-byte message to %s (%d: %s)\n",
674               (unsigned int) ssize,
675               GNUNET_a2s (sb, sbs),
676               (int) sent,
677               (sent < 0) ? STRERROR (errno) : "ok");
678   if (cont != NULL)
679     {
680       if (sent == GNUNET_SYSERR)
681         cont (cont_cls, target, GNUNET_SYSERR);
682       else
683         {
684           cont (cont_cls, target, GNUNET_OK);
685         }
686     }
687
688   GNUNET_free (message);
689   return sent;
690 }
691
692 /**
693  * We learned about a peer (possibly behind NAT) so run the
694  * gnunet-nat-client to send dummy ICMP responses
695  *
696  * @param plugin the plugin for this transport
697  * @param addr the address of the peer
698  * @param addrlen the length of the address
699  */
700 void
701 run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen)
702 {
703   char addr_buf[INET_ADDRSTRLEN];
704   char *address_as_string;
705   char *port_as_string;
706   struct GNUNET_OS_Process *proc;
707   const struct IPv4UdpAddress *t4;
708
709   GNUNET_assert(addrlen == sizeof(struct IPv4UdpAddress));
710   t4 = (struct IPv4UdpAddress *)addr;
711
712   if (NULL == inet_ntop (AF_INET,
713                          &t4->ipv4_addr,
714                          addr_buf, INET_ADDRSTRLEN))
715     {
716       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
717       return;
718     }
719   address_as_string = GNUNET_strdup (addr_buf);
720   GNUNET_asprintf(&port_as_string, "%d", plugin->port);
721 #if DEBUG_UDP
722   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
723                   _("Running gnunet-nat-client with arguments: %s %s %d\n"), plugin->external_address, address_as_string, plugin->port);
724 #endif
725
726   /* Start the server process */
727   proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
728   GNUNET_free(address_as_string);
729   GNUNET_free(port_as_string);
730   if (proc != NULL)
731     {
732       GNUNET_OS_process_wait (proc);
733       GNUNET_OS_process_close (proc);
734       proc = NULL;
735     }
736 }
737
738 /**
739  * Function that can be used by the transport service to transmit
740  * a message using the plugin.
741  *
742  * @param cls closure
743  * @param target who should receive this message (ignored by UDP)
744  * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
745  * @param msgbuf_size the size of the msgbuf to send
746  * @param priority how important is the message (ignored by UDP)
747  * @param timeout when should we time out (give up) if we can not transmit?
748  * @param session identifier used for this session (can be NULL)
749  * @param addr the addr to send the message to, needs to be a sockaddr for us
750  * @param addrlen the len of addr
751  * @param force_address not used, we had better have an address to send to
752  *        because we are stateless!!
753  * @param cont continuation to call once the message has
754  *        been transmitted (or if the transport is ready
755  *        for the next transmission call; or if the
756  *        peer disconnected...)
757  * @param cont_cls closure for cont
758  *
759  * @return the number of bytes written (may return 0 and the message can
760  *         still be transmitted later!)
761  */
762 static ssize_t
763 udp_plugin_send (void *cls,
764                      const struct GNUNET_PeerIdentity *target,
765                      const char *msgbuf,
766                      size_t msgbuf_size,
767                      unsigned int priority,
768                      struct GNUNET_TIME_Relative timeout,
769                      struct Session *session,
770                      const void *addr,
771                      size_t addrlen,
772                      int force_address,
773                      GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
774 {
775   struct Plugin *plugin = cls;
776   ssize_t sent;
777   struct MessageQueue *temp_message;
778   struct PeerSession *peer_session;
779   int other_peer_natd;
780   const struct IPv4UdpAddress *t4;
781
782   if (force_address == GNUNET_SYSERR)
783     return GNUNET_SYSERR;
784   GNUNET_assert (NULL == session);
785
786   other_peer_natd = GNUNET_NO;
787   if (addrlen == sizeof(struct IPv4UdpAddress))
788     {
789       t4 = addr;
790       if (ntohs(t4->u_port) == 0)
791         other_peer_natd = GNUNET_YES;
792     }
793   else if (addrlen != sizeof(struct IPv6UdpAddress))
794     {
795       GNUNET_break_op(0);
796       return -1; /* Must have an address to send to */
797     }
798
799   sent = 0;
800   if ((other_peer_natd == GNUNET_YES) && (plugin->allow_nat == GNUNET_YES))
801     {
802       peer_session = find_session(plugin, target);
803       if (peer_session == NULL) /* We have a new peer to add */
804         {
805           /*
806            * The first time, we can assume we have no knowledge of a
807            * working port for this peer, call the ICMP/UDP message sender
808            * and wait...
809            */
810           peer_session = GNUNET_malloc(sizeof(struct PeerSession));
811           peer_session->connect_addr = GNUNET_malloc(addrlen);
812           memcpy(peer_session->connect_addr, addr, addrlen);
813           peer_session->connect_alen = addrlen;
814           peer_session->plugin = plugin;
815           peer_session->sock = NULL;
816           memcpy(&peer_session->target, target, sizeof(struct GNUNET_PeerIdentity));
817           peer_session->expecting_welcome = GNUNET_YES;
818
819           peer_session->next = plugin->sessions;
820           plugin->sessions = peer_session;
821
822           peer_session->messages = GNUNET_malloc(sizeof(struct MessageQueue));
823           peer_session->messages->msgbuf = GNUNET_malloc(msgbuf_size);
824           memcpy(peer_session->messages->msgbuf, msgbuf, msgbuf_size);
825           peer_session->messages->msgbuf_size = msgbuf_size;
826           peer_session->messages->timeout = GNUNET_TIME_relative_to_absolute(timeout);
827           peer_session->messages->cont = cont;
828           peer_session->messages->cont_cls = cont_cls;
829 #if DEBUG_UDP
830           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
831                           _("Other peer is NAT'd, set up peer session for peer %s\n"), GNUNET_i2s(target));
832 #endif
833           run_gnunet_nat_client(plugin, addr, addrlen);
834         }
835       else
836         {
837           if (peer_session->expecting_welcome == GNUNET_NO) /* We are "connected" */
838             {
839               sent = udp_real_send(cls,
840                                    peer_session->sock,
841                                    target,
842                                    msgbuf, msgbuf_size,
843                                    priority, timeout,
844                                    peer_session->connect_addr, peer_session->connect_alen,
845                                    cont, cont_cls);
846             }
847           else /* Haven't gotten a response from this peer, queue message */
848             {
849               temp_message = GNUNET_malloc(sizeof(struct MessageQueue));
850               temp_message->msgbuf = GNUNET_malloc(msgbuf_size);
851               memcpy(temp_message->msgbuf, msgbuf, msgbuf_size);
852               temp_message->msgbuf_size = msgbuf_size;
853               temp_message->timeout = GNUNET_TIME_relative_to_absolute(timeout);
854               temp_message->cont = cont;
855               temp_message->cont_cls = cont_cls;
856               temp_message->next = peer_session->messages;
857               peer_session->messages = temp_message;
858             }
859         }
860     }
861   else if (other_peer_natd == GNUNET_NO) /* Other peer not behind a NAT, so we can just send the message as is */
862     {
863       sent = udp_real_send(cls,
864                            (addrlen == sizeof (struct IPv4UdpAddress)) ? plugin->udp_sockv4.desc : plugin->udp_sockv6.desc,
865                            target,
866                            msgbuf, msgbuf_size,
867                            priority, timeout, addr, addrlen,
868                            cont, cont_cls);
869     }
870   else /* Other peer is NAT'd, but we don't want to play with them (or can't!) */
871     {
872       return GNUNET_SYSERR;
873     }
874
875   /* When GNUNET_SYSERR is returned from udp_real_send, we will still call
876    * the callback so must not return GNUNET_SYSERR!
877    * If we did, then transport context would get freed twice. */
878   if (sent == GNUNET_SYSERR)
879     return 0;
880   return sent;
881 }
882
883
884 static void
885 add_to_address_list (struct Plugin *plugin,
886                      const void *arg,
887                      size_t arg_size)
888 {
889   struct LocalAddrList *lal;
890
891   lal = plugin->lal_head;
892   while (NULL != lal)
893     {
894       if ( (lal->size == arg_size) &&
895            (0 == memcmp (&lal[1], arg, arg_size)) )
896         return;
897       lal = lal->next;
898     }
899   lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size);
900   lal->size = arg_size;
901   memcpy (&lal[1], arg, arg_size);
902   GNUNET_CONTAINER_DLL_insert (plugin->lal_head,
903                                plugin->lal_tail,
904                                lal);
905 }
906
907
908 static int
909 check_local_addr (struct Plugin *plugin,
910                   const void *arg,
911                   size_t arg_size)
912 {
913   struct LocalAddrList *lal;
914
915   lal = plugin->lal_head;
916   while (NULL != lal)
917     {
918       if ( (lal->size == arg_size) &&
919            (0 == memcmp (&lal[1], arg, arg_size)) )
920         return GNUNET_OK;
921       lal = lal->next;
922     }
923   return GNUNET_SYSERR;
924 }
925
926 static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen)
927 {
928         uint32_t res = 0;
929         int local = GNUNET_NO;
930         int af = addr->sa_family;
931     switch (af)
932     {
933       case AF_INET:
934       {
935           uint32_t netmask = 0x7F000000;
936           uint32_t address = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr);
937           res = (address >> 24) ^ (netmask >> 24);
938           if (res != 0)
939                   local = GNUNET_NO;
940           else
941                   local = GNUNET_YES;
942 #if DEBUG_UDP
943             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
944                           "Checking IPv4 address `%s': %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
945 #endif
946             break;
947       }
948       case AF_INET6:
949       {
950            if (IN6_IS_ADDR_LOOPBACK  (&((struct sockaddr_in6 *) addr)->sin6_addr) ||
951                    IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
952                    local = GNUNET_YES;
953            else
954                    local = GNUNET_NO;
955 #if DEBUG_UDP
956            GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
957                           "Checking IPv6 address `%s' : %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
958 #endif
959            break;
960       }
961     }
962         return local;
963 }
964
965
966 /**
967  * Add the IP of our network interface to the list of
968  * our external IP addresses.
969  */
970 static int
971 process_interfaces (void *cls,
972                     const char *name,
973                     int isDefault,
974                     const struct sockaddr *addr, socklen_t addrlen)
975 {
976   struct Plugin *plugin = cls;
977   int af;
978   struct IPv4UdpAddress t4;
979   struct IPv6UdpAddress t6;
980   void *arg;
981   uint16_t args;
982   void *addr_nat;
983   char buf[INET6_ADDRSTRLEN];
984
985   addr_nat = NULL;
986   af = addr->sa_family;
987
988   if (plugin->use_localaddresses == GNUNET_NO)
989   {
990           if (GNUNET_YES == check_localaddress (addr, addrlen))
991           {
992 #if DEBUG_UDP
993           GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
994                    "udp",
995                            "Not notifying transport of address `%s' (local address)\n",
996                            GNUNET_a2s (addr, addrlen));
997 #endif
998                   return GNUNET_OK;
999           }
1000   }
1001
1002   memset(buf, 0, INET6_ADDRSTRLEN);
1003   if (af == AF_INET)
1004     {
1005       t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
1006       GNUNET_assert(NULL != inet_ntop(AF_INET, &t4.ipv4_addr, &buf[0], INET_ADDRSTRLEN));
1007       if ((plugin->bind6_address != NULL) || ((plugin->bind_address != NULL) && (0 != strcmp(buf, plugin->bind_address))))
1008         {
1009           GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Not notifying transport of address %s\n", "UDP", GNUNET_a2s (addr, addrlen));
1010           return GNUNET_OK;
1011         }
1012       add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t));
1013       if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
1014         {
1015           t4.u_port = htons (DEFAULT_NAT_PORT);
1016         }
1017       else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */
1018         {
1019           addr_nat = GNUNET_malloc(sizeof(t4));
1020           t4.u_port = htons (DEFAULT_NAT_PORT);
1021           memcpy(addr_nat, &t4, sizeof(t4));
1022           t4.u_port = plugin->port;
1023         }
1024       else
1025         {
1026           t4.u_port = htons(plugin->port);
1027         }
1028       arg = &t4;
1029       args = sizeof (t4);
1030     }
1031   else if (af == AF_INET6)
1032     {
1033       if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
1034         {
1035           /* skip link local addresses */
1036           return GNUNET_OK;
1037         }
1038       memcpy (&t6.ipv6_addr,
1039               &((struct sockaddr_in6 *) addr)->sin6_addr,
1040               sizeof (struct in6_addr));
1041       GNUNET_assert(NULL != inet_ntop(AF_INET6, &t6.ipv6_addr, &buf[0], INET6_ADDRSTRLEN));
1042       if (((plugin->bind_address != NULL) && (0 != strcmp(buf, plugin->bind_address)))
1043           || ((plugin->bind6_address != NULL) && (0 != strcmp(buf, plugin->bind6_address))))
1044         {
1045           GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Not notifying transport of address %s\n", "UDP", GNUNET_a2s (addr, addrlen));
1046           return GNUNET_OK;
1047         }
1048       add_to_address_list (plugin, &t6.ipv6_addr, sizeof (struct in6_addr));
1049       if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
1050         {
1051           t6.u6_port = htons (DEFAULT_NAT_PORT);
1052         }
1053       else if (plugin->behind_nat == GNUNET_YES)
1054         {
1055           addr_nat = GNUNET_malloc(sizeof(t6));
1056           t6.u6_port = htons (DEFAULT_NAT_PORT);
1057           memcpy(addr_nat, &t6, sizeof(t6));
1058           t6.u6_port = plugin->port;
1059         }
1060       else
1061         {
1062           t6.u6_port = htons (plugin->port);
1063         }
1064
1065       arg = &t6;
1066       args = sizeof (t6);
1067     }
1068   else
1069     {
1070       GNUNET_break (0);
1071       return GNUNET_OK;
1072     }
1073
1074   GNUNET_log (GNUNET_ERROR_TYPE_INFO |
1075               GNUNET_ERROR_TYPE_BULK,
1076               _("Found address `%s' (%s)\n"),
1077               GNUNET_a2s (addr, addrlen), name);
1078
1079   if (addr_nat != NULL)
1080     {
1081       plugin->env->notify_address (plugin->env->cls,
1082                                    "udp",
1083                                    addr_nat, args, GNUNET_TIME_UNIT_FOREVER_REL);
1084       GNUNET_log (GNUNET_ERROR_TYPE_INFO |
1085                   GNUNET_ERROR_TYPE_BULK,
1086                   _("Found NAT address `%s' (%s)\n"),
1087                   GNUNET_a2s (addr_nat, args), name);
1088       GNUNET_free(addr_nat);
1089     }
1090
1091   plugin->env->notify_address (plugin->env->cls,
1092                                "udp",
1093                                arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
1094   return GNUNET_OK;
1095 }
1096
1097
1098 /**
1099  * Function called by the resolver for each address obtained from DNS
1100  * for our own hostname.  Add the addresses to the list of our
1101  * external IP addresses.
1102  *
1103  * @param cls closure
1104  * @param addr one of the addresses of the host, NULL for the last address
1105  * @param addrlen length of the address
1106  */
1107 static void
1108 process_hostname_ips (void *cls,
1109                       const struct sockaddr *addr, socklen_t addrlen)
1110 {
1111   struct Plugin *plugin = cls;
1112
1113   if (addr == NULL)
1114     {
1115       plugin->hostname_dns = NULL;
1116       return;
1117     }
1118   process_interfaces (plugin, "<hostname>", GNUNET_YES, addr, addrlen);
1119 }
1120
1121
1122 /**
1123  * Send UDP probe messages or UDP keepalive messages, depending on the
1124  * state of the connection.
1125  *
1126  * @param cls closure for this call (should be the main Plugin)
1127  * @param tc task context for running this
1128  */
1129 static void
1130 send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1131 {
1132   struct UDP_NAT_Probes *probe = cls;
1133   struct UDP_NAT_ProbeMessage message;
1134   struct Plugin *plugin = probe->plugin;
1135
1136   memset (&message, 0, sizeof (message));
1137   message.header.size = htons(sizeof(struct UDP_NAT_ProbeMessage));
1138   message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE);
1139   /* If they gave us a port, use that.  If not, try our port. */
1140   if (ntohs(probe->addr.u_port) == 0)
1141     probe->addr.u_port = htons(plugin->port);
1142
1143 #if DEBUG_UDP
1144       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1145                       _("Sending a probe to port %d\n"), ntohs(probe->addr.u_port));
1146 #endif
1147   probe->count++;
1148   udp_real_send(plugin,
1149                 plugin->udp_sockv4.desc,
1150                 NULL,
1151                 (char *)&message, ntohs(message.header.size), 0,
1152                 GNUNET_TIME_relative_get_unit(),
1153                 &probe->addr, sizeof(struct IPv4UdpAddress),
1154                 &udp_probe_continuation, probe);
1155 }
1156
1157
1158 /**
1159  * Continuation for probe sends.  If the last probe was sent
1160  * "successfully", schedule sending of another one.  If not,
1161  *
1162  */
1163 void
1164 udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result)
1165 {
1166   struct UDP_NAT_Probes *probe = cls;
1167   /*struct Plugin *plugin = probe->plugin;*/
1168
1169   if ((result == GNUNET_OK) && (probe->count < MAX_PROBES))
1170     {
1171 #if DEBUG_UDP
1172       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1173                        _("Scheduling next probe for 10000 milliseconds\n"));
1174 #endif
1175       probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 10000), &send_udp_probe_message, probe);
1176     }
1177   else /* Destroy the probe context. */
1178     {
1179 #if DEBUG_UDP
1180       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1181                       _("Sending probe didn't go well...\n"));
1182 #endif
1183     }
1184 }
1185
1186 /**
1187  * Find probe message by address
1188  *
1189  * @param plugin the plugin for this transport
1190  * @param address_string the ip address as a string
1191  */
1192 struct UDP_NAT_Probes *
1193 find_probe(struct Plugin *plugin, char * address_string)
1194 {
1195   struct UDP_NAT_Probes *pos;
1196
1197   pos = plugin->probes;
1198   while (pos != NULL)
1199     if (strcmp(pos->address_string, address_string) == 0)
1200       return pos;
1201
1202   return pos;
1203 }
1204
1205
1206 /*
1207  * @param cls the plugin handle
1208  * @param tc the scheduling context (for rescheduling this function again)
1209  *
1210  * We have been notified that gnunet-nat-server has written something to stdout.
1211  * Handle the output, then reschedule this function to be called again once
1212  * more is available.
1213  *
1214  */
1215 static void
1216 udp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1217 {
1218   struct Plugin *plugin = cls;
1219   char mybuf[40];
1220   ssize_t bytes;
1221   memset(&mybuf, 0, sizeof(mybuf));
1222   int i;
1223   struct UDP_NAT_Probes *temp_probe;
1224   int port;
1225   char *port_start;
1226   struct IPv4UdpAddress a4;
1227
1228   if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1229     return;
1230
1231   bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, &mybuf, sizeof(mybuf));
1232
1233   if (bytes < 1)
1234     {
1235 #if DEBUG_UDP
1236       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1237                       _("Finished reading from server stdout with code: %d\n"), bytes);
1238 #endif
1239       return;
1240     }
1241
1242   port_start = NULL;
1243   for (i = 0; i < sizeof(mybuf); i++)
1244     {
1245       if (mybuf[i] == '\n')
1246         mybuf[i] = '\0';
1247
1248       if ((mybuf[i] == ':') && (i + 1 < sizeof(mybuf)))
1249         {
1250           mybuf[i] = '\0';
1251           port_start = &mybuf[i + 1];
1252         }
1253     }
1254
1255   if (port_start != NULL)
1256     port = atoi(port_start);
1257   else
1258     {
1259       plugin->server_read_task =
1260            GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1261                                            plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1262       return;
1263     }
1264
1265 #if DEBUG_UDP
1266   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1267                   _("nat-server-read read: %s port %d\n"), &mybuf, port);
1268 #endif
1269
1270   /**
1271    * We have received an ICMP response, ostensibly from a non-NAT'd peer
1272    *  that wants to connect to us! Send a message to establish a connection.
1273    */
1274   if (inet_pton(AF_INET, &mybuf[0], &a4.ipv4_addr) != 1)
1275     {
1276
1277       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1278                   _("nat-server-read malformed address\n"), &mybuf, port);
1279
1280       plugin->server_read_task =
1281           GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1282                                           plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1283       return;
1284     }
1285
1286   temp_probe = find_probe(plugin, &mybuf[0]);
1287
1288   if (temp_probe == NULL)
1289     {
1290       temp_probe = GNUNET_malloc(sizeof(struct UDP_NAT_Probes));
1291       temp_probe->address_string = strdup(&mybuf[0]);
1292       GNUNET_assert (1 == inet_pton(AF_INET, &mybuf[0], &temp_probe->addr.ipv4_addr));
1293       temp_probe->addr.u_port = htons(port);
1294       temp_probe->next = plugin->probes;
1295       temp_probe->plugin = plugin;
1296       temp_probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500), &send_udp_probe_message, temp_probe);
1297       plugin->probes = temp_probe;
1298     }
1299
1300   plugin->server_read_task =
1301        GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1302                                        plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1303
1304 }
1305
1306
1307 /**
1308  * Demultiplexer for UDP NAT messages
1309  *
1310  * @param plugin the main plugin for this transport
1311  * @param sender from which peer the message was received
1312  * @param currhdr pointer to the header of the message
1313  * @param sender_addr the address from which the message was received
1314  * @param fromlen the length of the address
1315  * @param sockinfo which socket did we receive the message on
1316  */
1317 static void
1318 udp_demultiplexer(struct Plugin *plugin, 
1319                   struct GNUNET_PeerIdentity *sender,
1320                   const struct GNUNET_MessageHeader *currhdr,
1321                   const void *sender_addr,
1322                   size_t fromlen, struct UDP_Sock_Info *sockinfo)
1323 {
1324   struct UDP_NAT_ProbeMessageReply *outgoing_probe_reply;
1325   struct UDP_NAT_ProbeMessageConfirmation *outgoing_probe_confirmation;
1326   char addr_buf[INET_ADDRSTRLEN];
1327   struct UDP_NAT_Probes *outgoing_probe;
1328   struct PeerSession *peer_session;
1329   struct MessageQueue *pending_message;
1330   struct MessageQueue *pending_message_temp;
1331   uint16_t incoming_port;
1332   struct GNUNET_TRANSPORT_ATS_Information distance[2];
1333   if (memcmp(sender, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)) == 0)
1334     {
1335 #if DEBUG_UDP
1336       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp",
1337                       _("Received a message from myself, dropping!!!\n"));
1338 #endif
1339       return;
1340     }
1341
1342   incoming_port = 0;
1343   GNUNET_assert(sender_addr != NULL); /* Can recvfrom have a NULL address? */
1344   if (fromlen == sizeof(struct IPv4UdpAddress))
1345     {
1346       incoming_port = ntohs(((struct IPv4UdpAddress *)sender_addr)->u_port);
1347     }
1348   else if (fromlen == sizeof(struct IPv6UdpAddress))
1349     {
1350       incoming_port = ntohs(((struct IPv6UdpAddress *)sender_addr)->u6_port);
1351     }
1352
1353   switch (ntohs(currhdr->type))
1354   {
1355     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE:
1356       /* Send probe reply */
1357       outgoing_probe_reply = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageReply));
1358       outgoing_probe_reply->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageReply));
1359       outgoing_probe_reply->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_REPLY);
1360
1361 #if DEBUG_UDP
1362       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1363                   _("Received a probe on listen port %d, sent_from port %d\n"),
1364                    sockinfo->port, incoming_port);
1365 #endif
1366
1367       udp_real_send(plugin, sockinfo->desc, NULL,
1368                     (char *)outgoing_probe_reply,
1369                     ntohs(outgoing_probe_reply->header.size), 0,
1370                     GNUNET_TIME_relative_get_unit(),
1371                     sender_addr, fromlen,
1372                     NULL, NULL);
1373
1374 #if DEBUG_UDP
1375       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1376                   _("Sent PROBE REPLY to port %d on outgoing port %d\n"),
1377                    incoming_port, sockinfo->port);
1378 #endif
1379       GNUNET_free(outgoing_probe_reply);
1380       break;
1381     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_REPLY:
1382       /* Check for existing probe, check ports returned, send confirmation if all is well */
1383 #if DEBUG_UDP
1384       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1385                   _("Received PROBE REPLY from port %d on incoming port %d\n"), incoming_port, sockinfo->port);
1386 #endif
1387       if (fromlen == sizeof(struct IPv4UdpAddress))
1388         {
1389           memset(&addr_buf, 0, sizeof(addr_buf));
1390           if (NULL == inet_ntop (AF_INET,
1391                                  &((struct IPv4UdpAddress *) sender_addr)->ipv4_addr, addr_buf,
1392                                  INET_ADDRSTRLEN))
1393             {
1394               GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
1395               return;
1396             }
1397           outgoing_probe = find_probe(plugin, &addr_buf[0]);
1398           if (outgoing_probe != NULL)
1399             {
1400 #if DEBUG_UDP
1401               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1402                           _("Sending confirmation that we were reached!\n"));
1403 #endif
1404               outgoing_probe_confirmation = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageConfirmation));
1405               outgoing_probe_confirmation->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageConfirmation));
1406               outgoing_probe_confirmation->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM);
1407               udp_real_send(plugin, sockinfo->desc, NULL,
1408                             (char *)outgoing_probe_confirmation,
1409                             ntohs(outgoing_probe_confirmation->header.size), 0,
1410                             GNUNET_TIME_relative_get_unit(),
1411                             sender_addr, fromlen, NULL, NULL);
1412
1413               if (outgoing_probe->task != GNUNET_SCHEDULER_NO_TASK)
1414                 {
1415                   GNUNET_SCHEDULER_cancel(outgoing_probe->task);
1416                   outgoing_probe->task = GNUNET_SCHEDULER_NO_TASK;
1417                   /* Schedule task to timeout and remove probe if confirmation not received */
1418                 }
1419               GNUNET_free(outgoing_probe_confirmation);
1420             }
1421           else
1422             {
1423 #if DEBUG_UDP
1424               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1425                           _("Received a probe reply, but have no record of a sent probe!\n"));
1426 #endif
1427             }
1428         }
1429       else
1430         {
1431 #if DEBUG_UDP
1432           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1433                       _("Received a probe reply, but sender address size is WRONG (should be %d, is %d)!\n"), sizeof(struct IPv4UdpAddress), fromlen);
1434 #endif
1435         }
1436       break;
1437     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM:
1438       peer_session = find_session(plugin, sender);
1439 #if DEBUG_UDP
1440           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1441                       _("Looking up peer session for peer %s\n"), GNUNET_i2s(sender));
1442 #endif
1443       if (peer_session == NULL) /* Shouldn't this NOT happen? */
1444         {
1445 #if DEBUG_UDP
1446           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1447                       _("Peer not in list, adding (THIS MAY BE A MISTAKE) %s\n"), GNUNET_i2s(sender));
1448 #endif
1449           peer_session = GNUNET_malloc(sizeof(struct PeerSession));
1450           peer_session->connect_addr = GNUNET_malloc(fromlen);
1451           memcpy(peer_session->connect_addr, sender_addr, fromlen);
1452           peer_session->connect_alen = fromlen;
1453           peer_session->plugin = plugin;
1454           peer_session->sock = sockinfo->desc;
1455           memcpy(&peer_session->target, sender, sizeof(struct GNUNET_PeerIdentity));
1456           peer_session->expecting_welcome = GNUNET_NO;
1457
1458           peer_session->next = plugin->sessions;
1459           plugin->sessions = peer_session;
1460
1461           peer_session->messages = NULL;
1462         }
1463       else if (peer_session->expecting_welcome == GNUNET_YES)
1464         {
1465           peer_session->expecting_welcome = GNUNET_NO;
1466           peer_session->sock = sockinfo->desc;
1467           if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress))
1468             {
1469               ((struct IPv4UdpAddress *)peer_session->connect_addr)->u_port = htons(incoming_port);
1470             }
1471           else if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress))
1472             {
1473               ((struct IPv6UdpAddress *)peer_session->connect_addr)->u6_port = htons(incoming_port);
1474             }
1475
1476 #if DEBUG_UDP
1477               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1478                           _("Received a probe confirmation, will send to peer on port %d\n"), incoming_port);
1479 #endif
1480           if (peer_session->messages != NULL)
1481             {
1482 #if DEBUG_UDP
1483               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1484                           _("Received a probe confirmation, sending queued messages.\n"));
1485 #endif
1486               pending_message = peer_session->messages;
1487               int count = 0;
1488               while (pending_message != NULL)
1489                 {
1490 #if DEBUG_UDP
1491                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1492                               _("sending queued message %d\n"), count);
1493 #endif
1494                   udp_real_send(plugin,
1495                                 peer_session->sock,
1496                                 &peer_session->target,
1497                                 pending_message->msgbuf,
1498                                 pending_message->msgbuf_size, 0,
1499                                 GNUNET_TIME_relative_get_unit(),
1500                                 peer_session->connect_addr,
1501                                 peer_session->connect_alen,
1502                                 pending_message->cont,
1503                                 pending_message->cont_cls);
1504
1505                   pending_message_temp = pending_message;
1506                   pending_message = pending_message->next;
1507                   GNUNET_free(pending_message_temp->msgbuf);
1508                   GNUNET_free(pending_message_temp);
1509 #if DEBUG_UDP
1510                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1511                               _("finished sending queued message %d\n"), count);
1512 #endif
1513                   count++;
1514                 }
1515             }
1516
1517         }
1518       else
1519         {
1520 #if DEBUG_UDP
1521           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1522                       _("Received probe confirmation for already confirmed peer!\n"));
1523 #endif
1524         }
1525       /* Received confirmation, add peer with address/port specified */
1526       break;
1527     case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_KEEPALIVE:
1528       /* Once we've sent NAT_PROBE_CONFIRM change to sending keepalives */
1529       /* If we receive these just ignore! */
1530       break;
1531     default:
1532
1533 #if DEBUG_UDP
1534       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1535                   "Sending message type %d to transport!\n",
1536                   ntohs(currhdr->type));
1537 #endif
1538
1539       distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
1540       distance[0].value = htonl (UDP_DIRECT_DISTANCE);
1541       distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
1542       distance[1].value = htonl (0);
1543
1544       plugin->env->receive (plugin->env->cls, sender, currhdr,
1545                     (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2,
1546                             NULL, sender_addr, fromlen);
1547   }
1548
1549 }
1550
1551
1552 /*
1553  * @param cls the plugin handle
1554  * @param tc the scheduling context (for rescheduling this function again)
1555  *
1556  * We have been notified that our writeset has something to read.  We don't
1557  * know which socket needs to be read, so we have to check each one
1558  * Then reschedule this function to be called again once more is available.
1559  *
1560  */
1561 static void
1562 udp_plugin_select (void *cls,
1563                    const struct GNUNET_SCHEDULER_TaskContext *tc)
1564 {
1565   struct Plugin *plugin = cls;
1566   char buf[65536];
1567   struct UDPMessage *msg;
1568   struct GNUNET_PeerIdentity sender;
1569   socklen_t fromlen;
1570   char addr[32];
1571   ssize_t ret;
1572   int offset;
1573   int tsize;
1574   char *msgbuf;
1575   const struct GNUNET_MessageHeader *currhdr;
1576   struct IPv4UdpAddress t4;
1577   struct IPv6UdpAddress t6;
1578   const struct sockaddr_in *s4;
1579   const struct sockaddr_in6 *s6;
1580   const void *ca;
1581   size_t calen;
1582   struct UDP_Sock_Info *udp_sock;
1583   uint16_t csize;
1584
1585   plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
1586   if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1587     return;
1588   udp_sock = NULL;
1589   if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1590                                   plugin->udp_sockv4.desc))
1591     udp_sock = &plugin->udp_sockv4;
1592   else if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1593                                        plugin->udp_sockv6.desc))
1594     udp_sock = &plugin->udp_sockv6;
1595   if (NULL == udp_sock)
1596     {
1597       GNUNET_break (0);
1598       return;
1599     }
1600   fromlen = sizeof (addr);
1601   memset (&addr, 0, sizeof(addr));
1602   ret =
1603     GNUNET_NETWORK_socket_recvfrom (udp_sock->desc, buf, sizeof (buf),
1604                                     (struct sockaddr *)&addr, &fromlen);
1605
1606   if (AF_INET == ((struct sockaddr *)addr)->sa_family)
1607     {
1608       s4 = (const struct sockaddr_in*) &addr;
1609       t4.u_port = s4->sin_port;
1610       t4.ipv4_addr = s4->sin_addr.s_addr;
1611       ca = &t4;
1612       calen = sizeof (t4);
1613     }
1614   else if (AF_INET6 == ((struct sockaddr *)addr)->sa_family)
1615     {
1616       s6 = (const struct sockaddr_in6*) &addr;
1617       t6.u6_port = s6->sin6_port;
1618       memcpy (&t6.ipv6_addr,
1619               &s6->sin6_addr,
1620               sizeof (struct in6_addr));
1621       ca = &t6;
1622       calen = sizeof (t6);
1623     }
1624   else
1625     {
1626       GNUNET_break (0);
1627       ca = NULL;
1628       calen = 0;
1629     }
1630   if (ret < sizeof (struct UDPMessage))
1631     {
1632       GNUNET_break_op (0);
1633       plugin->select_task =
1634         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1635                                      GNUNET_SCHEDULER_NO_TASK,
1636                                      GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1637                                      NULL, &udp_plugin_select, plugin);
1638       return;
1639     }
1640   msg = (struct UDPMessage *) buf;
1641   csize = ntohs (msg->header.size);
1642   if ( (csize < sizeof (struct UDPMessage)) ||
1643        (csize > ret) )
1644     {
1645       GNUNET_break_op (0);
1646       plugin->select_task =
1647         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1648                                      GNUNET_SCHEDULER_NO_TASK,
1649                                      GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1650                                      NULL, &udp_plugin_select, plugin);
1651       return;
1652     }
1653   msgbuf = (char *)&msg[1];
1654   memcpy (&sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity));
1655   offset = 0;
1656   tsize = csize - sizeof (struct UDPMessage);
1657   while (offset + sizeof (struct GNUNET_MessageHeader) <= tsize)
1658     {
1659       currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
1660       csize = ntohs (currhdr->size);
1661       if ( (csize < sizeof (struct GNUNET_MessageHeader)) ||
1662            (csize > tsize - offset) )
1663         {
1664           GNUNET_break_op (0);
1665           break;
1666         }
1667       udp_demultiplexer(plugin, &sender, currhdr, 
1668                         ca, calen, udp_sock);
1669       offset += csize;
1670     }
1671   plugin->select_task =
1672     GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1673                                  GNUNET_SCHEDULER_NO_TASK,
1674                                  GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1675                                  NULL, &udp_plugin_select, plugin);
1676
1677 }
1678
1679 /**
1680  * Create a slew of UDP sockets.  If possible, use IPv6 and IPv4.
1681  *
1682  * @param cls closure for server start, should be a struct Plugin *
1683  * @return number of sockets created or GNUNET_SYSERR on error
1684 */
1685 static int
1686 udp_transport_server_start (void *cls)
1687 {
1688   struct Plugin *plugin = cls;
1689   struct sockaddr_in serverAddrv4;
1690   struct sockaddr_in6 serverAddrv6;
1691   struct sockaddr *serverAddr;
1692   socklen_t addrlen;
1693   int sockets_created;
1694   int tries;
1695
1696
1697   sockets_created = 0;
1698   if (plugin->behind_nat == GNUNET_YES)
1699     {
1700       /* Pipe to read from started processes stdout (on read end) */
1701       plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES);
1702       if (plugin->server_stdout == NULL)
1703         return sockets_created;
1704 #if DEBUG_UDP
1705       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1706                   "Starting gnunet-nat-server process cmd: %s %s\n",
1707                   "gnunet-nat-server",
1708                   plugin->internal_address);
1709 #endif
1710       /* Start the server process */
1711       plugin->server_proc = GNUNET_OS_start_process(NULL,
1712                                                    plugin->server_stdout,
1713                                                    "gnunet-nat-server",
1714                                                    "gnunet-nat-server",
1715                                                    plugin->internal_address, NULL);
1716       if (plugin->server_proc == NULL)
1717         {
1718 #if DEBUG_UDP
1719           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1720                       "Failed to start gnunet-nat-server process\n");
1721 #endif
1722           return GNUNET_SYSERR;
1723         }
1724       /* Close the write end of the read pipe */
1725       GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
1726
1727       plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ);
1728       plugin->server_read_task =
1729         GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1730                                         plugin->server_stdout_handle, &udp_plugin_server_read, plugin);
1731     }
1732
1733   if ( (GNUNET_YES !=
1734         GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "transport-udp",
1735                                               "DISABLEV6")))
1736     {
1737       plugin->udp_sockv6.desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0);
1738       if (NULL == plugin->udp_sockv6.desc)
1739         {
1740           GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket");
1741         }
1742       else
1743         {
1744           memset (&serverAddrv6, 0, sizeof (serverAddrv6));
1745 #if HAVE_SOCKADDR_IN_SIN_LEN
1746           serverAddrv6.sin6_len = sizeof (serverAddrv6);
1747 #endif
1748
1749           serverAddrv6.sin6_family = AF_INET6;
1750           serverAddrv6.sin6_addr = in6addr_any;
1751           if (plugin->bind6_address != NULL)
1752             {
1753               if (1 != inet_pton(AF_INET6, plugin->bind6_address, &serverAddrv6.sin6_addr))
1754                 return 0;
1755             }
1756
1757           serverAddrv6.sin6_port = htons (plugin->port);
1758           addrlen = sizeof (serverAddrv6);
1759           serverAddr = (struct sockaddr *) &serverAddrv6;
1760 #if DEBUG_UDP
1761           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1762                            "Binding to IPv6 port %d\n",
1763                            ntohs(serverAddrv6.sin6_port));
1764 #endif
1765           tries = 0;
1766           while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv6.desc, serverAddr, addrlen) !=
1767                  GNUNET_OK)
1768             {
1769               serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */
1770 #if DEBUG_UDP
1771               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1772                                "IPv6 Binding failed, trying new port %d\n",
1773                                ntohs(serverAddrv6.sin6_port));
1774 #endif
1775               tries++;
1776               if (tries > 10)
1777                 {
1778                   GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc);
1779                   plugin->udp_sockv6.desc = NULL;
1780                   break;
1781                 }       
1782             }
1783           if (plugin->udp_sockv6.desc != NULL)
1784             {
1785               plugin->udp_sockv6.port = ntohs(serverAddrv6.sin6_port);
1786               sockets_created++;
1787             }
1788         }
1789     }
1790
1791   plugin->udp_sockv4.desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
1792   if (NULL == plugin->udp_sockv4.desc)
1793     {
1794       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket");
1795     }
1796   else
1797     {
1798       memset (&serverAddrv4, 0, sizeof (serverAddrv4));
1799 #if HAVE_SOCKADDR_IN_SIN_LEN
1800       serverAddrv4.sin_len = sizeof (serverAddrv4);
1801 #endif
1802       serverAddrv4.sin_family = AF_INET;
1803       serverAddrv4.sin_addr.s_addr = INADDR_ANY;
1804       if (plugin->bind_address != NULL)
1805         {
1806           if (1 != inet_pton(AF_INET, plugin->bind_address, &serverAddrv4.sin_addr))
1807             return 0;
1808         }
1809       serverAddrv4.sin_port = htons (plugin->port);
1810       addrlen = sizeof (serverAddrv4);
1811       serverAddr = (struct sockaddr *) &serverAddrv4;
1812 #if DEBUG_UDP
1813       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1814                        "Binding to IPv4 port %d\n",
1815                        ntohs(serverAddrv4.sin_port));
1816 #endif
1817       tries = 0;
1818       while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv4.desc, serverAddr, addrlen) !=
1819              GNUNET_OK)
1820         {
1821           serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */
1822 #if DEBUG_UDP
1823           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1824                            "IPv4 Binding failed, trying new port %d\n",
1825                            ntohs(serverAddrv4.sin_port));
1826 #endif
1827           tries++;
1828           if (tries > 10)
1829             {
1830               GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc);
1831               plugin->udp_sockv4.desc = NULL;
1832               break;
1833             }   
1834         }
1835       if (plugin->udp_sockv4.desc != NULL)
1836         {
1837           plugin->udp_sockv4.port = ntohs(serverAddrv4.sin_port);
1838           sockets_created++;
1839         }
1840     }
1841
1842   plugin->rs = GNUNET_NETWORK_fdset_create ();
1843   GNUNET_NETWORK_fdset_zero (plugin->rs);
1844   if (NULL != plugin->udp_sockv4.desc)
1845     GNUNET_NETWORK_fdset_set (plugin->rs,
1846                               plugin->udp_sockv4.desc);
1847   if (NULL != plugin->udp_sockv6.desc)
1848     GNUNET_NETWORK_fdset_set (plugin->rs,
1849                               plugin->udp_sockv6.desc);
1850
1851   plugin->select_task =
1852     GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1853                                  GNUNET_SCHEDULER_NO_TASK,
1854                                  GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
1855                                  NULL, &udp_plugin_select, plugin);
1856   return sockets_created;
1857 }
1858
1859
1860
1861 /**
1862  * Check if the given port is plausible (must be either
1863  * our listen port or our advertised port).  If it is
1864  * neither, we return GNUNET_SYSERR.
1865  *
1866  * @param plugin global variables
1867  * @param in_port port number to check
1868  * @return GNUNET_OK if port is either open_port or adv_port
1869  */
1870 static int
1871 check_port (struct Plugin *plugin, uint16_t in_port)
1872 {
1873   if ( (plugin->behind_nat == GNUNET_YES) && (in_port == 0) )
1874     return GNUNET_OK;
1875   if ( (plugin->only_nat_addresses == GNUNET_YES) &&
1876        (plugin->behind_nat == GNUNET_YES) )
1877     return GNUNET_SYSERR; /* odd case... */
1878   if (in_port == plugin->port)
1879     return GNUNET_OK;
1880   return GNUNET_SYSERR;
1881 }
1882
1883
1884 /**
1885  * Function that will be called to check if a binary address for this
1886  * plugin is well-formed and corresponds to an address for THIS peer
1887  * (as per our configuration).  Naturally, if absolutely necessary,
1888  * plugins can be a bit conservative in their answer, but in general
1889  * plugins should make sure that the address does not redirect
1890  * traffic to a 3rd party that might try to man-in-the-middle our
1891  * traffic.
1892  *
1893  * @param cls closure, should be our handle to the Plugin
1894  * @param addr pointer to the address
1895  * @param addrlen length of addr
1896  * @return GNUNET_OK if this is a plausible address for this peer
1897  *         and transport, GNUNET_SYSERR if not
1898  *
1899  */
1900 static int
1901 udp_check_address (void *cls,
1902                    const void *addr,
1903                    size_t addrlen)
1904 {
1905   struct Plugin *plugin = cls;
1906
1907   const void *sb;
1908   struct in_addr a4;
1909   struct in6_addr a6;
1910   int af;
1911   struct IPv4UdpAddress *v4;
1912   struct IPv6UdpAddress *v6;
1913
1914   if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
1915       (addrlen != sizeof (struct IPv6UdpAddress)))
1916     {
1917       GNUNET_break_op (0);
1918       return GNUNET_SYSERR;
1919     }
1920
1921   if (addrlen == sizeof (struct IPv4UdpAddress))
1922     {
1923       v4 = (struct IPv4UdpAddress *) addr;
1924       if (GNUNET_OK !=
1925           check_port (plugin, ntohs (v4->u_port)))
1926         return GNUNET_SYSERR;
1927       if (GNUNET_OK !=
1928           check_local_addr (plugin, &v4->ipv4_addr, sizeof (uint32_t)))
1929         return GNUNET_SYSERR;
1930
1931       af = AF_INET;
1932       memcpy (&a4, &v4->ipv4_addr, sizeof (a4));
1933       sb = &a4;
1934     }
1935   else
1936     {
1937       v6 = (struct IPv6UdpAddress *) addr;
1938       if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
1939         {
1940           GNUNET_break_op (0);
1941           return GNUNET_SYSERR;
1942         }
1943       if (GNUNET_OK !=
1944           check_port (plugin, ntohs (v6->u6_port)))
1945         return GNUNET_SYSERR;
1946       if (GNUNET_OK !=
1947           check_local_addr (plugin, &v6->ipv6_addr, sizeof (struct in6_addr)))
1948         return GNUNET_SYSERR;
1949
1950       af = AF_INET6;
1951       memcpy (&a6, &v6->ipv6_addr, sizeof (a6));
1952       sb = &a6;
1953     }
1954
1955   return GNUNET_OK;
1956 }
1957
1958
1959 /**
1960  * Append our port and forward the result.
1961  */
1962 static void
1963 append_port (void *cls, const char *hostname)
1964 {
1965   struct PrettyPrinterContext *ppc = cls;
1966   char *ret;
1967
1968   if (hostname == NULL)
1969     {
1970       ppc->asc (ppc->asc_cls, NULL);
1971       GNUNET_free (ppc);
1972       return;
1973     }
1974   GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
1975   ppc->asc (ppc->asc_cls, ret);
1976   GNUNET_free (ret);
1977 }
1978
1979
1980 /**
1981  * Convert the transports address to a nice, human-readable
1982  * format.
1983  *
1984  * @param cls closure
1985  * @param type name of the transport that generated the address
1986  * @param addr one of the addresses of the host, NULL for the last address
1987  *        the specific address format depends on the transport
1988  * @param addrlen length of the address
1989  * @param numeric should (IP) addresses be displayed in numeric form?
1990  * @param timeout after how long should we give up?
1991  * @param asc function to call on each string
1992  * @param asc_cls closure for asc
1993  */
1994 static void
1995 udp_plugin_address_pretty_printer (void *cls,
1996                                    const char *type,
1997                                    const void *addr,
1998                                    size_t addrlen,
1999                                    int numeric,
2000                                    struct GNUNET_TIME_Relative timeout,
2001                                    GNUNET_TRANSPORT_AddressStringCallback asc,
2002                                    void *asc_cls)
2003 {
2004   struct Plugin *plugin = cls;
2005   struct PrettyPrinterContext *ppc;
2006   const void *sb;
2007   size_t sbs;
2008   struct sockaddr_in a4;
2009   struct sockaddr_in6 a6;
2010   const struct IPv4UdpAddress *u4;
2011   const struct IPv6UdpAddress *u6;
2012   uint16_t port;
2013
2014   if (addrlen == sizeof (struct IPv6UdpAddress))
2015     {
2016       u6 = addr;
2017       memset (&a6, 0, sizeof (a6));
2018       a6.sin6_family = AF_INET6;
2019       a6.sin6_port = u6->u6_port;
2020       memcpy (&a6.sin6_addr,
2021               &u6->ipv6_addr,
2022               sizeof (struct in6_addr));
2023       port = ntohs (u6->u6_port);
2024       sb = &a6;
2025       sbs = sizeof (a6);
2026     }
2027   else if (addrlen == sizeof (struct IPv4UdpAddress))
2028     {
2029       u4 = addr;
2030       memset (&a4, 0, sizeof (a4));
2031       a4.sin_family = AF_INET;
2032       a4.sin_port = u4->u_port;
2033       a4.sin_addr.s_addr = u4->ipv4_addr;
2034       port = ntohs (u4->u_port);
2035       sb = &a4;
2036       sbs = sizeof (a4);
2037     }
2038   else
2039     {
2040       /* invalid address */
2041       GNUNET_break_op (0);
2042       asc (asc_cls, NULL);
2043       return;
2044     }
2045   ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
2046   ppc->asc = asc;
2047   ppc->asc_cls = asc_cls;
2048   ppc->port = port;
2049   GNUNET_RESOLVER_hostname_get (plugin->env->cfg,
2050                                 sb,
2051                                 sbs,
2052                                 !numeric, timeout, &append_port, ppc);
2053 }
2054
2055 /**
2056  * Return the actual path to a file found in the current
2057  * PATH environment variable.
2058  *
2059  * @param binary the name of the file to find
2060  */
2061 static char *
2062 get_path_from_PATH (char *binary)
2063 {
2064   char *path;
2065   char *pos;
2066   char *end;
2067   char *buf;
2068   const char *p;
2069
2070   p = getenv ("PATH");
2071   if (p == NULL)
2072     return NULL;
2073   path = GNUNET_strdup (p);     /* because we write on it */
2074   buf = GNUNET_malloc (strlen (path) + 20);
2075   pos = path;
2076
2077   while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
2078     {
2079       *end = '\0';
2080       sprintf (buf, "%s/%s", pos, binary);
2081       if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
2082         {
2083           GNUNET_free (path);
2084           return buf;
2085         }
2086       pos = end + 1;
2087     }
2088   sprintf (buf, "%s/%s", pos, binary);
2089   if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
2090     {
2091       GNUNET_free (path);
2092       return buf;
2093     }
2094   GNUNET_free (buf);
2095   GNUNET_free (path);
2096   return NULL;
2097 }
2098
2099 /**
2100  * Check whether the suid bit is set on a file.
2101  * Attempts to find the file using the current
2102  * PATH environment variable as a search path.
2103  *
2104  * @param binary the name of the file to check
2105  */
2106 static int
2107 check_gnunet_nat_binary(char *binary)
2108 {
2109   struct stat statbuf;
2110   char *p;
2111 #ifdef MINGW
2112   SOCKET rawsock;
2113 #endif
2114
2115 #ifdef MINGW
2116   char *binaryexe;
2117   GNUNET_asprintf (&binaryexe, "%s.exe", binary);
2118   p = get_path_from_PATH (binaryexe);
2119   free (binaryexe);
2120 #else
2121   p = get_path_from_PATH (binary);
2122 #endif
2123   if (p == NULL)
2124     return GNUNET_NO;
2125   if (0 != STAT (p, &statbuf))
2126     {
2127       GNUNET_free (p);
2128       return GNUNET_SYSERR;
2129     }
2130   GNUNET_free (p);
2131 #ifndef MINGW
2132   if ( (0 != (statbuf.st_mode & S_ISUID)) &&
2133        (statbuf.st_uid == 0) )
2134     return GNUNET_YES;
2135   return GNUNET_NO;
2136 #else
2137   rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
2138   if (INVALID_SOCKET == rawsock)
2139   {
2140     DWORD err = GetLastError ();
2141     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err);
2142     return GNUNET_NO; /* not running as administrator */
2143   }
2144   closesocket (rawsock);
2145   return GNUNET_YES;
2146 #endif
2147 }
2148
2149 /**
2150  * Function called for a quick conversion of the binary address to
2151  * a numeric address.  Note that the caller must not free the
2152  * address and that the next call to this function is allowed
2153  * to override the address again.
2154  *
2155  * @param cls closure
2156  * @param addr binary address
2157  * @param addrlen length of the address
2158  * @return string representing the same address
2159  */
2160 static const char*
2161 udp_address_to_string (void *cls,
2162                        const void *addr,
2163                        size_t addrlen)
2164 {
2165   static char rbuf[INET6_ADDRSTRLEN + 10];
2166   char buf[INET6_ADDRSTRLEN];
2167   const void *sb;
2168   struct in_addr a4;
2169   struct in6_addr a6;
2170   const struct IPv4UdpAddress *t4;
2171   const struct IPv6UdpAddress *t6;
2172   int af;
2173   uint16_t port;
2174
2175   if (addrlen == sizeof (struct IPv6UdpAddress))
2176     {
2177       t6 = addr;
2178       af = AF_INET6;
2179       port = ntohs (t6->u6_port);
2180       memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
2181       sb = &a6;
2182     }
2183   else if (addrlen == sizeof (struct IPv4UdpAddress))
2184     {
2185       t4 = addr;
2186       af = AF_INET;
2187       port = ntohs (t4->u_port);
2188       memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
2189       sb = &a4;
2190     }
2191   else
2192     return NULL;
2193   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
2194   GNUNET_snprintf (rbuf,
2195                    sizeof (rbuf),
2196                    "%s:%u",
2197                    buf,
2198                    port);
2199   return rbuf;
2200 }
2201
2202 /**
2203  * The exported method. Makes the core api available via a global and
2204  * returns the udp transport API.
2205  */
2206 void *
2207 libgnunet_plugin_transport_udp_init (void *cls)
2208 {
2209   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
2210   unsigned long long mtu;
2211   unsigned long long port;
2212   struct GNUNET_TRANSPORT_PluginFunctions *api;
2213   struct Plugin *plugin;
2214   int sockets_created;
2215   int behind_nat;
2216   int allow_nat;
2217   int only_nat_addresses;
2218   int use_localaddresses;
2219   char *internal_address;
2220   char *external_address;
2221   struct IPv4UdpAddress v4_address;
2222
2223   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2224                                                          "transport-udp",
2225                                                          "BEHIND_NAT"))
2226     {
2227       /* We are behind nat (according to the user) */
2228       if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES)
2229         behind_nat = GNUNET_YES;
2230       else
2231         {
2232           behind_nat = GNUNET_NO;
2233           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");
2234         }
2235     }
2236   else
2237     behind_nat = GNUNET_NO; /* We are not behind nat! */
2238
2239   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2240                                                          "transport-udp",
2241                                                          "ALLOW_NAT"))
2242     {
2243       if (check_gnunet_nat_binary("gnunet-nat-client") == GNUNET_YES)
2244         allow_nat = GNUNET_YES; /* We will try to connect to NAT'd peers */
2245       else
2246       {
2247         allow_nat = GNUNET_NO;
2248         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");
2249       }
2250
2251     }
2252   else
2253     allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */
2254
2255   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2256                                                            "transport-udp",
2257                                                            "ONLY_NAT_ADDRESSES"))
2258     only_nat_addresses = GNUNET_YES; /* We will only report our addresses as NAT'd */
2259   else
2260     only_nat_addresses = GNUNET_NO; /* We will report our addresses as NAT'd and non-NAT'd */
2261
2262   external_address = NULL;
2263   if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK !=
2264          GNUNET_CONFIGURATION_get_value_string (env->cfg,
2265                                                 "transport-udp",
2266                                                 "EXTERNAL_ADDRESS",
2267                                                 &external_address)))
2268     {
2269       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2270                   _("Require EXTERNAL_ADDRESS for service `%s' in configuration (either BEHIND_NAT or ALLOW_NAT set to YES)!\n"),
2271                   "transport-udp");
2272       return NULL;
2273     }
2274
2275   if ((external_address != NULL) && (inet_pton(AF_INET, external_address, &v4_address.ipv4_addr) != 1))
2276     {
2277       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed EXTERNAL_ADDRESS %s given in configuration!\n", external_address);
2278     }
2279
2280   internal_address = NULL;
2281   if ((GNUNET_YES == behind_nat) && (GNUNET_OK !=
2282          GNUNET_CONFIGURATION_get_value_string (env->cfg,
2283                                                 "transport-udp",
2284                                                 "INTERNAL_ADDRESS",
2285                                                 &internal_address)))
2286     {
2287       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2288                        _("Require INTERNAL_ADDRESS for service `%s' in configuration!\n"),
2289                        "transport-udp");
2290       GNUNET_free_non_null(external_address);
2291       return NULL;
2292     }
2293
2294   if ((internal_address != NULL) && (inet_pton(AF_INET, internal_address, &v4_address.ipv4_addr) != 1))
2295     {
2296       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed INTERNAL_ADDRESS %s given in configuration!\n", internal_address);
2297     }
2298
2299   if (GNUNET_OK !=
2300       GNUNET_CONFIGURATION_get_value_number (env->cfg,
2301                                              "transport-udp",
2302                                              "PORT",
2303                                              &port))
2304     port = UDP_NAT_DEFAULT_PORT;
2305   else if (port > 65535)
2306     {
2307       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2308                   _("Given `%s' option is out of range: %llu > %u\n"),
2309                   "PORT",
2310                   port,
2311                   65535);
2312       GNUNET_free_non_null(external_address);
2313       GNUNET_free_non_null(internal_address);
2314       return NULL;
2315     }
2316
2317   mtu = 1240;
2318   if (mtu < 1200)
2319     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2320                 _("MTU %llu for `%s' is probably too low!\n"), mtu,
2321                 "UDP");
2322
2323   use_localaddresses = GNUNET_NO;
2324   if (GNUNET_CONFIGURATION_have_value (env->cfg,
2325                   "transport-udp", "USE_LOCALADDR"))
2326     {
2327       use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2328                                                                    "transport-udp",
2329                                                                "USE_LOCALADDR");
2330     }
2331
2332   plugin = GNUNET_malloc (sizeof (struct Plugin));
2333   plugin->external_address = external_address;
2334   plugin->internal_address = internal_address;
2335   plugin->port = port;
2336   plugin->behind_nat = behind_nat;
2337   plugin->allow_nat = allow_nat;
2338   plugin->only_nat_addresses = only_nat_addresses;
2339   plugin->env = env;
2340   plugin->use_localaddresses = use_localaddresses;
2341
2342   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2343   api->cls = plugin;
2344
2345   api->send = &udp_plugin_send;
2346   api->disconnect = &udp_disconnect;
2347   api->address_pretty_printer = &udp_plugin_address_pretty_printer;
2348   api->address_to_string = &udp_address_to_string;
2349   api->check_address = &udp_check_address;
2350
2351   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO", &plugin->bind_address))
2352     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind_address);
2353   if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO6", &plugin->bind6_address))
2354     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind6_address);
2355
2356   if (plugin->behind_nat == GNUNET_NO)
2357     {
2358       GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
2359     }
2360
2361   plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (env->cfg,
2362                                                            AF_UNSPEC,
2363                                                            HOSTNAME_RESOLVE_TIMEOUT,
2364                                                            &process_hostname_ips,
2365                                                            plugin);
2366
2367   if ((plugin->behind_nat == GNUNET_YES) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1))
2368     {
2369       v4_address.u_port = htons(0);
2370       plugin->env->notify_address (plugin->env->cls,
2371                                   "udp",
2372                                   &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL);
2373       add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t));
2374       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying plugin of address %s:0\n", plugin->external_address);
2375     }
2376   else if ((plugin->external_address != NULL) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1))
2377     {
2378       v4_address.u_port = htons(plugin->port);
2379       plugin->env->notify_address (plugin->env->cls,
2380                                   "udp",
2381                                   &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL);
2382       add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t));
2383     }
2384
2385   sockets_created = udp_transport_server_start (plugin);
2386   if (sockets_created == 0)
2387     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2388                 _("Failed to open UDP sockets\n"));
2389   return api;
2390 }
2391
2392 void *
2393 libgnunet_plugin_transport_udp_done (void *cls)
2394 {
2395   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2396   struct Plugin *plugin = api->cls;
2397   struct LocalAddrList *lal;
2398
2399   udp_transport_server_stop (plugin);
2400   if (NULL != plugin->hostname_dns)
2401     {
2402       GNUNET_RESOLVER_request_cancel (plugin->hostname_dns);
2403       plugin->hostname_dns = NULL;
2404     }
2405
2406   GNUNET_NETWORK_fdset_destroy (plugin->rs);
2407   while (NULL != (lal = plugin->lal_head))
2408     {
2409       GNUNET_CONTAINER_DLL_remove (plugin->lal_head,
2410                                    plugin->lal_tail,
2411                                    lal);
2412       GNUNET_free (lal);
2413     }
2414   GNUNET_free (plugin);
2415   GNUNET_free (api);
2416   return NULL;
2417 }
2418
2419 /* end of plugin_transport_udp.c */