aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Cabral <bcabral@uw.edu>2015-08-22 06:24:03 +0000
committerBruno Cabral <bcabral@uw.edu>2015-08-22 06:24:03 +0000
commit5475027f60525bcf22d75fb7f7ee721703e01cfd (patch)
tree374daa52fd9da6a975b7ef37dbf276fa152c7103
parentdd1927b960c7cea13733e061a11142274652ba27 (diff)
downloadgnunet-5475027f60525bcf22d75fb7f7ee721703e01cfd.tar.gz
gnunet-5475027f60525bcf22d75fb7f7ee721703e01cfd.zip
gnunet-nat, tool to suggest changes to configure based on NAT configuration
-rw-r--r--src/include/gnunet_nat_lib.h29
-rw-r--r--src/nat/Makefile.am9
-rw-r--r--src/nat/gnunet-nat.c181
-rw-r--r--src/nat/nat_auto.c477
-rw-r--r--src/nat/nat_test.c9
5 files changed, 660 insertions, 45 deletions
diff --git a/src/include/gnunet_nat_lib.h b/src/include/gnunet_nat_lib.h
index 3e9d8171c..2eb18d74f 100644
--- a/src/include/gnunet_nat_lib.h
+++ b/src/include/gnunet_nat_lib.h
@@ -70,6 +70,31 @@ typedef void
70struct GNUNET_NAT_Handle; 70struct GNUNET_NAT_Handle;
71 71
72 72
73
74/**
75 * What the situation of the NAT connectivity
76 */
77enum GNUNET_NAT_Type
78{
79 /**
80 * We have a direct connection
81 */
82 GNUNET_NAT_TYPE_NO_NAT = GNUNET_OK,
83 /**
84 * We are under a NAT but cannot traverse it
85 */
86 GNUNET_NAT_TYPE_UNREACHABLE_NAT,
87 /**
88 * We can traverse using STUN
89 */
90 GNUNET_NAT_TYPE_STUN_PUNCHED_NAT,
91 /**
92 * WE can traverse using UPNP
93 */
94 GNUNET_NAT_TYPE_UPNP_NAT
95
96};
97
73/** 98/**
74 * Error Types for the NAT subsystem (which can then later be converted/resolved to a string) 99 * Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
75 */ 100 */
@@ -428,11 +453,13 @@ struct GNUNET_NAT_AutoHandle;
428 * @param diff minimal suggested changes to the original configuration 453 * @param diff minimal suggested changes to the original configuration
429 * to make it work (as best as we can) 454 * to make it work (as best as we can)
430 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code 455 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
456 * @param type what the situation of the NAT
431 */ 457 */
432typedef void 458typedef void
433(*GNUNET_NAT_AutoResultCallback)(void *cls, 459(*GNUNET_NAT_AutoResultCallback)(void *cls,
434 const struct GNUNET_CONFIGURATION_Handle *diff, 460 const struct GNUNET_CONFIGURATION_Handle *diff,
435 enum GNUNET_NAT_StatusCode result); 461 enum GNUNET_NAT_StatusCode result,
462 enum GNUNET_NAT_Type type);
436 463
437 464
438/** 465/**
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am
index 037c97ef4..0fde4c22d 100644
--- a/src/nat/Makefile.am
+++ b/src/nat/Makefile.am
@@ -34,7 +34,8 @@ install-exec-hook:
34endif 34endif
35 35
36bin_PROGRAMS = \ 36bin_PROGRAMS = \
37 gnunet-nat-server 37 gnunet-nat-server \
38 gnunet-nat
38 39
39libexec_PROGRAMS = \ 40libexec_PROGRAMS = \
40 $(NATBIN) 41 $(NATBIN)
@@ -51,6 +52,12 @@ gnunet_helper_nat_server_SOURCES = \
51gnunet_helper_nat_client_SOURCES = \ 52gnunet_helper_nat_client_SOURCES = \
52 $(NATCLIENT) 53 $(NATCLIENT)
53 54
55
56gnunet_nat_SOURCES = \
57gnunet-nat.c nat.h
58gnunet_nat_LDADD = \
59 libgnunetnat.la \
60 $(top_builddir)/src/util/libgnunetutil.la
54 61
55 62
56if USE_COVERAGE 63if USE_COVERAGE
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c
new file mode 100644
index 000000000..f9aae10cf
--- /dev/null
+++ b/src/nat/gnunet-nat.c
@@ -0,0 +1,181 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2015 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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file src/nat/gnunet-nat.c
23 * @brief Daemon to auto configure nat
24 * @author Christian Grothoff
25 * @author Bruno Cabral
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_nat_lib.h"
30#include "gnunet_protocols.h"
31#include "nat.h"
32
33
34struct GNUNET_CONFIGURATION_Handle *cfg;
35
36
37
38/**
39 * Function to iterate over sugested changes options
40 *
41 * @param cls closure
42 * @param section name of the section
43 * @param option name of the option
44 * @param value value of the option
45 */
46static void
47auto_conf_iter (void *cls,
48 const char *section,
49 const char *option,
50 const char *value)
51{
52
53 printf( "%s: %s \n", option, value);
54}
55
56
57
58/**
59 * Function called with the result from the autoconfiguration.
60 *
61 * @param cls closure
62 * @param diff minimal suggested changes to the original configuration
63 * to make it work (as best as we can)
64 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
65 * @param type what the situation of the NAT
66 */
67
68void
69auto_config_cb(void *cls,
70 const struct GNUNET_CONFIGURATION_Handle *diff,
71 enum GNUNET_NAT_StatusCode result, enum GNUNET_NAT_Type type)
72{
73 char* nat_type;
74
75
76 switch (type)
77 {
78 case GNUNET_NAT_TYPE_NO_NAT:
79 nat_type = "NO NAT";
80 break;
81 case GNUNET_NAT_TYPE_UNREACHABLE_NAT:
82 nat_type = "NAT but we can traverse";
83 break;
84 case GNUNET_NAT_TYPE_STUN_PUNCHED_NAT:
85 nat_type = "NAT but STUN is able to identify the correct information";
86 break;
87 case GNUNET_NAT_TYPE_UPNP_NAT:
88 nat_type = "NAT but UPNP opened the ports";
89 break;
90
91 }
92
93 printf("NAT status: %s \n", nat_type );
94 printf("SUGGESTED CHANGES: \n" );
95
96 GNUNET_CONFIGURATION_iterate_section_values (diff,
97 "nat",
98 &auto_conf_iter,
99 NULL);
100
101 //TODO: Save config
102
103}
104
105
106
107
108
109/**
110 * Main function that will be run.
111 *
112 * @param cls closure
113 * @param args remaining command-line arguments
114 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
115 * @param c configuration
116 */
117static void
118run (void *cls, char *const *args, const char *cfgfile,
119 const struct GNUNET_CONFIGURATION_Handle *c)
120{
121
122
123 GNUNET_NAT_autoconfig_start(c,auto_config_cb, NULL);
124
125}
126
127
128/**
129 * Main function of gnunet-nat
130 *
131 * @param argc number of command-line arguments
132 * @param argv command line
133 * @return 0 on success, -1 on error
134 */
135int
136main (int argc, char *const argv[])
137{
138 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
139 GNUNET_GETOPT_OPTION_END
140 };
141
142 int ret = 0;
143 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
144 return 2;
145
146 /* Lets start resolver */
147 char *fn;
148 struct GNUNET_OS_Process *proc;
149
150 fn = GNUNET_OS_get_libexec_binary_path ("gnunet-service-resolver");
151 proc = GNUNET_OS_start_process (GNUNET_YES,
152 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
153 NULL, NULL, NULL,
154 fn,
155 "gnunet-service-resolver");
156 GNUNET_assert (NULL != proc);
157
158 if (GNUNET_OK !=
159 GNUNET_PROGRAM_run (argc, argv, "gnunet-nat [options]",
160 _("GNUnet NAT traversal autoconfigure daemon"), options,
161 &run, NULL))
162 {
163 ret = 1;
164 }
165
166 /* Now kill the resolver */
167 if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG))
168 {
169 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
170 }
171 GNUNET_OS_process_wait (proc);
172 GNUNET_OS_process_destroy (proc);
173 proc = NULL;
174
175
176 GNUNET_free ((void*) argv);
177 return ret;
178}
179
180
181/* end of gnunet-nat-server.c */
diff --git a/src/nat/nat_auto.c b/src/nat/nat_auto.c
index 327970e0a..dc7eecb3e 100644
--- a/src/nat/nat_auto.c
+++ b/src/nat/nat_auto.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012 Christian Grothoff (and other contributing authors) 3 Copyright (C) 2015 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -22,6 +22,7 @@
22 * @file nat/nat_auto.c 22 * @file nat/nat_auto.c
23 * @brief functions for auto-configuration of the network 23 * @brief functions for auto-configuration of the network
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Bruno Cabral
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -37,6 +38,8 @@
37 */ 38 */
38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) 39#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
39 40
41#define NAT_SERVER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
42
40/** 43/**
41 * Phases of the auto configuration. 44 * Phases of the auto configuration.
42 */ 45 */
@@ -48,14 +51,14 @@ enum AutoPhase
48 AUTO_INIT = 0, 51 AUTO_INIT = 0,
49 52
50 /** 53 /**
51 * Test if we are online. 54 * Test our external IP.
52 */ 55 */
53 AUTO_ONLINE, 56 AUTO_EXTERNAL_IP,
54 57
55 /** 58 /**
56 * Test our external IP. 59 * Test our external IP.
57 */ 60 */
58 AUTO_EXTERNAL_IP, 61 AUTO_STUN,
59 62
60 /** 63 /**
61 * Test our internal IP. 64 * Test our internal IP.
@@ -136,25 +139,236 @@ struct GNUNET_NAT_AutoHandle
136 */ 139 */
137 enum AutoPhase phase; 140 enum AutoPhase phase;
138 141
142
143 /**
144 * Situation of the NAT
145 */
146 enum GNUNET_NAT_Type type;
147
139 /** 148 /**
140 * Do we have IPv6? 149 * Do we have IPv6?
141 */ 150 */
142 int have_v6; 151 int have_v6;
143 152
144 /** 153 /**
154 * UPnP already set the external ip address ?
155 */
156 int upnp_set_external_address;
157
158 /**
159 * Did the external server connected back ?
160 */
161 int connected_back;
162
163 /**
164 * Address detected by STUN
165 */
166 char* stun_ip;
167 int stun_port;
168
169 /**
170 * Internal IP is the same as the public one ?
171 */
172 int internal_ip_is_public;
173
174 /**
145 * Error code for better debugging and user feedback 175 * Error code for better debugging and user feedback
146 */ 176 */
147 enum GNUNET_NAT_StatusCode ret; 177 enum GNUNET_NAT_StatusCode ret;
148}; 178};
149 179
150 180
181
182
183
184
185/**
186 * The listen socket of the service for IPv4
187 */
188static struct GNUNET_NETWORK_Handle *lsock4;
189
190
191/**
192 * The listen task ID for IPv4
193 */
194static struct GNUNET_SCHEDULER_Task * ltask4;
195
196
197
198
199/**
200 * The port the test service is running on (default 7895)
201 */
202static unsigned long long port = 7895;
203
204static char *stun_server = "stun.ekiga.net";
205static int stun_port = 3478;
206
207
208
151/** 209/**
152 * Run the next phase of the auto test. 210 * Run the next phase of the auto test.
153 * 211 *
154 * @param ah auto test handle 212 * @param ah auto test handle
155 */ 213 */
156static void 214static void
157next_phase (struct GNUNET_NAT_AutoHandle *ah); 215 next_phase (struct GNUNET_NAT_AutoHandle *ah);
216
217
218
219
220static void
221process_stun_reply(struct sockaddr_in* answer, struct GNUNET_NAT_AutoHandle *ah)
222{
223
224 ah->stun_ip = inet_ntoa(answer->sin_addr);
225 ah->stun_port = ntohs(answer->sin_port);
226 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "External IP is: %s , with port %d\n", ah->stun_ip, ah->stun_port);
227
228
229 next_phase (ah);
230
231}
232
233/**
234 * Function that terminates the test.
235 */
236static void
237stop_stun ()
238{
239 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n");
240
241 //Clean task
242 if(NULL != ltask4)
243 GNUNET_SCHEDULER_cancel (ltask4);
244
245 //Clean socket
246 if(NULL != ltask4)
247 GNUNET_NETWORK_socket_close (lsock4);
248
249}
250
251/**
252 * Activity on our incoming socket. Read data from the
253 * incoming connection.
254 *
255 * @param cls
256 * @param tc scheduler context
257 */
258static void
259do_udp_read (void *cls,
260 const struct GNUNET_SCHEDULER_TaskContext *tc)
261{
262 struct GNUNET_NAT_AutoHandle *ah = cls;
263 unsigned char reply_buf[1024];
264 ssize_t rlen;
265 struct sockaddr_in answer;
266
267
268 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
269 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
270 lsock4)))
271 {
272 rlen = GNUNET_NETWORK_socket_recv (lsock4, reply_buf, sizeof (reply_buf));
273
274
275 //Lets handle the packet
276 memset(&answer, 0, sizeof(struct sockaddr_in));
277
278
279
280
281
282 if(ah->phase == AUTO_NAT_PUNCHED)
283 {
284 //Destroy the connection
285 GNUNET_NETWORK_socket_close (lsock4);
286 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "The external server was able to connect back");
287 ah->connected_back = GNUNET_YES;
288 next_phase (ah);
289 }
290 else
291 {
292 if(GNUNET_OK == GNUNET_NAT_stun_handle_packet(reply_buf,rlen, &answer))
293 {
294 //Process the answer
295 process_stun_reply(&answer, ah);
296
297 }
298 else
299 {
300 next_phase (ah);
301 }
302 }
303
304
305 }
306 else
307 {
308 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "TIMEOUT while aiting for an answer");
309 if(ah->phase == AUTO_NAT_PUNCHED)
310 {
311 stop_stun();
312 }
313
314 next_phase(ah);
315 }
316
317
318
319}
320
321
322/**
323 * Create an IPv4 listen socket bound to our port.
324 *
325 * @return NULL on error
326 */
327static struct GNUNET_NETWORK_Handle *
328bind_v4 ()
329{
330 struct GNUNET_NETWORK_Handle *ls;
331 struct sockaddr_in sa4;
332 int eno;
333
334 memset (&sa4, 0, sizeof (sa4));
335 sa4.sin_family = AF_INET;
336 sa4.sin_port = htons (port);
337#if HAVE_SOCKADDR_IN_SIN_LEN
338 sa4.sin_len = sizeof (sa4);
339#endif
340 ls = GNUNET_NETWORK_socket_create (AF_INET,
341 SOCK_DGRAM,
342 0);
343 if (NULL == ls)
344 return NULL;
345 if (GNUNET_OK !=
346 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa4,
347 sizeof (sa4)))
348 {
349 eno = errno;
350 GNUNET_NETWORK_socket_close (ls);
351 errno = eno;
352 return NULL;
353 }
354 return ls;
355}
356
357
358
359
360static void request_callback(void *cls,
361 enum GNUNET_NAT_StatusCode result)
362{
363 struct GNUNET_NAT_AutoHandle *ah = cls;
364 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n");
365 stop_stun();
366
367 next_phase(ah);
368};
369
370
371
158 372
159 373
160/** 374/**
@@ -170,6 +384,7 @@ result_callback (void *cls,
170 enum GNUNET_NAT_StatusCode ret) 384 enum GNUNET_NAT_StatusCode ret)
171{ 385{
172 struct GNUNET_NAT_AutoHandle *ah = cls; 386 struct GNUNET_NAT_AutoHandle *ah = cls;
387
173 if (GNUNET_NAT_ERROR_SUCCESS == ret) 388 if (GNUNET_NAT_ERROR_SUCCESS == ret)
174 GNUNET_NAT_test_stop (ah->tst); 389 GNUNET_NAT_test_stop (ah->tst);
175 ah->tst = NULL; 390 ah->tst = NULL;
@@ -206,24 +421,8 @@ reversal_test (void *cls,
206 421
207 422
208/** 423/**
209 * Test if we are online at all. 424 * Set our external IPv4 address based on the UPnP.
210 * 425 *
211 * @param ah auto setup context
212 */
213static void
214test_online (struct GNUNET_NAT_AutoHandle *ah)
215{
216 // FIXME: not implemented
217 /*
218 * if (failure)
219 * ah->ret = GNUNET_NAT_ERROR_NOT_ONLINE;
220 */
221 next_phase (ah);
222}
223
224
225/**
226 * Set our external IPv4 address.
227 * 426 *
228 * @param cls closure with our setup context 427 * @param cls closure with our setup context
229 * @param addr the address, NULL on errors 428 * @param addr the address, NULL on errors
@@ -267,6 +466,7 @@ set_external_ipv4 (void *cls,
267 } 466 }
268 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS", 467 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS",
269 buf); 468 buf);
469 ah->upnp_set_external_address = GNUNET_YES;
270 next_phase (ah); 470 next_phase (ah);
271} 471}
272 472
@@ -290,6 +490,59 @@ test_external_ip (struct GNUNET_NAT_AutoHandle *ah)
290 490
291 491
292/** 492/**
493 * Determine our external IPv4 address and port using an external STUN server
494 *
495 * @param ah auto setup context
496 */
497static void
498test_stun (struct GNUNET_NAT_AutoHandle *ah)
499{
500
501 GNUNET_log (GNUNET_ERROR_TYPE_INFO,"Running STUN test");
502
503 /* Get port from the configuration */
504 if (GNUNET_OK !=
505 GNUNET_CONFIGURATION_get_value_number (ah->cfg,
506 "transport-udp",
507 "PORT",
508 &port))
509 {
510 port = 2086;
511 }
512
513 //Lets create the socket
514 lsock4 = bind_v4 ();
515 if (NULL == lsock4)
516 {
517 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
518 next_phase(ah);
519 return;
520 }
521 else
522 {
523 //Lets call our function now when it accepts
524 ltask4 = GNUNET_SCHEDULER_add_read_net (NAT_SERVER_TIMEOUT,
525 lsock4, &do_udp_read, ah);
526
527 }
528
529
530 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
531 "STUN service listens on port %u\n",
532 port);
533 if( GNUNET_NO == GNUNET_NAT_stun_make_request(stun_server, stun_port, lsock4, &request_callback, NULL))
534 {
535 /*An error happened*/
536 stop_stun();
537 next_phase(ah);
538 }
539
540
541}
542
543
544
545/**
293 * Process list of local IP addresses. Find and set the 546 * Process list of local IP addresses. Find and set the
294 * one of the default interface. 547 * one of the default interface.
295 * 548 *
@@ -315,8 +568,7 @@ process_if (void *cls,
315 const struct sockaddr_in *in; 568 const struct sockaddr_in *in;
316 char buf[INET_ADDRSTRLEN]; 569 char buf[INET_ADDRSTRLEN];
317 570
318 if (!isDefault) 571
319 return GNUNET_OK;
320 if ( (sizeof (struct sockaddr_in6) == addrlen) && 572 if ( (sizeof (struct sockaddr_in6) == addrlen) &&
321 (0 != memcmp (&in6addr_loopback, &((const struct sockaddr_in6 *) addr)->sin6_addr, 573 (0 != memcmp (&in6addr_loopback, &((const struct sockaddr_in6 *) addr)->sin6_addr,
322 sizeof (struct in6_addr))) && 574 sizeof (struct in6_addr))) &&
@@ -325,12 +577,14 @@ process_if (void *cls,
325 ah->have_v6 = GNUNET_YES; 577 ah->have_v6 = GNUNET_YES;
326 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 578 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
327 _("This system has a global IPv6 address, setting IPv6 to supported.\n")); 579 _("This system has a global IPv6 address, setting IPv6 to supported.\n"));
580
328 return GNUNET_OK; 581 return GNUNET_OK;
329 } 582 }
330 if (addrlen != sizeof (struct sockaddr_in)) 583 if (addrlen != sizeof (struct sockaddr_in))
331 return GNUNET_OK; 584 return GNUNET_OK;
332 in = (const struct sockaddr_in *) addr; 585 in = (const struct sockaddr_in *) addr;
333 586
587
334 /* set internal IP address */ 588 /* set internal IP address */
335 if (NULL == inet_ntop (AF_INET, &in->sin_addr, buf, sizeof (buf))) 589 if (NULL == inet_ntop (AF_INET, &in->sin_addr, buf, sizeof (buf)))
336 { 590 {
@@ -342,9 +596,24 @@ process_if (void *cls,
342 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 596 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
343 _("Detected internal network address `%s'.\n"), 597 _("Detected internal network address `%s'.\n"),
344 buf); 598 buf);
599
600
345 ah->ret = GNUNET_NAT_ERROR_SUCCESS; 601 ah->ret = GNUNET_NAT_ERROR_SUCCESS;
346 /* no need to continue iteration */ 602
347 return GNUNET_SYSERR; 603 /* Check if our internal IP is the same as the External detect by STUN*/
604 if(ah->stun_ip && (strcmp(buf, ah->stun_ip) == 0) )
605 {
606 ah->internal_ip_is_public = GNUNET_YES;
607 GNUNET_log (GNUNET_ERROR_TYPE_INFO,"A internal IP is the sameas the external");
608 /* No need to continue*/
609 return GNUNET_SYSERR;
610 }
611
612 /* no need to continue iteration if we found the default */
613 if (!isDefault)
614 return GNUNET_OK;
615 else
616 return GNUNET_SYSERR;
348} 617}
349 618
350 619
@@ -374,15 +643,55 @@ test_local_ip (struct GNUNET_NAT_AutoHandle *ah)
374static void 643static void
375test_nat_punched (struct GNUNET_NAT_AutoHandle *ah) 644test_nat_punched (struct GNUNET_NAT_AutoHandle *ah)
376{ 645{
377 if (GNUNET_NAT_ERROR_SUCCESS != ah->ret) 646
378 next_phase (ah); 647 struct GNUNET_CLIENT_Connection *client;
379 648 struct GNUNET_NAT_TestMessage msg;
380 // FIXME: not implemented 649
381 650
382 next_phase (ah); 651 if(ah->stun_ip)
652 {
653 LOG (GNUNET_ERROR_TYPE_INFO,
654 "Asking gnunet-nat-server to connect to `%s'\n",
655 ah->stun_ip);
656
657
658 msg.header.size = htons (sizeof (struct GNUNET_NAT_TestMessage));
659 msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAT_TEST);
660 msg.dst_ipv4 = inet_addr(ah->stun_ip);
661 msg.dport = htons(ah->stun_port);
662 msg.data = port;
663 msg.is_tcp = htonl ((uint32_t) GNUNET_NO);
664
665 client = GNUNET_CLIENT_connect ("gnunet-nat-server", ah->cfg);
666 if (NULL == client)
667 {
668 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
669 _("Failed to connect to `gnunet-nat-server'\n"));
670 return;
671 }
672
673 GNUNET_break (GNUNET_OK ==
674 GNUNET_CLIENT_transmit_and_get_response (client, &msg.header,
675 NAT_SERVER_TIMEOUT,
676 GNUNET_YES, NULL,
677 NULL));
678 ltask4 = GNUNET_SCHEDULER_add_read_net (NAT_SERVER_TIMEOUT,
679 lsock4, &do_udp_read, ah);
680
681 }
682 else
683 {
684 LOG (GNUNET_ERROR_TYPE_INFO,
685 "We don't have a STUN IP");
686 next_phase(ah);
687 }
688
689
383} 690}
384 691
385 692
693
694
386/** 695/**
387 * Test if UPnPC works. 696 * Test if UPnPC works.
388 * 697 *
@@ -391,16 +700,16 @@ test_nat_punched (struct GNUNET_NAT_AutoHandle *ah)
391static void 700static void
392test_upnpc (struct GNUNET_NAT_AutoHandle *ah) 701test_upnpc (struct GNUNET_NAT_AutoHandle *ah)
393{ 702{
703
394 int have_upnpc; 704 int have_upnpc;
395 705
396 if (GNUNET_NAT_ERROR_SUCCESS != ah->ret) 706 if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
397 next_phase (ah); 707 next_phase (ah);
398 708
399 /* test if upnpc is available */ 709 // test if upnpc is available
400 have_upnpc = (GNUNET_SYSERR != 710 have_upnpc = (GNUNET_SYSERR !=
401 GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL)); 711 GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL));
402 /* FIXME: test if upnpc is actually working, that is, if transports 712 //FIXME: test if upnpc is actually working, that is, if transports start to work once we use UPnP
403 start to work once we use UPnP */
404 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 713 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
405 (have_upnpc) 714 (have_upnpc)
406 ? _("upnpc found, enabling its use\n") 715 ? _("upnpc found, enabling its use\n")
@@ -408,6 +717,7 @@ test_upnpc (struct GNUNET_NAT_AutoHandle *ah)
408 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "ENABLE_UPNP", 717 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "ENABLE_UPNP",
409 (GNUNET_YES == have_upnpc) ? "YES" : "NO"); 718 (GNUNET_YES == have_upnpc) ? "YES" : "NO");
410 next_phase (ah); 719 next_phase (ah);
720
411} 721}
412 722
413 723
@@ -419,6 +729,7 @@ test_upnpc (struct GNUNET_NAT_AutoHandle *ah)
419static void 729static void
420test_icmp_server (struct GNUNET_NAT_AutoHandle *ah) 730test_icmp_server (struct GNUNET_NAT_AutoHandle *ah)
421{ 731{
732
422 int ext_ip; 733 int ext_ip;
423 int nated; 734 int nated;
424 int binary; 735 int binary;
@@ -460,6 +771,7 @@ err:
460 ah->task = GNUNET_SCHEDULER_add_now (&reversal_test, ah); 771 ah->task = GNUNET_SCHEDULER_add_now (&reversal_test, ah);
461 else 772 else
462 next_phase (ah); 773 next_phase (ah);
774
463} 775}
464 776
465 777
@@ -471,6 +783,8 @@ err:
471static void 783static void
472test_icmp_client (struct GNUNET_NAT_AutoHandle *ah) 784test_icmp_client (struct GNUNET_NAT_AutoHandle *ah)
473{ 785{
786
787
474 char *tmp; 788 char *tmp;
475 char *helper; 789 char *helper;
476 790
@@ -502,6 +816,7 @@ err:
502 GNUNET_free (helper); 816 GNUNET_free (helper);
503 817
504 next_phase (ah); 818 next_phase (ah);
819
505} 820}
506 821
507 822
@@ -519,37 +834,116 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
519 case AUTO_INIT: 834 case AUTO_INIT:
520 GNUNET_assert (0); 835 GNUNET_assert (0);
521 break; 836 break;
522 case AUTO_ONLINE:
523 test_online (ah);
524 break;
525 case AUTO_EXTERNAL_IP: 837 case AUTO_EXTERNAL_IP:
838 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run AUTO_EXTERNAL_IP\n");
526 test_external_ip (ah); 839 test_external_ip (ah);
527 break; 840 break;
841 case AUTO_STUN:
842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run AUTO_STUN\n");
843 test_stun (ah);
844 break;
528 case AUTO_LOCAL_IP: 845 case AUTO_LOCAL_IP:
846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run AUTO_LOCAL_IP\n");
529 test_local_ip (ah); 847 test_local_ip (ah);
530 break; 848 break;
531 case AUTO_NAT_PUNCHED: 849 case AUTO_NAT_PUNCHED:
850 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run GNUNET_ERROR_TYPE_DEBUG\n");
532 test_nat_punched (ah); 851 test_nat_punched (ah);
533 break; 852 break;
534 case AUTO_UPNPC: 853 case AUTO_UPNPC:
854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run AUTO_UPNPC\n");
535 test_upnpc (ah); 855 test_upnpc (ah);
536 break; 856 break;
537 case AUTO_ICMP_SERVER: 857 case AUTO_ICMP_SERVER:
858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run AUTO_ICMP_SERVER\n");
538 test_icmp_server (ah); 859 test_icmp_server (ah);
539 break; 860 break;
540 case AUTO_ICMP_CLIENT: 861 case AUTO_ICMP_CLIENT:
862 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run AUTO_ICMP_CLIENT\n");
541 test_icmp_client (ah); 863 test_icmp_client (ah);
542 break; 864 break;
543 case AUTO_DONE: 865 case AUTO_DONE:
866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Done with tests\n");
867 if(!ah->internal_ip_is_public)
868 {
869 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "BEHIND_NAT", "YES");
870
871 if(ah->connected_back)
872 {
873 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "PUNCHED_NAT", "YES");
874 }
875 else
876 {
877 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "PUNCHED_NAT", "NO");
878 }
879
880 if (ah->stun_ip)
881 {
882 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS",
883 ah->stun_ip);
884 if(ah->connected_back)
885 {
886 ah->type = GNUNET_NAT_TYPE_STUN_PUNCHED_NAT;
887 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "USE_STUN", "YES");
888 }
889 else
890 {
891 ah->type = GNUNET_NAT_TYPE_UNREACHABLE_NAT;
892 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "USE_STUN", "NO");
893 }
894
895 }
896 if(ah->stun_port)
897 {
898 GNUNET_CONFIGURATION_set_value_number (ah->cfg, "transport-udp",
899 "ADVERTISED_PORT",
900 ah->stun_port);
901 }
902
903 }
904 else
905 {
906 //The internal IP is the same as public, but we didn't got a incoming connection
907 if(ah->connected_back)
908 {
909 ah->type = GNUNET_NAT_TYPE_NO_NAT;
910 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "BEHIND_NAT", "NO");
911 }
912 else
913 {
914 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "BEHIND_NAT", "YES");
915 ah->type = GNUNET_NAT_TYPE_UNREACHABLE_NAT;
916 if (ah->stun_ip)
917 {
918 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS",
919 ah->stun_ip);
920 }
921 if(ah->stun_port)
922 {
923 GNUNET_CONFIGURATION_set_value_number (ah->cfg, "transport-udp",
924 "ADVERTISED_PORT",
925 ah->stun_port);
926
927 }
928 }
929 }
930
544 diff = GNUNET_CONFIGURATION_get_diff (ah->initial_cfg, 931 diff = GNUNET_CONFIGURATION_get_diff (ah->initial_cfg,
545 ah->cfg); 932 ah->cfg);
933
934
546 ah->fin_cb (ah->fin_cb_cls, 935 ah->fin_cb (ah->fin_cb_cls,
547 diff, 936 diff,
548 ah->ret); 937 ah->ret,
938 ah->type);
549 GNUNET_CONFIGURATION_destroy (diff); 939 GNUNET_CONFIGURATION_destroy (diff);
550 GNUNET_NAT_autoconfig_cancel (ah); 940 GNUNET_NAT_autoconfig_cancel (ah);
551 return; 941 return;
942
552 } 943 }
944
945
946
553} 947}
554 948
555 949
@@ -580,6 +974,7 @@ GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
580 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", 974 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat",
581 "USE_LOCALADDR", 975 "USE_LOCALADDR",
582 "NO"); 976 "NO");
977
583 next_phase (ah); 978 next_phase (ah);
584 return ah; 979 return ah;
585} 980}
diff --git a/src/nat/nat_test.c b/src/nat/nat_test.c
index 3ee80ecae..b998d46a0 100644
--- a/src/nat/nat_test.c
+++ b/src/nat/nat_test.c
@@ -287,6 +287,8 @@ do_accept (void *cls,
287 struct GNUNET_NETWORK_Handle *s; 287 struct GNUNET_NETWORK_Handle *s;
288 struct NatActivity *wl; 288 struct NatActivity *wl;
289 289
290 printf("Inbound");
291
290 tst->ltask = NULL; 292 tst->ltask = NULL;
291 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 293 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
292 return; 294 return;
@@ -333,6 +335,8 @@ addr_cb (void *cls,
333 struct GNUNET_NAT_TestMessage msg; 335 struct GNUNET_NAT_TestMessage msg;
334 const struct sockaddr_in *sa; 336 const struct sockaddr_in *sa;
335 337
338 printf("Addr callback");
339
336 if (GNUNET_YES != add_remove) 340 if (GNUNET_YES != add_remove)
337 return; 341 return;
338 if (addrlen != sizeof (struct sockaddr_in)) 342 if (addrlen != sizeof (struct sockaddr_in))
@@ -448,6 +452,7 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
448 } 452 }
449 else 453 else
450 { 454 {
455 printf("Vou criar o socket");
451 nh->lsock = 456 nh->lsock =
452 GNUNET_NETWORK_socket_create (AF_INET, 457 GNUNET_NETWORK_socket_create (AF_INET,
453 (is_tcp == 458 (is_tcp ==
@@ -484,7 +489,7 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
484 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 489 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
485 nh->lsock, &do_udp_read, nh); 490 nh->lsock, &do_udp_read, nh);
486 } 491 }
487 LOG (GNUNET_ERROR_TYPE_DEBUG, 492 LOG (GNUNET_ERROR_TYPE_INFO,
488 "NAT test listens on port %u (%s)\n", 493 "NAT test listens on port %u (%s)\n",
489 bnd_port, 494 bnd_port,
490 (GNUNET_YES == is_tcp) ? "tcp" : "udp"); 495 (GNUNET_YES == is_tcp) ? "tcp" : "udp");
@@ -493,7 +498,7 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
493 &addr_cb, NULL, nh, NULL); 498 &addr_cb, NULL, nh, NULL);
494 if (NULL == nh->nat) 499 if (NULL == nh->nat)
495 { 500 {
496 LOG (GNUNET_ERROR_TYPE_ERROR, 501 LOG (GNUNET_ERROR_TYPE_INFO,
497 _("NAT test failed to start NAT library\n")); 502 _("NAT test failed to start NAT library\n"));
498 if (NULL != nh->ltask) 503 if (NULL != nh->ltask)
499 { 504 {