aboutsummaryrefslogtreecommitdiff
path: root/src/nat/gnunet-nat-server.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-06 13:26:38 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-06 13:26:38 +0100
commit80e1315b56f559db60499f5373e90c293c5ab065 (patch)
tree3b279e6ac8e6298d7d9d96d12868f628a413939b /src/nat/gnunet-nat-server.c
parent1b7f6eea0a06abab9b75b30f021aa6313fccfcd4 (diff)
downloadgnunet-80e1315b56f559db60499f5373e90c293c5ab065.tar.gz
gnunet-80e1315b56f559db60499f5373e90c293c5ab065.zip
separate service for autoconfiguration from NAT traversal
Diffstat (limited to 'src/nat/gnunet-nat-server.c')
-rw-r--r--src/nat/gnunet-nat-server.c384
1 files changed, 0 insertions, 384 deletions
diff --git a/src/nat/gnunet-nat-server.c b/src/nat/gnunet-nat-server.c
deleted file mode 100644
index 1692a8ef1..000000000
--- a/src/nat/gnunet-nat-server.c
+++ /dev/null
@@ -1,384 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
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-server.c
23 * @brief Daemon to run on 'gnunet.org' to help test NAT traversal code
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_nat_lib.h"
29#include "gnunet_protocols.h"
30#include "nat.h"
31
32
33/**
34 * Our server.
35 */
36static struct GNUNET_SERVER_Handle *server;
37
38/**
39 * Our configuration.
40 */
41static const struct GNUNET_CONFIGURATION_Handle *cfg;
42
43
44/**
45 * Try contacting the peer using autonomous NAT traveral method.
46 *
47 * @param dst_ipv4 IPv4 address to send the fake ICMP message
48 * @param dport destination port to include in ICMP message
49 * @param is_tcp mark for TCP (#GNUNET_YES) or UDP (#GNUNET_NO)
50 */
51static void
52try_anat (uint32_t dst_ipv4,
53 uint16_t dport,
54 int is_tcp)
55{
56 struct GNUNET_NAT_Handle *h;
57 struct sockaddr_in sa;
58
59 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
60 "Asking for connection reversal with %x and code %u\n",
61 (unsigned int) dst_ipv4,
62 (unsigned int) dport);
63 h = GNUNET_NAT_register (cfg,
64 is_tcp,
65 dport,
66 0,
67 NULL, NULL, NULL, NULL, NULL, NULL);
68 memset (&sa, 0, sizeof (sa));
69 sa.sin_family = AF_INET;
70#if HAVE_SOCKADDR_IN_SIN_LEN
71 sa.sin_len = sizeof (sa);
72#endif
73 sa.sin_addr.s_addr = dst_ipv4;
74 GNUNET_NAT_run_client (h, &sa);
75 GNUNET_NAT_unregister (h);
76}
77
78
79/**
80 * Closure for #tcp_send.
81 */
82struct TcpContext
83{
84 /**
85 * TCP socket.
86 */
87 struct GNUNET_NETWORK_Handle *s;
88
89 /**
90 * Data to transmit.
91 */
92 uint16_t data;
93};
94
95
96/**
97 * Task called by the scheduler once we can do the TCP send
98 * (or once we failed to connect...).
99 *
100 * @param cls the `struct TcpContext`
101 */
102static void
103tcp_send (void *cls)
104{
105 struct TcpContext *ctx = cls;
106 const struct GNUNET_SCHEDULER_TaskContext *tc;
107
108 tc = GNUNET_SCHEDULER_get_task_context ();
109 if ((NULL != tc->write_ready) &&
110 (GNUNET_NETWORK_fdset_isset (tc->write_ready, ctx->s)))
111 {
112 if (-1 ==
113 GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data)))
114 {
115 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
116 }
117 GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR);
118 }
119 GNUNET_NETWORK_socket_close (ctx->s);
120 GNUNET_free (ctx);
121}
122
123
124/**
125 * Try to send @a data to the
126 * IP @a dst_ipv4' at port @a dport via TCP.
127 *
128 * @param dst_ipv4 target IP
129 * @param dport target port
130 * @param data data to send
131 */
132static void
133try_send_tcp (uint32_t dst_ipv4,
134 uint16_t dport,
135 uint16_t data)
136{
137 struct GNUNET_NETWORK_Handle *s;
138 struct sockaddr_in sa;
139 struct TcpContext *ctx;
140
141 s = GNUNET_NETWORK_socket_create (AF_INET,
142 SOCK_STREAM,
143 0);
144 if (NULL == s)
145 {
146 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
147 "socket");
148 return;
149 }
150 memset (&sa, 0, sizeof (sa));
151 sa.sin_family = AF_INET;
152#if HAVE_SOCKADDR_IN_SIN_LEN
153 sa.sin_len = sizeof (sa);
154#endif
155 sa.sin_addr.s_addr = dst_ipv4;
156 sa.sin_port = htons (dport);
157 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
158 "Sending TCP message to `%s'\n",
159 GNUNET_a2s ((struct sockaddr *) &sa,
160 sizeof (sa)));
161 if ( (GNUNET_OK !=
162 GNUNET_NETWORK_socket_connect (s,
163 (const struct sockaddr *) &sa,
164 sizeof (sa))) &&
165 (errno != EINPROGRESS) )
166 {
167 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
168 "connect");
169 GNUNET_NETWORK_socket_close (s);
170 return;
171 }
172 ctx = GNUNET_new (struct TcpContext);
173 ctx->s = s;
174 ctx->data = data;
175 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_SECONDS,
176 s,
177 &tcp_send,
178 ctx);
179}
180
181
182/**
183 * Try to send @a data to the
184 * IP @a dst_ipv4 at port @a dport via UDP.
185 *
186 * @param dst_ipv4 target IP
187 * @param dport target port
188 * @param data data to send
189 */
190static void
191try_send_udp (uint32_t dst_ipv4,
192 uint16_t dport,
193 uint16_t data)
194{
195 struct GNUNET_NETWORK_Handle *s;
196 struct sockaddr_in sa;
197
198 s = GNUNET_NETWORK_socket_create (AF_INET,
199 SOCK_DGRAM,
200 0);
201 if (NULL == s)
202 {
203 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
204 "socket");
205 return;
206 }
207 memset (&sa, 0, sizeof (sa));
208 sa.sin_family = AF_INET;
209#if HAVE_SOCKADDR_IN_SIN_LEN
210 sa.sin_len = sizeof (sa);
211#endif
212 sa.sin_addr.s_addr = dst_ipv4;
213 sa.sin_port = htons (dport);
214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
215 "Sending UDP packet to `%s'\n",
216 GNUNET_a2s ((struct sockaddr *) &sa,
217 sizeof (sa)));
218 if (-1 ==
219 GNUNET_NETWORK_socket_sendto (s,
220 &data,
221 sizeof (data),
222 (const struct sockaddr *) &sa,
223 sizeof (sa)))
224 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
225 "sendto");
226 GNUNET_NETWORK_socket_close (s);
227}
228
229
230/**
231 * We've received a request to probe a NAT
232 * traversal. Do it.
233 *
234 * @param cls unused
235 * @param client handle to client (we always close)
236 * @param msg message with details about what to test
237 */
238static void
239test (void *cls,
240 struct GNUNET_SERVER_Client *client,
241 const struct GNUNET_MessageHeader *msg)
242{
243 const struct GNUNET_NAT_TestMessage *tm;
244 uint16_t dport;
245
246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
247 "Received test request\n");
248 tm = (const struct GNUNET_NAT_TestMessage *) msg;
249 dport = ntohs (tm->dport);
250 if (0 == dport)
251 try_anat (tm->dst_ipv4,
252 ntohs (tm->data),
253 (int) ntohl (tm->is_tcp));
254 else if (GNUNET_YES == ntohl (tm->is_tcp))
255 try_send_tcp (tm->dst_ipv4,
256 dport,
257 tm->data);
258 else
259 try_send_udp (tm->dst_ipv4,
260 dport,
261 tm->data);
262 GNUNET_SERVER_receive_done (client,
263 GNUNET_NO);
264}
265
266
267/**
268 * Task run during shutdown.
269 *
270 * @param cls unused
271 */
272static void
273shutdown_task (void *cls)
274{
275 GNUNET_SERVER_destroy (server);
276 server = NULL;
277}
278
279
280/**
281 * Main function that will be run.
282 *
283 * @param cls closure
284 * @param args remaining command-line arguments
285 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
286 * @param c configuration
287 */
288static void
289run (void *cls,
290 char *const *args,
291 const char *cfgfile,
292 const struct GNUNET_CONFIGURATION_Handle *c)
293{
294 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
295 {&test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST,
296 sizeof (struct GNUNET_NAT_TestMessage)},
297 {NULL, NULL, 0, 0}
298 };
299 unsigned int port;
300 struct sockaddr_in in4;
301 struct sockaddr_in6 in6;
302
303 socklen_t slen[] = {
304 sizeof (in4),
305 sizeof (in6),
306 0
307 };
308 struct sockaddr *sa[] = {
309 (struct sockaddr *) &in4,
310 (struct sockaddr *) &in6,
311 NULL
312 };
313
314 cfg = c;
315 if ( (NULL == args[0]) ||
316 (1 != SSCANF (args[0], "%u", &port)) ||
317 (0 == port) ||
318 (65536 <= port) )
319 {
320 FPRINTF (stderr,
321 _("Please pass valid port number as the first argument! (got `%s')\n"),
322 args[0]);
323 return;
324 }
325 memset (&in4, 0, sizeof (in4));
326 memset (&in6, 0, sizeof (in6));
327 in4.sin_family = AF_INET;
328 in4.sin_port = htons ((uint16_t) port);
329 in6.sin6_family = AF_INET6;
330 in6.sin6_port = htons ((uint16_t) port);
331#if HAVE_SOCKADDR_IN_SIN_LEN
332 in4.sin_len = sizeof (in4);
333 in6.sin6_len = sizeof (in6);
334#endif
335 server = GNUNET_SERVER_create (NULL,
336 NULL,
337 (struct sockaddr * const *) sa,
338 slen,
339 GNUNET_TIME_UNIT_SECONDS,
340 GNUNET_YES);
341 GNUNET_SERVER_add_handlers (server,
342 handlers);
343 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
344 NULL);
345}
346
347
348/**
349 * Main function of gnunet-nat-server.
350 *
351 * @param argc number of command-line arguments
352 * @param argv command line
353 * @return 0 on success, -1 on error
354 */
355int
356main (int argc, char *const argv[])
357{
358 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
359 GNUNET_GETOPT_OPTION_END
360 };
361
362 if (GNUNET_OK !=
363 GNUNET_STRINGS_get_utf8_args (argc, argv,
364 &argc, &argv))
365 return 2;
366
367 if (GNUNET_OK !=
368 GNUNET_PROGRAM_run (argc,
369 argv,
370 "gnunet-nat-server [options] PORT",
371 _("GNUnet NAT traversal test helper daemon"),
372 options,
373 &run,
374 NULL))
375 {
376 GNUNET_free ((void*) argv);
377 return 1;
378 }
379 GNUNET_free ((void*) argv);
380 return 0;
381}
382
383
384/* end of gnunet-nat-server.c */