diff options
Diffstat (limited to 'src/nat/gnunet-nat-server.c')
-rw-r--r-- | src/nat/gnunet-nat-server.c | 200 |
1 files changed, 87 insertions, 113 deletions
diff --git a/src/nat/gnunet-nat-server.c b/src/nat/gnunet-nat-server.c index bf4318a91..3b4ec2293 100644 --- a/src/nat/gnunet-nat-server.c +++ b/src/nat/gnunet-nat-server.c | |||
@@ -51,30 +51,23 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
51 | * @param is_tcp mark for TCP (GNUNET_YES) or UDP (GNUNET_NO) | 51 | * @param is_tcp mark for TCP (GNUNET_YES) or UDP (GNUNET_NO) |
52 | */ | 52 | */ |
53 | static void | 53 | static void |
54 | try_anat (uint32_t dst_ipv4, | 54 | try_anat (uint32_t dst_ipv4, uint16_t dport, int is_tcp) |
55 | uint16_t dport, | ||
56 | int is_tcp) | ||
57 | { | 55 | { |
58 | struct GNUNET_NAT_Handle *h; | 56 | struct GNUNET_NAT_Handle *h; |
59 | struct sockaddr_in sa; | 57 | struct sockaddr_in sa; |
60 | 58 | ||
61 | #if DEBUG_NAT | 59 | #if DEBUG_NAT |
62 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 60 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
63 | "Asking for connection reversal with %x and code %u\n", | 61 | "Asking for connection reversal with %x and code %u\n", |
64 | (unsigned int) dst_ipv4, | 62 | (unsigned int) dst_ipv4, (unsigned int) dport); |
65 | (unsigned int) dport); | ||
66 | #endif | 63 | #endif |
67 | h = GNUNET_NAT_register (cfg, | 64 | h = GNUNET_NAT_register (cfg, is_tcp, dport, 0, NULL, NULL, NULL, NULL, NULL); |
68 | is_tcp, | ||
69 | dport, | ||
70 | 0, NULL, NULL, | ||
71 | NULL, NULL, NULL); | ||
72 | memset (&sa, 0, sizeof (sa)); | 65 | memset (&sa, 0, sizeof (sa)); |
73 | sa.sin_family = AF_INET; | 66 | sa.sin_family = AF_INET; |
74 | #if HAVE_SOCKADDR_IN_SIN_LEN | 67 | #if HAVE_SOCKADDR_IN_SIN_LEN |
75 | sa.sin_len = sizeof (sa); | 68 | sa.sin_len = sizeof (sa); |
76 | #endif | 69 | #endif |
77 | sa.sin_addr.s_addr = dst_ipv4; | 70 | sa.sin_addr.s_addr = dst_ipv4; |
78 | GNUNET_NAT_run_client (h, &sa); | 71 | GNUNET_NAT_run_client (h, &sa); |
79 | GNUNET_NAT_unregister (h); | 72 | GNUNET_NAT_unregister (h); |
80 | } | 73 | } |
@@ -83,7 +76,7 @@ try_anat (uint32_t dst_ipv4, | |||
83 | /** | 76 | /** |
84 | * Closure for 'tcp_send'. | 77 | * Closure for 'tcp_send'. |
85 | */ | 78 | */ |
86 | struct TcpContext | 79 | struct TcpContext |
87 | { | 80 | { |
88 | /** | 81 | /** |
89 | * TCP socket. | 82 | * TCP socket. |
@@ -92,7 +85,7 @@ struct TcpContext | |||
92 | 85 | ||
93 | /** | 86 | /** |
94 | * Data to transmit. | 87 | * Data to transmit. |
95 | */ | 88 | */ |
96 | uint16_t data; | 89 | uint16_t data; |
97 | }; | 90 | }; |
98 | 91 | ||
@@ -105,23 +98,22 @@ struct TcpContext | |||
105 | * @param tc scheduler context | 98 | * @param tc scheduler context |
106 | */ | 99 | */ |
107 | static void | 100 | static void |
108 | tcp_send (void *cls, | 101 | tcp_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
109 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
110 | { | 102 | { |
111 | struct TcpContext *ctx = cls; | 103 | struct TcpContext *ctx = cls; |
112 | 104 | ||
113 | if ( (NULL != tc->write_ready) && | 105 | if ((NULL != tc->write_ready) && |
114 | (GNUNET_NETWORK_fdset_isset (tc->write_ready, | 106 | (GNUNET_NETWORK_fdset_isset (tc->write_ready, ctx->s))) |
115 | ctx->s)) ) | 107 | { |
108 | if (-1 == | ||
109 | GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data))) | ||
116 | { | 110 | { |
117 | if (-1 == GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data))) | ||
118 | { | ||
119 | #if DEBUG_NAT | 111 | #if DEBUG_NAT |
120 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); | 112 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); |
121 | #endif | 113 | #endif |
122 | } | ||
123 | GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR); | ||
124 | } | 114 | } |
115 | GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR); | ||
116 | } | ||
125 | GNUNET_NETWORK_socket_close (ctx->s); | 117 | GNUNET_NETWORK_socket_close (ctx->s); |
126 | GNUNET_free (ctx); | 118 | GNUNET_free (ctx); |
127 | } | 119 | } |
@@ -136,9 +128,7 @@ tcp_send (void *cls, | |||
136 | * @param data data to send | 128 | * @param data data to send |
137 | */ | 129 | */ |
138 | static void | 130 | static void |
139 | try_send_tcp (uint32_t dst_ipv4, | 131 | try_send_tcp (uint32_t dst_ipv4, uint16_t dport, uint16_t data) |
140 | uint16_t dport, | ||
141 | uint16_t data) | ||
142 | { | 132 | { |
143 | struct GNUNET_NETWORK_Handle *s; | 133 | struct GNUNET_NETWORK_Handle *s; |
144 | struct sockaddr_in sa; | 134 | struct sockaddr_in sa; |
@@ -146,37 +136,35 @@ try_send_tcp (uint32_t dst_ipv4, | |||
146 | 136 | ||
147 | s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); | 137 | s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); |
148 | if (NULL == s) | 138 | if (NULL == s) |
149 | { | 139 | { |
150 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); | 140 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); |
151 | return; | 141 | return; |
152 | } | 142 | } |
153 | memset (&sa, 0, sizeof (sa)); | 143 | memset (&sa, 0, sizeof (sa)); |
154 | sa.sin_family = AF_INET; | 144 | sa.sin_family = AF_INET; |
155 | #if HAVE_SOCKADDR_IN_SIN_LEN | 145 | #if HAVE_SOCKADDR_IN_SIN_LEN |
156 | sa.sin_len = sizeof (sa); | 146 | sa.sin_len = sizeof (sa); |
157 | #endif | 147 | #endif |
158 | sa.sin_addr.s_addr = dst_ipv4; | 148 | sa.sin_addr.s_addr = dst_ipv4; |
159 | sa.sin_port = htons (dport); | 149 | sa.sin_port = htons (dport); |
160 | #if DEBUG_NAT | 150 | #if DEBUG_NAT |
161 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 151 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
162 | "Sending TCP message to `%s'\n", | 152 | "Sending TCP message to `%s'\n", |
163 | GNUNET_a2s ((struct sockaddr*) &sa, sizeof (sa))); | 153 | GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa))); |
164 | #endif | 154 | #endif |
165 | if ( (GNUNET_OK != | 155 | if ((GNUNET_OK != |
166 | GNUNET_NETWORK_socket_connect (s, | 156 | GNUNET_NETWORK_socket_connect (s, |
167 | (const struct sockaddr*) &sa, sizeof (sa))) && | 157 | (const struct sockaddr *) &sa, |
168 | (errno != EINPROGRESS) ) | 158 | sizeof (sa))) && (errno != EINPROGRESS)) |
169 | { | 159 | { |
170 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect"); | 160 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect"); |
171 | GNUNET_NETWORK_socket_close (s); | 161 | GNUNET_NETWORK_socket_close (s); |
172 | return; | 162 | return; |
173 | } | 163 | } |
174 | ctx = GNUNET_malloc (sizeof (struct TcpContext)); | 164 | ctx = GNUNET_malloc (sizeof (struct TcpContext)); |
175 | ctx->s = s; | 165 | ctx->s = s; |
176 | ctx->data = data; | 166 | ctx->data = data; |
177 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_SECONDS, | 167 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_SECONDS, s, &tcp_send, ctx); |
178 | s, | ||
179 | &tcp_send, ctx); | ||
180 | } | 168 | } |
181 | 169 | ||
182 | 170 | ||
@@ -189,34 +177,33 @@ try_send_tcp (uint32_t dst_ipv4, | |||
189 | * @param data data to send | 177 | * @param data data to send |
190 | */ | 178 | */ |
191 | static void | 179 | static void |
192 | try_send_udp (uint32_t dst_ipv4, | 180 | try_send_udp (uint32_t dst_ipv4, uint16_t dport, uint16_t data) |
193 | uint16_t dport, | ||
194 | uint16_t data) | ||
195 | { | 181 | { |
196 | struct GNUNET_NETWORK_Handle *s; | 182 | struct GNUNET_NETWORK_Handle *s; |
197 | struct sockaddr_in sa; | 183 | struct sockaddr_in sa; |
198 | 184 | ||
199 | s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0); | 185 | s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0); |
200 | if (NULL == s) | 186 | if (NULL == s) |
201 | { | 187 | { |
202 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); | 188 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); |
203 | return; | 189 | return; |
204 | } | 190 | } |
205 | memset (&sa, 0, sizeof (sa)); | 191 | memset (&sa, 0, sizeof (sa)); |
206 | sa.sin_family = AF_INET; | 192 | sa.sin_family = AF_INET; |
207 | #if HAVE_SOCKADDR_IN_SIN_LEN | 193 | #if HAVE_SOCKADDR_IN_SIN_LEN |
208 | sa.sin_len = sizeof (sa); | 194 | sa.sin_len = sizeof (sa); |
209 | #endif | 195 | #endif |
210 | sa.sin_addr.s_addr = dst_ipv4; | 196 | sa.sin_addr.s_addr = dst_ipv4; |
211 | sa.sin_port = htons (dport); | 197 | sa.sin_port = htons (dport); |
212 | #if DEBUG_NAT | 198 | #if DEBUG_NAT |
213 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 199 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
214 | "Sending UDP packet to `%s'\n", | 200 | "Sending UDP packet to `%s'\n", |
215 | GNUNET_a2s ((struct sockaddr*) &sa, sizeof (sa))); | 201 | GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa))); |
216 | #endif | 202 | #endif |
217 | if (-1 == GNUNET_NETWORK_socket_sendto (s, | 203 | if (-1 == GNUNET_NETWORK_socket_sendto (s, |
218 | &data, sizeof(data), | 204 | &data, sizeof (data), |
219 | (const struct sockaddr*) &sa, sizeof (sa))) | 205 | (const struct sockaddr *) &sa, |
206 | sizeof (sa))) | ||
220 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); | 207 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); |
221 | GNUNET_NETWORK_socket_close (s); | 208 | GNUNET_NETWORK_socket_close (s); |
222 | } | 209 | } |
@@ -239,21 +226,17 @@ test (void *cls, | |||
239 | uint16_t dport; | 226 | uint16_t dport; |
240 | 227 | ||
241 | #if DEBUG_NAT | 228 | #if DEBUG_NAT |
242 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 229 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received test request\n"); |
243 | "Received test request\n"); | ||
244 | #endif | 230 | #endif |
245 | tm = (const struct GNUNET_NAT_TestMessage*) msg; | 231 | tm = (const struct GNUNET_NAT_TestMessage *) msg; |
246 | dport = ntohs (tm->dport); | 232 | dport = ntohs (tm->dport); |
247 | if (0 == dport) | 233 | if (0 == dport) |
248 | try_anat (tm->dst_ipv4, | 234 | try_anat (tm->dst_ipv4, ntohs (tm->data), (int) ntohl (tm->is_tcp)); |
249 | ntohs (tm->data), | ||
250 | (int) ntohl (tm->is_tcp)); | ||
251 | else if (GNUNET_YES == ntohl (tm->is_tcp)) | 235 | else if (GNUNET_YES == ntohl (tm->is_tcp)) |
252 | try_send_tcp (tm->dst_ipv4, dport, tm->data); | 236 | try_send_tcp (tm->dst_ipv4, dport, tm->data); |
253 | else | 237 | else |
254 | try_send_udp (tm->dst_ipv4, dport, tm->data); | 238 | try_send_udp (tm->dst_ipv4, dport, tm->data); |
255 | GNUNET_SERVER_receive_done (client, | 239 | GNUNET_SERVER_receive_done (client, GNUNET_NO); |
256 | GNUNET_NO); | ||
257 | } | 240 | } |
258 | 241 | ||
259 | 242 | ||
@@ -264,8 +247,7 @@ test (void *cls, | |||
264 | * @param tc scheduler context | 247 | * @param tc scheduler context |
265 | */ | 248 | */ |
266 | static void | 249 | static void |
267 | shutdown_task (void *cls, | 250 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
268 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
269 | { | 251 | { |
270 | GNUNET_SERVER_destroy (server); | 252 | GNUNET_SERVER_destroy (server); |
271 | server = NULL; | 253 | server = NULL; |
@@ -283,43 +265,40 @@ shutdown_task (void *cls, | |||
283 | static void | 265 | static void |
284 | run (void *cls, | 266 | run (void *cls, |
285 | char *const *args, | 267 | char *const *args, |
286 | const char *cfgfile, | 268 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) |
287 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
288 | { | 269 | { |
289 | static const struct GNUNET_SERVER_MessageHandler handlers[] = | 270 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
290 | { | 271 | {&test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST, |
291 | { &test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST, sizeof (struct GNUNET_NAT_TestMessage) }, | 272 | sizeof (struct GNUNET_NAT_TestMessage)}, |
292 | { NULL, NULL, 0, 0 } | 273 | {NULL, NULL, 0, 0} |
293 | }; | 274 | }; |
294 | unsigned int port; | 275 | unsigned int port; |
295 | struct sockaddr_in in4; | 276 | struct sockaddr_in in4; |
296 | struct sockaddr_in6 in6; | 277 | struct sockaddr_in6 in6; |
297 | socklen_t slen[] = | 278 | |
298 | { | 279 | socklen_t slen[] = { |
299 | sizeof (in4), | 280 | sizeof (in4), |
300 | sizeof (in6), | 281 | sizeof (in6), |
301 | 0 | 282 | 0 |
302 | }; | 283 | }; |
303 | struct sockaddr *sa[] = | 284 | struct sockaddr *sa[] = { |
304 | { | 285 | (struct sockaddr *) &in4, |
305 | (struct sockaddr*) &in4, | 286 | (struct sockaddr *) &in6, |
306 | (struct sockaddr*) &in6, | 287 | NULL |
307 | NULL | 288 | }; |
308 | }; | ||
309 | 289 | ||
310 | cfg = c; | 290 | cfg = c; |
311 | if ( (args[0] == NULL) || | 291 | if ((args[0] == NULL) || |
312 | (1 != SSCANF (args[0], "%u", &port)) || | 292 | (1 != SSCANF (args[0], "%u", &port)) || (0 == port) || (65536 <= port)) |
313 | (0 == port) || | 293 | { |
314 | (65536 <= port) ) | 294 | fprintf (stderr, |
315 | { | 295 | _ |
316 | fprintf (stderr, | 296 | ("Please pass valid port number as the first argument! (got `%s')\n"), |
317 | _("Please pass valid port number as the first argument! (got `%s')\n"), | 297 | args[0]); |
318 | args[0]); | 298 | return; |
319 | return; | 299 | } |
320 | } | 300 | memset (&in4, 0, sizeof (in4)); |
321 | memset (&in4, 0, sizeof (in4)); | 301 | memset (&in6, 0, sizeof (in6)); |
322 | memset (&in6, 0, sizeof (in6)); | ||
323 | in4.sin_family = AF_INET; | 302 | in4.sin_family = AF_INET; |
324 | in4.sin_port = htons ((uint16_t) port); | 303 | in4.sin_port = htons ((uint16_t) port); |
325 | in6.sin6_family = AF_INET6; | 304 | in6.sin6_family = AF_INET6; |
@@ -329,15 +308,11 @@ run (void *cls, | |||
329 | in6.sin6_len = sizeof (in6); | 308 | in6.sin6_len = sizeof (in6); |
330 | #endif | 309 | #endif |
331 | server = GNUNET_SERVER_create (NULL, NULL, | 310 | server = GNUNET_SERVER_create (NULL, NULL, |
332 | (struct sockaddr*const*) sa, | 311 | (struct sockaddr * const *) sa, |
333 | slen, | 312 | slen, GNUNET_TIME_UNIT_SECONDS, GNUNET_YES); |
334 | GNUNET_TIME_UNIT_SECONDS, | 313 | GNUNET_SERVER_add_handlers (server, handlers); |
335 | GNUNET_YES); | ||
336 | GNUNET_SERVER_add_handlers (server, | ||
337 | handlers); | ||
338 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 314 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
339 | &shutdown_task, | 315 | &shutdown_task, NULL); |
340 | NULL); | ||
341 | } | 316 | } |
342 | 317 | ||
343 | 318 | ||
@@ -356,11 +331,10 @@ main (int argc, char *const argv[]) | |||
356 | }; | 331 | }; |
357 | 332 | ||
358 | if (GNUNET_OK != | 333 | if (GNUNET_OK != |
359 | GNUNET_PROGRAM_run (argc, argv, | 334 | GNUNET_PROGRAM_run (argc, argv, |
360 | "gnunet-nat-server [options] PORT", | 335 | "gnunet-nat-server [options] PORT", |
361 | _("GNUnet NAT traversal test helper daemon"), | 336 | _("GNUnet NAT traversal test helper daemon"), |
362 | options, | 337 | options, &run, NULL)) |
363 | &run, NULL)) | ||
364 | return 1; | 338 | return 1; |
365 | return 0; | 339 | return 0; |
366 | } | 340 | } |