diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-08-15 21:46:35 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-08-15 21:46:35 +0000 |
commit | 502af2167f7c218366666ca4944bd7cc54b5b19a (patch) | |
tree | a91fec5cc9769d260640bd91c6633cb9cf395524 /src/nat | |
parent | 03af5a603b7cc53432249d5854cd412aa90dde0d (diff) | |
download | gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.tar.gz gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.zip |
indentation
Diffstat (limited to 'src/nat')
-rw-r--r-- | src/nat/gnunet-helper-nat-client-windows.c | 303 | ||||
-rw-r--r-- | src/nat/gnunet-helper-nat-client.c | 278 | ||||
-rw-r--r-- | src/nat/gnunet-helper-nat-server-windows.c | 419 | ||||
-rw-r--r-- | src/nat/gnunet-helper-nat-server.c | 401 | ||||
-rw-r--r-- | src/nat/gnunet-nat-server.c | 200 | ||||
-rw-r--r-- | src/nat/nat.c | 1187 | ||||
-rw-r--r-- | src/nat/nat.h | 6 | ||||
-rw-r--r-- | src/nat/nat_mini.c | 423 | ||||
-rw-r--r-- | src/nat/nat_test.c | 289 | ||||
-rw-r--r-- | src/nat/test_nat.c | 32 | ||||
-rw-r--r-- | src/nat/test_nat_mini.c | 34 | ||||
-rw-r--r-- | src/nat/test_nat_test.c | 34 |
12 files changed, 1594 insertions, 2012 deletions
diff --git a/src/nat/gnunet-helper-nat-client-windows.c b/src/nat/gnunet-helper-nat-client-windows.c index 0717eecfe..0fa62ff7c 100644 --- a/src/nat/gnunet-helper-nat-client-windows.c +++ b/src/nat/gnunet-helper-nat-client-windows.c | |||
@@ -193,19 +193,14 @@ static uint16_t port; | |||
193 | * @return 1 on success | 193 | * @return 1 on success |
194 | */ | 194 | */ |
195 | static int | 195 | static int |
196 | inet_pton (int af, | 196 | inet_pton (int af, const char *cp, struct in_addr *buf) |
197 | const char *cp, | ||
198 | struct in_addr *buf) | ||
199 | { | 197 | { |
200 | buf->s_addr = inet_addr(cp); | 198 | buf->s_addr = inet_addr (cp); |
201 | if (buf->s_addr == INADDR_NONE) | 199 | if (buf->s_addr == INADDR_NONE) |
202 | { | 200 | { |
203 | fprintf(stderr, | 201 | fprintf (stderr, "Error %d handling address %s", WSAGetLastError (), cp); |
204 | "Error %d handling address %s", | 202 | return 0; |
205 | WSAGetLastError(), | 203 | } |
206 | cp); | ||
207 | return 0; | ||
208 | } | ||
209 | return 1; | 204 | return 1; |
210 | } | 205 | } |
211 | 206 | ||
@@ -218,17 +213,16 @@ inet_pton (int af, | |||
218 | * @return the CRC 16. | 213 | * @return the CRC 16. |
219 | */ | 214 | */ |
220 | static uint16_t | 215 | static uint16_t |
221 | calc_checksum(const uint16_t *data, | 216 | calc_checksum (const uint16_t * data, unsigned int bytes) |
222 | unsigned int bytes) | ||
223 | { | 217 | { |
224 | uint32_t sum; | 218 | uint32_t sum; |
225 | unsigned int i; | 219 | unsigned int i; |
226 | 220 | ||
227 | sum = 0; | 221 | sum = 0; |
228 | for (i=0;i<bytes/2;i++) | 222 | for (i = 0; i < bytes / 2; i++) |
229 | sum += data[i]; | 223 | sum += data[i]; |
230 | sum = (sum & 0xffff) + (sum >> 16); | 224 | sum = (sum & 0xffff) + (sum >> 16); |
231 | sum = htons(0xffff - sum); | 225 | sum = htons (0xffff - sum); |
232 | return sum; | 226 | return sum; |
233 | } | 227 | } |
234 | 228 | ||
@@ -240,12 +234,11 @@ calc_checksum(const uint16_t *data, | |||
240 | * @param other target address | 234 | * @param other target address |
241 | */ | 235 | */ |
242 | static void | 236 | static void |
243 | send_icmp_udp (const struct in_addr *my_ip, | 237 | send_icmp_udp (const struct in_addr *my_ip, const struct in_addr *other) |
244 | const struct in_addr *other) | ||
245 | { | 238 | { |
246 | char packet[sizeof(struct ip_header) * 2 + | 239 | char packet[sizeof (struct ip_header) * 2 + |
247 | sizeof(struct icmp_ttl_exceeded_header) + | 240 | sizeof (struct icmp_ttl_exceeded_header) + |
248 | sizeof(struct udp_header)]; | 241 | sizeof (struct udp_header)]; |
249 | struct ip_header ip_pkt; | 242 | struct ip_header ip_pkt; |
250 | struct icmp_ttl_exceeded_header icmp_pkt; | 243 | struct icmp_ttl_exceeded_header icmp_pkt; |
251 | struct udp_header udp_pkt; | 244 | struct udp_header udp_pkt; |
@@ -257,86 +250,74 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
257 | off = 0; | 250 | off = 0; |
258 | ip_pkt.vers_ihl = 0x45; | 251 | ip_pkt.vers_ihl = 0x45; |
259 | ip_pkt.tos = 0; | 252 | ip_pkt.tos = 0; |
260 | ip_pkt.pkt_len = htons(sizeof (packet)); | 253 | ip_pkt.pkt_len = htons (sizeof (packet)); |
261 | ip_pkt.id = htons(256); | 254 | ip_pkt.id = htons (256); |
262 | ip_pkt.flags_frag_offset = 0; | 255 | ip_pkt.flags_frag_offset = 0; |
263 | ip_pkt.ttl = 128; | 256 | ip_pkt.ttl = 128; |
264 | ip_pkt.proto = IPPROTO_ICMP; | 257 | ip_pkt.proto = IPPROTO_ICMP; |
265 | ip_pkt.checksum = 0; | 258 | ip_pkt.checksum = 0; |
266 | ip_pkt.src_ip = my_ip->s_addr; | 259 | ip_pkt.src_ip = my_ip->s_addr; |
267 | ip_pkt.dst_ip = other->s_addr; | 260 | ip_pkt.dst_ip = other->s_addr; |
268 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 261 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
269 | sizeof (struct ip_header))); | 262 | sizeof (struct ip_header))); |
270 | memcpy(&packet[off], | 263 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
271 | &ip_pkt, | 264 | off += sizeof (struct ip_header); |
272 | sizeof(struct ip_header)); | ||
273 | off += sizeof(struct ip_header); | ||
274 | 265 | ||
275 | icmp_pkt.type = ICMP_TIME_EXCEEDED; | 266 | icmp_pkt.type = ICMP_TIME_EXCEEDED; |
276 | icmp_pkt.code = 0; | 267 | icmp_pkt.code = 0; |
277 | icmp_pkt.checksum = 0; | 268 | icmp_pkt.checksum = 0; |
278 | icmp_pkt.unused = 0; | 269 | icmp_pkt.unused = 0; |
279 | memcpy(&packet[off], | 270 | memcpy (&packet[off], &icmp_pkt, sizeof (struct icmp_ttl_exceeded_header)); |
280 | &icmp_pkt, | 271 | off += sizeof (struct icmp_ttl_exceeded_header); |
281 | sizeof(struct icmp_ttl_exceeded_header)); | ||
282 | off += sizeof(struct icmp_ttl_exceeded_header); | ||
283 | 272 | ||
284 | /* ip header of the presumably 'lost' udp packet */ | 273 | /* ip header of the presumably 'lost' udp packet */ |
285 | ip_pkt.vers_ihl = 0x45; | 274 | ip_pkt.vers_ihl = 0x45; |
286 | ip_pkt.tos = 0; | 275 | ip_pkt.tos = 0; |
287 | ip_pkt.pkt_len = htons(sizeof (struct ip_header) + | 276 | ip_pkt.pkt_len = htons (sizeof (struct ip_header) + |
288 | sizeof (struct udp_header)); | 277 | sizeof (struct udp_header)); |
289 | ip_pkt.id = htons(0); | 278 | ip_pkt.id = htons (0); |
290 | ip_pkt.flags_frag_offset = 0; | 279 | ip_pkt.flags_frag_offset = 0; |
291 | ip_pkt.ttl = 128; | 280 | ip_pkt.ttl = 128; |
292 | ip_pkt.proto = IPPROTO_UDP; | 281 | ip_pkt.proto = IPPROTO_UDP; |
293 | ip_pkt.checksum = 0; | 282 | ip_pkt.checksum = 0; |
294 | ip_pkt.src_ip = other->s_addr; | 283 | ip_pkt.src_ip = other->s_addr; |
295 | ip_pkt.dst_ip = dummy.s_addr; | 284 | ip_pkt.dst_ip = dummy.s_addr; |
296 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 285 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
297 | sizeof (struct ip_header))); | 286 | sizeof (struct ip_header))); |
298 | memcpy(&packet[off], | 287 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
299 | &ip_pkt, | 288 | off += sizeof (struct ip_header); |
300 | sizeof(struct ip_header)); | ||
301 | off += sizeof(struct ip_header); | ||
302 | 289 | ||
303 | /* build UDP header */ | 290 | /* build UDP header */ |
304 | udp_pkt.src_port = htons(NAT_TRAV_PORT); | 291 | udp_pkt.src_port = htons (NAT_TRAV_PORT); |
305 | udp_pkt.dst_port = htons(NAT_TRAV_PORT); | 292 | udp_pkt.dst_port = htons (NAT_TRAV_PORT); |
306 | udp_pkt.length = htons (port); | 293 | udp_pkt.length = htons (port); |
307 | udp_pkt.crc = 0; | 294 | udp_pkt.crc = 0; |
308 | memcpy(&packet[off], | 295 | memcpy (&packet[off], &udp_pkt, sizeof (struct udp_header)); |
309 | &udp_pkt, | 296 | off += sizeof (struct udp_header); |
310 | sizeof(struct udp_header)); | ||
311 | off += sizeof(struct udp_header); | ||
312 | 297 | ||
313 | /* no go back to calculate ICMP packet checksum */ | 298 | /* no go back to calculate ICMP packet checksum */ |
314 | icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[off], | 299 | icmp_pkt.checksum = htons (calc_checksum ((uint16_t *) & packet[off], |
315 | sizeof (struct icmp_ttl_exceeded_header) + | 300 | sizeof (struct |
316 | sizeof (struct ip_header) + | 301 | icmp_ttl_exceeded_header) + |
317 | sizeof (struct udp_header))); | 302 | sizeof (struct ip_header) + |
318 | memcpy (&packet[sizeof (struct ip_header)], | 303 | sizeof (struct udp_header))); |
319 | &icmp_pkt, | 304 | memcpy (&packet[sizeof (struct ip_header)], &icmp_pkt, |
320 | sizeof (struct icmp_ttl_exceeded_header)); | 305 | sizeof (struct icmp_ttl_exceeded_header)); |
321 | 306 | ||
322 | memset (&dst, 0, sizeof (dst)); | 307 | memset (&dst, 0, sizeof (dst)); |
323 | dst.sin_family = AF_INET; | 308 | dst.sin_family = AF_INET; |
324 | dst.sin_addr = *other; | 309 | dst.sin_addr = *other; |
325 | err = sendto(rawsock, | 310 | err = sendto (rawsock, |
326 | packet, | 311 | packet, |
327 | sizeof (packet), 0, | 312 | sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst)); |
328 | (struct sockaddr*)&dst, | ||
329 | sizeof(dst)); | ||
330 | if (err < 0) | 313 | if (err < 0) |
331 | { | 314 | { |
332 | fprintf(stderr, | 315 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
333 | "sendto failed: %s\n", strerror(errno)); | 316 | } |
334 | } | ||
335 | else if (sizeof (packet) != (size_t) err) | 317 | else if (sizeof (packet) != (size_t) err) |
336 | { | 318 | { |
337 | fprintf(stderr, | 319 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
338 | "Error: partial send of ICMP message\n"); | 320 | } |
339 | } | ||
340 | } | 321 | } |
341 | 322 | ||
342 | 323 | ||
@@ -347,16 +328,15 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
347 | * @param other target address | 328 | * @param other target address |
348 | */ | 329 | */ |
349 | static void | 330 | static void |
350 | send_icmp (const struct in_addr *my_ip, | 331 | send_icmp (const struct in_addr *my_ip, const struct in_addr *other) |
351 | const struct in_addr *other) | ||
352 | { | 332 | { |
353 | struct ip_header ip_pkt; | 333 | struct ip_header ip_pkt; |
354 | struct icmp_ttl_exceeded_header icmp_ttl; | 334 | struct icmp_ttl_exceeded_header icmp_ttl; |
355 | struct icmp_echo_header icmp_echo; | 335 | struct icmp_echo_header icmp_echo; |
356 | struct sockaddr_in dst; | 336 | struct sockaddr_in dst; |
357 | char packet[sizeof (struct ip_header) * 2 + | 337 | char packet[sizeof (struct ip_header) * 2 + |
358 | sizeof (struct icmp_ttl_exceeded_header) + | 338 | sizeof (struct icmp_ttl_exceeded_header) + |
359 | sizeof(struct icmp_echo_header)]; | 339 | sizeof (struct icmp_echo_header)]; |
360 | size_t off; | 340 | size_t off; |
361 | int err; | 341 | int err; |
362 | 342 | ||
@@ -365,88 +345,76 @@ send_icmp (const struct in_addr *my_ip, | |||
365 | ip_pkt.vers_ihl = 0x45; | 345 | ip_pkt.vers_ihl = 0x45; |
366 | ip_pkt.tos = 0; | 346 | ip_pkt.tos = 0; |
367 | ip_pkt.pkt_len = htons (sizeof (packet)); | 347 | ip_pkt.pkt_len = htons (sizeof (packet)); |
368 | ip_pkt.id = htons(256); | 348 | ip_pkt.id = htons (256); |
369 | ip_pkt.flags_frag_offset = 0; | 349 | ip_pkt.flags_frag_offset = 0; |
370 | ip_pkt.ttl = IPDEFTTL; | 350 | ip_pkt.ttl = IPDEFTTL; |
371 | ip_pkt.proto = IPPROTO_ICMP; | 351 | ip_pkt.proto = IPPROTO_ICMP; |
372 | ip_pkt.checksum = 0; | 352 | ip_pkt.checksum = 0; |
373 | ip_pkt.src_ip = my_ip->s_addr; | 353 | ip_pkt.src_ip = my_ip->s_addr; |
374 | ip_pkt.dst_ip = other->s_addr; | 354 | ip_pkt.dst_ip = other->s_addr; |
375 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 355 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
376 | sizeof (struct ip_header))); | 356 | sizeof (struct ip_header))); |
377 | memcpy (&packet[off], | 357 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
378 | &ip_pkt, | ||
379 | sizeof (struct ip_header)); | ||
380 | off += sizeof (ip_pkt); | 358 | off += sizeof (ip_pkt); |
381 | 359 | ||
382 | /* icmp reply: time exceeded */ | 360 | /* icmp reply: time exceeded */ |
383 | icmp_ttl.type = ICMP_TIME_EXCEEDED; | 361 | icmp_ttl.type = ICMP_TIME_EXCEEDED; |
384 | icmp_ttl.code = 0; | 362 | icmp_ttl.code = 0; |
385 | icmp_ttl.checksum = 0; | 363 | icmp_ttl.checksum = 0; |
386 | icmp_ttl.unused = 0; | 364 | icmp_ttl.unused = 0; |
387 | memcpy (&packet[off], | 365 | memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header)); |
388 | &icmp_ttl, | ||
389 | sizeof (struct icmp_ttl_exceeded_header)); | ||
390 | off += sizeof (struct icmp_ttl_exceeded_header); | 366 | off += sizeof (struct icmp_ttl_exceeded_header); |
391 | 367 | ||
392 | /* ip header of the presumably 'lost' udp packet */ | 368 | /* ip header of the presumably 'lost' udp packet */ |
393 | ip_pkt.vers_ihl = 0x45; | 369 | ip_pkt.vers_ihl = 0x45; |
394 | ip_pkt.tos = 0; | 370 | ip_pkt.tos = 0; |
395 | ip_pkt.pkt_len = htons(sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); | 371 | ip_pkt.pkt_len = |
372 | htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); | ||
396 | ip_pkt.id = htons (256); | 373 | ip_pkt.id = htons (256); |
397 | ip_pkt.flags_frag_offset = 0; | 374 | ip_pkt.flags_frag_offset = 0; |
398 | ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ | 375 | ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ |
399 | ip_pkt.proto = IPPROTO_ICMP; | 376 | ip_pkt.proto = IPPROTO_ICMP; |
400 | ip_pkt.src_ip = other->s_addr; | 377 | ip_pkt.src_ip = other->s_addr; |
401 | ip_pkt.dst_ip = dummy.s_addr; | 378 | ip_pkt.dst_ip = dummy.s_addr; |
402 | ip_pkt.checksum = 0; | 379 | ip_pkt.checksum = 0; |
403 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 380 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
404 | sizeof (struct ip_header))); | 381 | sizeof (struct ip_header))); |
405 | memcpy (&packet[off], | 382 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
406 | &ip_pkt, | ||
407 | sizeof (struct ip_header)); | ||
408 | off += sizeof (struct ip_header); | 383 | off += sizeof (struct ip_header); |
409 | 384 | ||
410 | icmp_echo.type = ICMP_ECHO; | 385 | icmp_echo.type = ICMP_ECHO; |
411 | icmp_echo.code = 0; | 386 | icmp_echo.code = 0; |
412 | icmp_echo.reserved = htonl(port); | 387 | icmp_echo.reserved = htonl (port); |
413 | icmp_echo.checksum = 0; | 388 | icmp_echo.checksum = 0; |
414 | icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, | 389 | icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo, |
415 | sizeof (struct icmp_echo_header))); | 390 | sizeof (struct icmp_echo_header))); |
416 | memcpy (&packet[off], | 391 | memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header)); |
417 | &icmp_echo, | ||
418 | sizeof(struct icmp_echo_header)); | ||
419 | 392 | ||
420 | /* no go back to calculate ICMP packet checksum */ | 393 | /* no go back to calculate ICMP packet checksum */ |
421 | off = sizeof (struct ip_header); | 394 | off = sizeof (struct ip_header); |
422 | icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off], | 395 | icmp_ttl.checksum = htons (calc_checksum ((uint16_t *) & packet[off], |
423 | sizeof (struct icmp_ttl_exceeded_header) + | 396 | sizeof (struct |
424 | sizeof (struct ip_header) + | 397 | icmp_ttl_exceeded_header) + |
425 | sizeof (struct icmp_echo_header))); | 398 | sizeof (struct ip_header) + |
426 | memcpy (&packet[off], | 399 | sizeof (struct icmp_echo_header))); |
427 | &icmp_ttl, | 400 | memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header)); |
428 | sizeof (struct icmp_ttl_exceeded_header)); | ||
429 | 401 | ||
430 | memset (&dst, 0, sizeof (dst)); | 402 | memset (&dst, 0, sizeof (dst)); |
431 | dst.sin_family = AF_INET; | 403 | dst.sin_family = AF_INET; |
432 | dst.sin_addr = *other; | 404 | dst.sin_addr = *other; |
433 | 405 | ||
434 | err = sendto(rawsock, | 406 | err = sendto (rawsock, |
435 | packet, | 407 | packet, |
436 | sizeof (packet), 0, | 408 | sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst)); |
437 | (struct sockaddr*)&dst, | ||
438 | sizeof(dst)); | ||
439 | 409 | ||
440 | if (err < 0) | 410 | if (err < 0) |
441 | { | 411 | { |
442 | fprintf(stderr, | 412 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
443 | "sendto failed: %s\n", strerror(errno)); | 413 | } |
444 | } | ||
445 | else if (sizeof (packet) != (size_t) err) | 414 | else if (sizeof (packet) != (size_t) err) |
446 | { | 415 | { |
447 | fprintf(stderr, | 416 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
448 | "Error: partial send of ICMP message\n"); | 417 | } |
449 | } | ||
450 | } | 418 | } |
451 | 419 | ||
452 | 420 | ||
@@ -459,34 +427,30 @@ static SOCKET | |||
459 | make_raw_socket () | 427 | make_raw_socket () |
460 | { | 428 | { |
461 | DWORD bOptVal = TRUE; | 429 | DWORD bOptVal = TRUE; |
462 | int bOptLen = sizeof(bOptVal); | 430 | int bOptLen = sizeof (bOptVal); |
463 | SOCKET ret; | 431 | SOCKET ret; |
464 | 432 | ||
465 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); | 433 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); |
466 | if (INVALID_SOCKET == ret) | 434 | if (INVALID_SOCKET == ret) |
467 | { | 435 | { |
468 | fprintf (stderr, | 436 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); |
469 | "Error opening RAW socket: %s\n", | 437 | return INVALID_SOCKET; |
470 | strerror (errno)); | 438 | } |
471 | return INVALID_SOCKET; | 439 | if (0 != |
472 | } | 440 | setsockopt (ret, SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal, bOptLen)) |
473 | if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen)) | 441 | { |
474 | { | 442 | fprintf (stderr, |
475 | fprintf(stderr, | 443 | "Error setting SO_BROADCAST to ON: %s\n", strerror (errno)); |
476 | "Error setting SO_BROADCAST to ON: %s\n", | 444 | closesocket (rawsock); |
477 | strerror (errno)); | 445 | return INVALID_SOCKET; |
478 | closesocket(rawsock); | 446 | } |
479 | return INVALID_SOCKET; | 447 | |
480 | } | 448 | if (0 != setsockopt (ret, IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen)) |
481 | 449 | { | |
482 | if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen)) | 450 | fprintf (stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror (errno)); |
483 | { | 451 | closesocket (rawsock); |
484 | fprintf(stderr, | 452 | return INVALID_SOCKET; |
485 | "Error setting IP_HDRINCL to ON: %s\n", | 453 | } |
486 | strerror (errno)); | ||
487 | closesocket(rawsock); | ||
488 | return INVALID_SOCKET; | ||
489 | } | ||
490 | return ret; | 454 | return ret; |
491 | } | 455 | } |
492 | 456 | ||
@@ -501,47 +465,38 @@ main (int argc, char *const *argv) | |||
501 | unsigned int p; | 465 | unsigned int p; |
502 | 466 | ||
503 | if (argc != 4) | 467 | if (argc != 4) |
504 | { | 468 | { |
505 | fprintf (stderr, | 469 | fprintf (stderr, |
506 | "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); | 470 | "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); |
507 | return 1; | 471 | return 1; |
508 | } | 472 | } |
509 | if ( (1 != inet_pton (AF_INET, argv[1], &external)) || | 473 | if ((1 != inet_pton (AF_INET, argv[1], &external)) || |
510 | (1 != inet_pton (AF_INET, argv[2], &target)) ) | 474 | (1 != inet_pton (AF_INET, argv[2], &target))) |
511 | { | 475 | { |
512 | fprintf (stderr, | 476 | fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno)); |
513 | "Error parsing IPv4 address: %s\n", | 477 | return 1; |
514 | strerror (errno)); | 478 | } |
515 | return 1; | 479 | if ((1 != sscanf (argv[3], "%u", &p)) || (0 == p) || (0xFFFF < p)) |
516 | } | 480 | { |
517 | if ( (1 != sscanf (argv[3], "%u", &p) ) || | 481 | fprintf (stderr, "Error parsing port value `%s'\n", argv[3]); |
518 | (0 == p) || | 482 | return 1; |
519 | (0xFFFF < p) ) | 483 | } |
520 | { | ||
521 | fprintf (stderr, | ||
522 | "Error parsing port value `%s'\n", | ||
523 | argv[3]); | ||
524 | return 1; | ||
525 | } | ||
526 | port = (uint16_t) p; | 484 | port = (uint16_t) p; |
527 | 485 | ||
528 | if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData)) | 486 | if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData)) |
529 | { | 487 | { |
530 | fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); | 488 | fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); |
531 | return 2; | 489 | return 2; |
532 | } | 490 | } |
533 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 491 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) |
534 | { | 492 | { |
535 | fprintf (stderr, | 493 | fprintf (stderr, "Internal error converting dummy IP to binary.\n"); |
536 | "Internal error converting dummy IP to binary.\n"); | 494 | return 2; |
537 | return 2; | 495 | } |
538 | } | 496 | if (-1 == (rawsock = make_raw_socket ())) |
539 | if (-1 == (rawsock = make_raw_socket())) | ||
540 | return 3; | 497 | return 3; |
541 | send_icmp (&external, | 498 | send_icmp (&external, &target); |
542 | &target); | 499 | send_icmp_udp (&external, &target); |
543 | send_icmp_udp (&external, | ||
544 | &target); | ||
545 | closesocket (rawsock); | 500 | closesocket (rawsock); |
546 | WSACleanup (); | 501 | WSACleanup (); |
547 | return 0; | 502 | return 0; |
diff --git a/src/nat/gnunet-helper-nat-client.c b/src/nat/gnunet-helper-nat-client.c index 10aa2f438..76f405bf1 100644 --- a/src/nat/gnunet-helper-nat-client.c +++ b/src/nat/gnunet-helper-nat-client.c | |||
@@ -190,17 +190,16 @@ static uint16_t port; | |||
190 | * @return the CRC 16. | 190 | * @return the CRC 16. |
191 | */ | 191 | */ |
192 | static uint16_t | 192 | static uint16_t |
193 | calc_checksum (const uint16_t *data, | 193 | calc_checksum (const uint16_t * data, unsigned int bytes) |
194 | unsigned int bytes) | ||
195 | { | 194 | { |
196 | uint32_t sum; | 195 | uint32_t sum; |
197 | unsigned int i; | 196 | unsigned int i; |
198 | 197 | ||
199 | sum = 0; | 198 | sum = 0; |
200 | for (i=0;i<bytes/2;i++) | 199 | for (i = 0; i < bytes / 2; i++) |
201 | sum += data[i]; | 200 | sum += data[i]; |
202 | sum = (sum & 0xffff) + (sum >> 16); | 201 | sum = (sum & 0xffff) + (sum >> 16); |
203 | sum = htons(0xffff - sum); | 202 | sum = htons (0xffff - sum); |
204 | return sum; | 203 | return sum; |
205 | } | 204 | } |
206 | 205 | ||
@@ -212,12 +211,11 @@ calc_checksum (const uint16_t *data, | |||
212 | * @param other target address | 211 | * @param other target address |
213 | */ | 212 | */ |
214 | static void | 213 | static void |
215 | send_icmp_udp (const struct in_addr *my_ip, | 214 | send_icmp_udp (const struct in_addr *my_ip, const struct in_addr *other) |
216 | const struct in_addr *other) | ||
217 | { | 215 | { |
218 | char packet[sizeof(struct ip_header) * 2 + | 216 | char packet[sizeof (struct ip_header) * 2 + |
219 | sizeof(struct icmp_ttl_exceeded_header) + | 217 | sizeof (struct icmp_ttl_exceeded_header) + |
220 | sizeof(struct udp_header)]; | 218 | sizeof (struct udp_header)]; |
221 | struct ip_header ip_pkt; | 219 | struct ip_header ip_pkt; |
222 | struct icmp_ttl_exceeded_header icmp_pkt; | 220 | struct icmp_ttl_exceeded_header icmp_pkt; |
223 | struct udp_header udp_pkt; | 221 | struct udp_header udp_pkt; |
@@ -230,66 +228,58 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
230 | ip_pkt.vers_ihl = 0x45; | 228 | ip_pkt.vers_ihl = 0x45; |
231 | ip_pkt.tos = 0; | 229 | ip_pkt.tos = 0; |
232 | ip_pkt.pkt_len = htons (sizeof (packet)); | 230 | ip_pkt.pkt_len = htons (sizeof (packet)); |
233 | ip_pkt.id = htons(256); | 231 | ip_pkt.id = htons (256); |
234 | ip_pkt.flags_frag_offset = 0; | 232 | ip_pkt.flags_frag_offset = 0; |
235 | ip_pkt.ttl = 128; | 233 | ip_pkt.ttl = 128; |
236 | ip_pkt.proto = IPPROTO_ICMP; | 234 | ip_pkt.proto = IPPROTO_ICMP; |
237 | ip_pkt.checksum = 0; | 235 | ip_pkt.checksum = 0; |
238 | ip_pkt.src_ip = my_ip->s_addr; | 236 | ip_pkt.src_ip = my_ip->s_addr; |
239 | ip_pkt.dst_ip = other->s_addr; | 237 | ip_pkt.dst_ip = other->s_addr; |
240 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 238 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
241 | sizeof (struct ip_header))); | 239 | sizeof (struct ip_header))); |
242 | memcpy(&packet[off], | 240 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
243 | &ip_pkt, | 241 | off += sizeof (struct ip_header); |
244 | sizeof(struct ip_header)); | ||
245 | off += sizeof(struct ip_header); | ||
246 | 242 | ||
247 | icmp_pkt.type = ICMP_TIME_EXCEEDED; | 243 | icmp_pkt.type = ICMP_TIME_EXCEEDED; |
248 | icmp_pkt.code = 0; | 244 | icmp_pkt.code = 0; |
249 | icmp_pkt.checksum = 0; | 245 | icmp_pkt.checksum = 0; |
250 | icmp_pkt.unused = 0; | 246 | icmp_pkt.unused = 0; |
251 | memcpy(&packet[off], | 247 | memcpy (&packet[off], &icmp_pkt, sizeof (struct icmp_ttl_exceeded_header)); |
252 | &icmp_pkt, | 248 | off += sizeof (struct icmp_ttl_exceeded_header); |
253 | sizeof(struct icmp_ttl_exceeded_header)); | ||
254 | off += sizeof(struct icmp_ttl_exceeded_header); | ||
255 | 249 | ||
256 | /* ip header of the presumably 'lost' udp packet */ | 250 | /* ip header of the presumably 'lost' udp packet */ |
257 | ip_pkt.vers_ihl = 0x45; | 251 | ip_pkt.vers_ihl = 0x45; |
258 | ip_pkt.tos = 0; | 252 | ip_pkt.tos = 0; |
259 | ip_pkt.pkt_len = htons(sizeof (struct ip_header) + | 253 | ip_pkt.pkt_len = htons (sizeof (struct ip_header) + |
260 | sizeof (struct udp_header)); | 254 | sizeof (struct udp_header)); |
261 | ip_pkt.id = htons(0); | 255 | ip_pkt.id = htons (0); |
262 | ip_pkt.flags_frag_offset = 0; | 256 | ip_pkt.flags_frag_offset = 0; |
263 | ip_pkt.ttl = 128; | 257 | ip_pkt.ttl = 128; |
264 | ip_pkt.proto = IPPROTO_UDP; | 258 | ip_pkt.proto = IPPROTO_UDP; |
265 | ip_pkt.checksum = 0; | 259 | ip_pkt.checksum = 0; |
266 | ip_pkt.src_ip = other->s_addr; | 260 | ip_pkt.src_ip = other->s_addr; |
267 | ip_pkt.dst_ip = dummy.s_addr; | 261 | ip_pkt.dst_ip = dummy.s_addr; |
268 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 262 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
269 | sizeof (struct ip_header))); | 263 | sizeof (struct ip_header))); |
270 | memcpy(&packet[off], | 264 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
271 | &ip_pkt, | 265 | off += sizeof (struct ip_header); |
272 | sizeof(struct ip_header)); | ||
273 | off += sizeof(struct ip_header); | ||
274 | 266 | ||
275 | /* build UDP header */ | 267 | /* build UDP header */ |
276 | udp_pkt.src_port = htons(NAT_TRAV_PORT); | 268 | udp_pkt.src_port = htons (NAT_TRAV_PORT); |
277 | udp_pkt.dst_port = htons(NAT_TRAV_PORT); | 269 | udp_pkt.dst_port = htons (NAT_TRAV_PORT); |
278 | udp_pkt.length = htons (port); | 270 | udp_pkt.length = htons (port); |
279 | udp_pkt.crc = 0; | 271 | udp_pkt.crc = 0; |
280 | memcpy(&packet[off], | 272 | memcpy (&packet[off], &udp_pkt, sizeof (struct udp_header)); |
281 | &udp_pkt, | 273 | off += sizeof (struct udp_header); |
282 | sizeof(struct udp_header)); | ||
283 | off += sizeof(struct udp_header); | ||
284 | 274 | ||
285 | /* set ICMP checksum */ | 275 | /* set ICMP checksum */ |
286 | icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[sizeof(struct ip_header)], | 276 | icmp_pkt.checksum = |
287 | sizeof (struct icmp_ttl_exceeded_header) + | 277 | htons (calc_checksum |
288 | sizeof (struct ip_header) + | 278 | ((uint16_t *) & packet[sizeof (struct ip_header)], |
289 | sizeof (struct udp_header))); | 279 | sizeof (struct icmp_ttl_exceeded_header) + |
290 | memcpy (&packet[sizeof(struct ip_header)], | 280 | sizeof (struct ip_header) + sizeof (struct udp_header))); |
291 | &icmp_pkt, | 281 | memcpy (&packet[sizeof (struct ip_header)], &icmp_pkt, |
292 | sizeof (struct icmp_ttl_exceeded_header)); | 282 | sizeof (struct icmp_ttl_exceeded_header)); |
293 | 283 | ||
294 | memset (&dst, 0, sizeof (dst)); | 284 | memset (&dst, 0, sizeof (dst)); |
295 | dst.sin_family = AF_INET; | 285 | dst.sin_family = AF_INET; |
@@ -297,21 +287,17 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
297 | dst.sin_len = sizeof (struct sockaddr_in); | 287 | dst.sin_len = sizeof (struct sockaddr_in); |
298 | #endif | 288 | #endif |
299 | dst.sin_addr = *other; | 289 | dst.sin_addr = *other; |
300 | err = sendto(rawsock, | 290 | err = sendto (rawsock, |
301 | packet, | 291 | packet, |
302 | sizeof (packet), 0, | 292 | sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst)); |
303 | (struct sockaddr*)&dst, | ||
304 | sizeof(dst)); | ||
305 | if (err < 0) | 293 | if (err < 0) |
306 | { | 294 | { |
307 | fprintf(stderr, | 295 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
308 | "sendto failed: %s\n", strerror(errno)); | 296 | } |
309 | } | ||
310 | else if (sizeof (packet) != (size_t) err) | 297 | else if (sizeof (packet) != (size_t) err) |
311 | { | 298 | { |
312 | fprintf(stderr, | 299 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
313 | "Error: partial send of ICMP message\n"); | 300 | } |
314 | } | ||
315 | } | 301 | } |
316 | 302 | ||
317 | 303 | ||
@@ -322,16 +308,15 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
322 | * @param other target address | 308 | * @param other target address |
323 | */ | 309 | */ |
324 | static void | 310 | static void |
325 | send_icmp (const struct in_addr *my_ip, | 311 | send_icmp (const struct in_addr *my_ip, const struct in_addr *other) |
326 | const struct in_addr *other) | ||
327 | { | 312 | { |
328 | struct ip_header ip_pkt; | 313 | struct ip_header ip_pkt; |
329 | struct icmp_ttl_exceeded_header icmp_ttl; | 314 | struct icmp_ttl_exceeded_header icmp_ttl; |
330 | struct icmp_echo_header icmp_echo; | 315 | struct icmp_echo_header icmp_echo; |
331 | struct sockaddr_in dst; | 316 | struct sockaddr_in dst; |
332 | char packet[sizeof (struct ip_header) * 2 + | 317 | char packet[sizeof (struct ip_header) * 2 + |
333 | sizeof (struct icmp_ttl_exceeded_header) + | 318 | sizeof (struct icmp_ttl_exceeded_header) + |
334 | sizeof (struct icmp_echo_header)]; | 319 | sizeof (struct icmp_echo_header)]; |
335 | size_t off; | 320 | size_t off; |
336 | int err; | 321 | int err; |
337 | 322 | ||
@@ -347,11 +332,9 @@ send_icmp (const struct in_addr *my_ip, | |||
347 | ip_pkt.checksum = 0; | 332 | ip_pkt.checksum = 0; |
348 | ip_pkt.src_ip = my_ip->s_addr; | 333 | ip_pkt.src_ip = my_ip->s_addr; |
349 | ip_pkt.dst_ip = other->s_addr; | 334 | ip_pkt.dst_ip = other->s_addr; |
350 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 335 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
351 | sizeof (struct ip_header))); | 336 | sizeof (struct ip_header))); |
352 | memcpy (&packet[off], | 337 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
353 | &ip_pkt, | ||
354 | sizeof (struct ip_header)); | ||
355 | off = sizeof (ip_pkt); | 338 | off = sizeof (ip_pkt); |
356 | 339 | ||
357 | /* icmp reply: time exceeded */ | 340 | /* icmp reply: time exceeded */ |
@@ -359,48 +342,42 @@ send_icmp (const struct in_addr *my_ip, | |||
359 | icmp_ttl.code = 0; | 342 | icmp_ttl.code = 0; |
360 | icmp_ttl.checksum = 0; | 343 | icmp_ttl.checksum = 0; |
361 | icmp_ttl.unused = 0; | 344 | icmp_ttl.unused = 0; |
362 | memcpy (&packet[off], | 345 | memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header)); |
363 | &icmp_ttl, | ||
364 | sizeof (struct icmp_ttl_exceeded_header)); | ||
365 | off += sizeof (struct icmp_ttl_exceeded_header); | 346 | off += sizeof (struct icmp_ttl_exceeded_header); |
366 | 347 | ||
367 | /* ip header of the presumably 'lost' udp packet */ | 348 | /* ip header of the presumably 'lost' udp packet */ |
368 | ip_pkt.vers_ihl = 0x45; | 349 | ip_pkt.vers_ihl = 0x45; |
369 | ip_pkt.tos = 0; | 350 | ip_pkt.tos = 0; |
370 | ip_pkt.pkt_len = htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); | 351 | ip_pkt.pkt_len = |
352 | htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); | ||
371 | ip_pkt.id = htons (256); | 353 | ip_pkt.id = htons (256); |
372 | ip_pkt.flags_frag_offset = 0; | 354 | ip_pkt.flags_frag_offset = 0; |
373 | ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ | 355 | ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ |
374 | ip_pkt.proto = IPPROTO_ICMP; | 356 | ip_pkt.proto = IPPROTO_ICMP; |
375 | ip_pkt.src_ip = other->s_addr; | 357 | ip_pkt.src_ip = other->s_addr; |
376 | ip_pkt.dst_ip = dummy.s_addr; | 358 | ip_pkt.dst_ip = dummy.s_addr; |
377 | ip_pkt.checksum = 0; | 359 | ip_pkt.checksum = 0; |
378 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 360 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
379 | sizeof (struct ip_header))); | 361 | sizeof (struct ip_header))); |
380 | memcpy (&packet[off], | 362 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
381 | &ip_pkt, | ||
382 | sizeof (struct ip_header)); | ||
383 | off += sizeof (struct ip_header); | 363 | off += sizeof (struct ip_header); |
384 | 364 | ||
385 | icmp_echo.type = ICMP_ECHO; | 365 | icmp_echo.type = ICMP_ECHO; |
386 | icmp_echo.code = 0; | 366 | icmp_echo.code = 0; |
387 | icmp_echo.reserved = htonl (port); | 367 | icmp_echo.reserved = htonl (port); |
388 | icmp_echo.checksum = 0; | 368 | icmp_echo.checksum = 0; |
389 | icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, | 369 | icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo, |
390 | sizeof (struct icmp_echo_header))); | 370 | sizeof (struct icmp_echo_header))); |
391 | memcpy (&packet[off], | 371 | memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header)); |
392 | &icmp_echo, | ||
393 | sizeof(struct icmp_echo_header)); | ||
394 | 372 | ||
395 | /* no go back to calculate ICMP packet checksum */ | 373 | /* no go back to calculate ICMP packet checksum */ |
396 | off = sizeof (struct ip_header); | 374 | off = sizeof (struct ip_header); |
397 | icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off], | 375 | icmp_ttl.checksum = htons (calc_checksum ((uint16_t *) & packet[off], |
398 | sizeof (struct icmp_ttl_exceeded_header) + | 376 | sizeof (struct |
399 | sizeof (struct ip_header) + | 377 | icmp_ttl_exceeded_header) + |
400 | sizeof (struct icmp_echo_header))); | 378 | sizeof (struct ip_header) + |
401 | memcpy (&packet[off], | 379 | sizeof (struct icmp_echo_header))); |
402 | &icmp_ttl, | 380 | memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header)); |
403 | sizeof (struct icmp_ttl_exceeded_header)); | ||
404 | 381 | ||
405 | /* prepare for transmission */ | 382 | /* prepare for transmission */ |
406 | memset (&dst, 0, sizeof (dst)); | 383 | memset (&dst, 0, sizeof (dst)); |
@@ -409,21 +386,17 @@ send_icmp (const struct in_addr *my_ip, | |||
409 | dst.sin_len = sizeof (struct sockaddr_in); | 386 | dst.sin_len = sizeof (struct sockaddr_in); |
410 | #endif | 387 | #endif |
411 | dst.sin_addr = *other; | 388 | dst.sin_addr = *other; |
412 | err = sendto(rawsock, | 389 | err = sendto (rawsock, |
413 | packet, | 390 | packet, |
414 | sizeof (packet), 0, | 391 | sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst)); |
415 | (struct sockaddr*)&dst, | ||
416 | sizeof(dst)); | ||
417 | if (err < 0) | 392 | if (err < 0) |
418 | { | 393 | { |
419 | fprintf(stderr, | 394 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
420 | "sendto failed: %s\n", strerror(errno)); | 395 | } |
421 | } | ||
422 | else if (sizeof (packet) != (size_t) err) | 396 | else if (sizeof (packet) != (size_t) err) |
423 | { | 397 | { |
424 | fprintf(stderr, | 398 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
425 | "Error: partial send of ICMP message\n"); | 399 | } |
426 | } | ||
427 | } | 400 | } |
428 | 401 | ||
429 | 402 | ||
@@ -440,30 +413,24 @@ make_raw_socket () | |||
440 | 413 | ||
441 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); | 414 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); |
442 | if (-1 == ret) | 415 | if (-1 == ret) |
443 | { | 416 | { |
444 | fprintf (stderr, | 417 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); |
445 | "Error opening RAW socket: %s\n", | 418 | return -1; |
446 | strerror (errno)); | 419 | } |
447 | return -1; | 420 | if (0 != setsockopt (ret, SOL_SOCKET, SO_BROADCAST, |
448 | } | 421 | (char *) &one, sizeof (one))) |
449 | if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, | 422 | { |
450 | (char *)&one, sizeof(one))) | 423 | fprintf (stderr, "setsockopt failed: %s\n", strerror (errno)); |
451 | { | 424 | close (ret); |
452 | fprintf(stderr, | 425 | return -1; |
453 | "setsockopt failed: %s\n", | 426 | } |
454 | strerror (errno)); | 427 | if (0 != setsockopt (ret, IPPROTO_IP, IP_HDRINCL, |
455 | close (ret); | 428 | (char *) &one, sizeof (one))) |
456 | return -1; | 429 | { |
457 | } | 430 | fprintf (stderr, "setsockopt failed: %s\n", strerror (errno)); |
458 | if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL, | 431 | close (ret); |
459 | (char *)&one, sizeof(one))) | 432 | return -1; |
460 | { | 433 | } |
461 | fprintf(stderr, | ||
462 | "setsockopt failed: %s\n", | ||
463 | strerror (errno)); | ||
464 | close (ret); | ||
465 | return -1; | ||
466 | } | ||
467 | return ret; | 434 | return ret; |
468 | } | 435 | } |
469 | 436 | ||
@@ -477,49 +444,38 @@ main (int argc, char *const *argv) | |||
477 | unsigned int p; | 444 | unsigned int p; |
478 | 445 | ||
479 | if (4 != argc) | 446 | if (4 != argc) |
480 | { | 447 | { |
481 | fprintf (stderr, | 448 | fprintf (stderr, |
482 | "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); | 449 | "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); |
483 | return 1; | 450 | return 1; |
484 | } | 451 | } |
485 | if ( (1 != inet_pton (AF_INET, argv[1], &external)) || | 452 | if ((1 != inet_pton (AF_INET, argv[1], &external)) || |
486 | (1 != inet_pton (AF_INET, argv[2], &target)) ) | 453 | (1 != inet_pton (AF_INET, argv[2], &target))) |
487 | { | 454 | { |
488 | fprintf (stderr, | 455 | fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno)); |
489 | "Error parsing IPv4 address: %s\n", | 456 | return 1; |
490 | strerror (errno)); | 457 | } |
491 | return 1; | 458 | if ((1 != sscanf (argv[3], "%u", &p)) || (0 == p) || (0xFFFF < p)) |
492 | } | 459 | { |
493 | if ( (1 != sscanf (argv[3], "%u", &p) ) || | 460 | fprintf (stderr, "Error parsing port value `%s'\n", argv[3]); |
494 | (0 == p) || | 461 | return 1; |
495 | (0xFFFF < p) ) | 462 | } |
496 | { | ||
497 | fprintf (stderr, | ||
498 | "Error parsing port value `%s'\n", | ||
499 | argv[3]); | ||
500 | return 1; | ||
501 | } | ||
502 | port = (uint16_t) p; | 463 | port = (uint16_t) p; |
503 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 464 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) |
504 | { | 465 | { |
505 | fprintf (stderr, | 466 | fprintf (stderr, "Internal error converting dummy IP to binary.\n"); |
506 | "Internal error converting dummy IP to binary.\n"); | 467 | return 2; |
507 | return 2; | 468 | } |
508 | } | 469 | if (-1 == (rawsock = make_raw_socket ())) |
509 | if (-1 == (rawsock = make_raw_socket())) | ||
510 | return 2; | 470 | return 2; |
511 | uid = getuid (); | 471 | uid = getuid (); |
512 | if (0 != setresuid (uid, uid, uid)) | 472 | if (0 != setresuid (uid, uid, uid)) |
513 | { | 473 | { |
514 | fprintf (stderr, | 474 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); |
515 | "Failed to setresuid: %s\n", | 475 | /* not critical, continue anyway */ |
516 | strerror (errno)); | 476 | } |
517 | /* not critical, continue anyway */ | 477 | send_icmp (&external, &target); |
518 | } | 478 | send_icmp_udp (&external, &target); |
519 | send_icmp (&external, | ||
520 | &target); | ||
521 | send_icmp_udp (&external, | ||
522 | &target); | ||
523 | close (rawsock); | 479 | close (rawsock); |
524 | return 0; | 480 | return 0; |
525 | } | 481 | } |
diff --git a/src/nat/gnunet-helper-nat-server-windows.c b/src/nat/gnunet-helper-nat-server-windows.c index 7a607c62d..727a7be67 100644 --- a/src/nat/gnunet-helper-nat-server-windows.c +++ b/src/nat/gnunet-helper-nat-server-windows.c | |||
@@ -118,12 +118,12 @@ struct ip_header | |||
118 | /** | 118 | /** |
119 | * Time to live | 119 | * Time to live |
120 | */ | 120 | */ |
121 | uint8_t ttl; | 121 | uint8_t ttl; |
122 | 122 | ||
123 | /** | 123 | /** |
124 | * Protocol | 124 | * Protocol |
125 | */ | 125 | */ |
126 | uint8_t proto; | 126 | uint8_t proto; |
127 | 127 | ||
128 | /** | 128 | /** |
129 | * Header checksum | 129 | * Header checksum |
@@ -133,12 +133,12 @@ struct ip_header | |||
133 | /** | 133 | /** |
134 | * Source address | 134 | * Source address |
135 | */ | 135 | */ |
136 | uint32_t src_ip; | 136 | uint32_t src_ip; |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * Destination address | 139 | * Destination address |
140 | */ | 140 | */ |
141 | uint32_t dst_ip; | 141 | uint32_t dst_ip; |
142 | }; | 142 | }; |
143 | 143 | ||
144 | /** | 144 | /** |
@@ -211,17 +211,16 @@ static struct in_addr dummy; | |||
211 | * @return the CRC 16. | 211 | * @return the CRC 16. |
212 | */ | 212 | */ |
213 | static uint16_t | 213 | static uint16_t |
214 | calc_checksum(const uint16_t *data, | 214 | calc_checksum (const uint16_t * data, unsigned int bytes) |
215 | unsigned int bytes) | ||
216 | { | 215 | { |
217 | uint32_t sum; | 216 | uint32_t sum; |
218 | unsigned int i; | 217 | unsigned int i; |
219 | 218 | ||
220 | sum = 0; | 219 | sum = 0; |
221 | for (i=0;i<bytes/2;i++) | 220 | for (i = 0; i < bytes / 2; i++) |
222 | sum += data[i]; | 221 | sum += data[i]; |
223 | sum = (sum & 0xffff) + (sum >> 16); | 222 | sum = (sum & 0xffff) + (sum >> 16); |
224 | sum = htons(0xffff - sum); | 223 | sum = htons (0xffff - sum); |
225 | return sum; | 224 | return sum; |
226 | } | 225 | } |
227 | 226 | ||
@@ -235,19 +234,14 @@ calc_checksum(const uint16_t *data, | |||
235 | * @return 1 on success | 234 | * @return 1 on success |
236 | */ | 235 | */ |
237 | static int | 236 | static int |
238 | inet_pton (int af, | 237 | inet_pton (int af, const char *cp, struct in_addr *buf) |
239 | const char *cp, | ||
240 | struct in_addr *buf) | ||
241 | { | 238 | { |
242 | buf->s_addr = inet_addr(cp); | 239 | buf->s_addr = inet_addr (cp); |
243 | if (buf->s_addr == INADDR_NONE) | 240 | if (buf->s_addr == INADDR_NONE) |
244 | { | 241 | { |
245 | fprintf(stderr, | 242 | fprintf (stderr, "Error %d handling address %s", WSAGetLastError (), cp); |
246 | "Error %d handling address %s", | 243 | return 0; |
247 | WSAGetLastError(), | 244 | } |
248 | cp); | ||
249 | return 0; | ||
250 | } | ||
251 | return 1; | 245 | return 1; |
252 | } | 246 | } |
253 | 247 | ||
@@ -278,43 +272,35 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
278 | ip_pkt.checksum = 0; | 272 | ip_pkt.checksum = 0; |
279 | ip_pkt.src_ip = my_ip->s_addr; | 273 | ip_pkt.src_ip = my_ip->s_addr; |
280 | ip_pkt.dst_ip = dummy.s_addr; | 274 | ip_pkt.dst_ip = dummy.s_addr; |
281 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 275 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
282 | sizeof (struct ip_header))); | 276 | sizeof (struct ip_header))); |
283 | memcpy (&packet[off], | 277 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
284 | &ip_pkt, | ||
285 | sizeof (struct ip_header)); | ||
286 | off += sizeof (struct ip_header); | 278 | off += sizeof (struct ip_header); |
287 | 279 | ||
288 | icmp_echo.type = ICMP_ECHO; | 280 | icmp_echo.type = ICMP_ECHO; |
289 | icmp_echo.code = 0; | 281 | icmp_echo.code = 0; |
290 | icmp_echo.reserved = 0; | 282 | icmp_echo.reserved = 0; |
291 | icmp_echo.checksum = 0; | 283 | icmp_echo.checksum = 0; |
292 | icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, | 284 | icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo, |
293 | sizeof (struct icmp_echo_header))); | 285 | sizeof (struct icmp_echo_header))); |
294 | memcpy (&packet[off], | 286 | memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header)); |
295 | &icmp_echo, | ||
296 | sizeof (struct icmp_echo_header)); | ||
297 | off += sizeof (struct icmp_echo_header); | 287 | off += sizeof (struct icmp_echo_header); |
298 | 288 | ||
299 | memset (&dst, 0, sizeof (dst)); | 289 | memset (&dst, 0, sizeof (dst)); |
300 | dst.sin_family = AF_INET; | 290 | dst.sin_family = AF_INET; |
301 | dst.sin_addr = dummy; | 291 | dst.sin_addr = dummy; |
302 | err = sendto(rawsock, | 292 | err = sendto (rawsock, |
303 | packet, off, 0, | 293 | packet, off, 0, (struct sockaddr *) &dst, sizeof (dst)); |
304 | (struct sockaddr*)&dst, | ||
305 | sizeof(dst)); | ||
306 | if (err < 0) | 294 | if (err < 0) |
307 | { | 295 | { |
308 | #if VERBOSE | 296 | #if VERBOSE |
309 | fprintf(stderr, | 297 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
310 | "sendto failed: %s\n", strerror(errno)); | ||
311 | #endif | 298 | #endif |
312 | } | 299 | } |
313 | else if (err != off) | 300 | else if (err != off) |
314 | { | 301 | { |
315 | fprintf(stderr, | 302 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
316 | "Error: partial send of ICMP message\n"); | 303 | } |
317 | } | ||
318 | } | 304 | } |
319 | 305 | ||
320 | 306 | ||
@@ -331,22 +317,17 @@ send_udp () | |||
331 | dst.sin_family = AF_INET; | 317 | dst.sin_family = AF_INET; |
332 | dst.sin_addr = dummy; | 318 | dst.sin_addr = dummy; |
333 | dst.sin_port = htons (NAT_TRAV_PORT); | 319 | dst.sin_port = htons (NAT_TRAV_PORT); |
334 | err = sendto(udpsock, | 320 | err = sendto (udpsock, NULL, 0, 0, (struct sockaddr *) &dst, sizeof (dst)); |
335 | NULL, 0, 0, | ||
336 | (struct sockaddr*)&dst, | ||
337 | sizeof(dst)); | ||
338 | if (err < 0) | 321 | if (err < 0) |
339 | { | 322 | { |
340 | #if VERBOSE | 323 | #if VERBOSE |
341 | fprintf(stderr, | 324 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
342 | "sendto failed: %s\n", strerror(errno)); | ||
343 | #endif | 325 | #endif |
344 | } | 326 | } |
345 | else if (0 != err) | 327 | else if (0 != err) |
346 | { | 328 | { |
347 | fprintf(stderr, | 329 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
348 | "Error: partial send of ICMP message\n"); | 330 | } |
349 | } | ||
350 | } | 331 | } |
351 | 332 | ||
352 | 333 | ||
@@ -369,96 +350,74 @@ process_icmp_response () | |||
369 | 350 | ||
370 | have = read (icmpsock, buf, sizeof (buf)); | 351 | have = read (icmpsock, buf, sizeof (buf)); |
371 | if (have == -1) | 352 | if (have == -1) |
372 | { | 353 | { |
373 | fprintf (stderr, | 354 | fprintf (stderr, "Error reading raw socket: %s\n", strerror (errno)); |
374 | "Error reading raw socket: %s\n", | 355 | return; |
375 | strerror (errno)); | 356 | } |
376 | return; | ||
377 | } | ||
378 | #if VERBOSE | 357 | #if VERBOSE |
379 | fprintf (stderr, | 358 | fprintf (stderr, "Received message of %u bytes\n", (unsigned int) have); |
380 | "Received message of %u bytes\n", | ||
381 | (unsigned int) have); | ||
382 | #endif | 359 | #endif |
383 | if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct ip_header))) | 360 | if (have < |
384 | { | 361 | (ssize_t) (sizeof (struct ip_header) + |
385 | /* malformed */ | 362 | sizeof (struct icmp_ttl_exceeded_header) + |
386 | return; | 363 | sizeof (struct ip_header))) |
387 | } | 364 | { |
365 | /* malformed */ | ||
366 | return; | ||
367 | } | ||
388 | off = 0; | 368 | off = 0; |
389 | memcpy (&ip_pkt, | 369 | memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header)); |
390 | &buf[off], | ||
391 | sizeof (struct ip_header)); | ||
392 | off += sizeof (struct ip_header); | 370 | off += sizeof (struct ip_header); |
393 | memcpy(&source_ip, | 371 | memcpy (&source_ip, &ip_pkt.src_ip, sizeof (source_ip)); |
394 | &ip_pkt.src_ip, | 372 | memcpy (&icmp_ttl, &buf[off], sizeof (struct icmp_ttl_exceeded_header)); |
395 | sizeof (source_ip)); | ||
396 | memcpy (&icmp_ttl, | ||
397 | &buf[off], | ||
398 | sizeof (struct icmp_ttl_exceeded_header)); | ||
399 | off += sizeof (struct icmp_ttl_exceeded_header); | 373 | off += sizeof (struct icmp_ttl_exceeded_header); |
400 | if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) || | 374 | if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code)) |
401 | (0 != icmp_ttl.code) ) | 375 | { |
402 | { | 376 | /* different type than what we want */ |
403 | /* different type than what we want */ | 377 | return; |
404 | return; | 378 | } |
405 | } | ||
406 | /* skip 2nd IP header */ | 379 | /* skip 2nd IP header */ |
407 | memcpy (&ip_pkt, | 380 | memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header)); |
408 | &buf[off], | ||
409 | sizeof (struct ip_header)); | ||
410 | off += sizeof (struct ip_header); | 381 | off += sizeof (struct ip_header); |
411 | 382 | ||
412 | switch (ip_pkt.proto) | 383 | switch (ip_pkt.proto) |
384 | { | ||
385 | case IPPROTO_ICMP: | ||
386 | if (have != (sizeof (struct ip_header) * 2 + | ||
387 | sizeof (struct icmp_ttl_exceeded_header) + | ||
388 | sizeof (struct icmp_echo_header))) | ||
413 | { | 389 | { |
414 | case IPPROTO_ICMP: | 390 | /* malformed */ |
415 | if (have != (sizeof (struct ip_header) * 2 + | ||
416 | sizeof (struct icmp_ttl_exceeded_header) + | ||
417 | sizeof (struct icmp_echo_header)) ) | ||
418 | { | ||
419 | /* malformed */ | ||
420 | return; | ||
421 | } | ||
422 | /* grab ICMP ECHO content */ | ||
423 | memcpy (&icmp_echo, | ||
424 | &buf[off], | ||
425 | sizeof (struct icmp_echo_header)); | ||
426 | port = (uint16_t) ntohl (icmp_echo.reserved); | ||
427 | break; | ||
428 | case IPPROTO_UDP: | ||
429 | if (have != (sizeof (struct ip_header) * 2 + | ||
430 | sizeof (struct icmp_ttl_exceeded_header) + | ||
431 | sizeof (struct udp_header)) ) | ||
432 | { | ||
433 | /* malformed */ | ||
434 | return; | ||
435 | } | ||
436 | /* grab UDP content */ | ||
437 | memcpy (&udp_pkt, | ||
438 | &buf[off], | ||
439 | sizeof (struct udp_header)); | ||
440 | port = ntohs (udp_pkt.length); | ||
441 | break; | ||
442 | default: | ||
443 | /* different type than what we want */ | ||
444 | return; | 391 | return; |
445 | } | 392 | } |
446 | 393 | /* grab ICMP ECHO content */ | |
447 | ssize = sizeof(buf); | 394 | memcpy (&icmp_echo, &buf[off], sizeof (struct icmp_echo_header)); |
448 | WSAAddressToString((LPSOCKADDR)&source_ip, | 395 | port = (uint16_t) ntohl (icmp_echo.reserved); |
449 | sizeof(source_ip), | 396 | break; |
450 | NULL, | 397 | case IPPROTO_UDP: |
451 | buf, | 398 | if (have != (sizeof (struct ip_header) * 2 + |
452 | &ssize); | 399 | sizeof (struct icmp_ttl_exceeded_header) + |
400 | sizeof (struct udp_header))) | ||
401 | { | ||
402 | /* malformed */ | ||
403 | return; | ||
404 | } | ||
405 | /* grab UDP content */ | ||
406 | memcpy (&udp_pkt, &buf[off], sizeof (struct udp_header)); | ||
407 | port = ntohs (udp_pkt.length); | ||
408 | break; | ||
409 | default: | ||
410 | /* different type than what we want */ | ||
411 | return; | ||
412 | } | ||
413 | |||
414 | ssize = sizeof (buf); | ||
415 | WSAAddressToString ((LPSOCKADDR) & source_ip, | ||
416 | sizeof (source_ip), NULL, buf, &ssize); | ||
453 | if (port == 0) | 417 | if (port == 0) |
454 | fprintf (stdout, | 418 | fprintf (stdout, "%s\n", buf); |
455 | "%s\n", | ||
456 | buf); | ||
457 | else | 419 | else |
458 | fprintf (stdout, | 420 | fprintf (stdout, "%s:%u\n", buf, (unsigned int) port); |
459 | "%s:%u\n", | ||
460 | buf, | ||
461 | (unsigned int) port); | ||
462 | fflush (stdout); | 421 | fflush (stdout); |
463 | } | 422 | } |
464 | 423 | ||
@@ -475,12 +434,10 @@ make_icmp_socket () | |||
475 | 434 | ||
476 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | 435 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); |
477 | if (INVALID_SOCKET == ret) | 436 | if (INVALID_SOCKET == ret) |
478 | { | 437 | { |
479 | fprintf (stderr, | 438 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); |
480 | "Error opening RAW socket: %s\n", | 439 | return INVALID_SOCKET; |
481 | strerror (errno)); | 440 | } |
482 | return INVALID_SOCKET; | ||
483 | } | ||
484 | return ret; | 441 | return ret; |
485 | } | 442 | } |
486 | 443 | ||
@@ -494,39 +451,30 @@ static SOCKET | |||
494 | make_raw_socket () | 451 | make_raw_socket () |
495 | { | 452 | { |
496 | DWORD bOptVal = TRUE; | 453 | DWORD bOptVal = TRUE; |
497 | int bOptLen = sizeof(bOptVal); | 454 | int bOptLen = sizeof (bOptVal); |
498 | 455 | ||
499 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | 456 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); |
500 | if (INVALID_SOCKET == rawsock) | 457 | if (INVALID_SOCKET == rawsock) |
501 | { | 458 | { |
502 | fprintf (stderr, | 459 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); |
503 | "Error opening RAW socket: %s\n", | 460 | return INVALID_SOCKET; |
504 | strerror (errno)); | 461 | } |
505 | return INVALID_SOCKET; | 462 | |
506 | } | 463 | if (0 != setsockopt (rawsock, |
507 | 464 | SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal, bOptLen)) | |
508 | if (0 != setsockopt(rawsock, | 465 | { |
509 | SOL_SOCKET, | 466 | fprintf (stderr, |
510 | SO_BROADCAST, | 467 | "Error setting SO_BROADCAST to ON: %s\n", strerror (errno)); |
511 | (char*)&bOptVal, bOptLen)) | 468 | closesocket (rawsock); |
512 | { | 469 | return INVALID_SOCKET; |
513 | fprintf(stderr, | 470 | } |
514 | "Error setting SO_BROADCAST to ON: %s\n", | 471 | if (0 != setsockopt (rawsock, |
515 | strerror (errno)); | 472 | IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen)) |
516 | closesocket(rawsock); | 473 | { |
517 | return INVALID_SOCKET; | 474 | fprintf (stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror (errno)); |
518 | } | 475 | closesocket (rawsock); |
519 | if (0 != setsockopt(rawsock, | 476 | return INVALID_SOCKET; |
520 | IPPROTO_IP, | 477 | } |
521 | IP_HDRINCL, | ||
522 | (char*)&bOptVal, bOptLen)) | ||
523 | { | ||
524 | fprintf(stderr, | ||
525 | "Error setting IP_HDRINCL to ON: %s\n", | ||
526 | strerror (errno)); | ||
527 | closesocket(rawsock); | ||
528 | return INVALID_SOCKET; | ||
529 | } | ||
530 | return rawsock; | 478 | return rawsock; |
531 | } | 479 | } |
532 | 480 | ||
@@ -545,33 +493,27 @@ make_udp_socket (const struct in_addr *my_ip) | |||
545 | 493 | ||
546 | ret = socket (AF_INET, SOCK_DGRAM, 0); | 494 | ret = socket (AF_INET, SOCK_DGRAM, 0); |
547 | if (INVALID_SOCKET == ret) | 495 | if (INVALID_SOCKET == ret) |
548 | { | 496 | { |
549 | fprintf (stderr, | 497 | fprintf (stderr, "Error opening UDP socket: %s\n", strerror (errno)); |
550 | "Error opening UDP socket: %s\n", | 498 | return INVALID_SOCKET; |
551 | strerror (errno)); | 499 | } |
552 | return INVALID_SOCKET; | ||
553 | } | ||
554 | memset (&addr, 0, sizeof (addr)); | 500 | memset (&addr, 0, sizeof (addr)); |
555 | addr.sin_family = AF_INET; | 501 | addr.sin_family = AF_INET; |
556 | addr.sin_addr = *my_ip; | 502 | addr.sin_addr = *my_ip; |
557 | addr.sin_port = htons (NAT_TRAV_PORT); | 503 | addr.sin_port = htons (NAT_TRAV_PORT); |
558 | if (0 != bind (ret, | 504 | if (0 != bind (ret, (struct sockaddr *) &addr, sizeof (addr))) |
559 | (struct sockaddr *)&addr, | 505 | { |
560 | sizeof(addr))) | 506 | fprintf (stderr, |
561 | { | 507 | "Error binding UDP socket to port %u: %s\n", |
562 | fprintf (stderr, | 508 | NAT_TRAV_PORT, strerror (errno)); |
563 | "Error binding UDP socket to port %u: %s\n", | 509 | /* likely problematic, but not certain, try to continue */ |
564 | NAT_TRAV_PORT, | 510 | } |
565 | strerror (errno)); | ||
566 | /* likely problematic, but not certain, try to continue */ | ||
567 | } | ||
568 | return ret; | 511 | return ret; |
569 | } | 512 | } |
570 | 513 | ||
571 | 514 | ||
572 | int | 515 | int |
573 | main (int argc, | 516 | main (int argc, char *const *argv) |
574 | char *const *argv) | ||
575 | { | 517 | { |
576 | struct in_addr external; | 518 | struct in_addr external; |
577 | fd_set rs; | 519 | fd_set rs; |
@@ -581,70 +523,67 @@ main (int argc, | |||
581 | 523 | ||
582 | alt = 0; | 524 | alt = 0; |
583 | if (2 != argc) | 525 | if (2 != argc) |
584 | { | 526 | { |
585 | fprintf (stderr, | 527 | fprintf (stderr, |
586 | "This program must be started with our (internal NAT) IP as the only argument.\n"); | 528 | "This program must be started with our (internal NAT) IP as the only argument.\n"); |
587 | return 1; | 529 | return 1; |
588 | } | 530 | } |
589 | if (1 != inet_pton (AF_INET, argv[1], &external)) | 531 | if (1 != inet_pton (AF_INET, argv[1], &external)) |
590 | { | 532 | { |
591 | fprintf (stderr, | 533 | fprintf (stderr, |
592 | "Error parsing IPv4 address: %s, error %s\n", | 534 | "Error parsing IPv4 address: %s, error %s\n", |
593 | argv[1], strerror (errno)); | 535 | argv[1], strerror (errno)); |
594 | return 1; | 536 | return 1; |
595 | } | 537 | } |
596 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 538 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) |
597 | { | 539 | { |
598 | fprintf (stderr, | 540 | fprintf (stderr, "Internal error converting dummy IP to binary.\n"); |
599 | "Internal error converting dummy IP to binary.\n"); | 541 | return 2; |
600 | return 2; | 542 | } |
601 | } | ||
602 | if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0) | 543 | if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0) |
603 | { | 544 | { |
604 | fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); | 545 | fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); |
605 | return 2; | 546 | return 2; |
606 | } | 547 | } |
607 | if (INVALID_SOCKET == (icmpsock = make_icmp_socket())) | 548 | if (INVALID_SOCKET == (icmpsock = make_icmp_socket ())) |
608 | { | 549 | { |
609 | return 3; | 550 | return 3; |
610 | } | 551 | } |
611 | if (INVALID_SOCKET == (make_raw_socket())) | 552 | if (INVALID_SOCKET == (make_raw_socket ())) |
612 | { | 553 | { |
613 | closesocket (icmpsock); | 554 | closesocket (icmpsock); |
614 | return 3; | 555 | return 3; |
615 | } | 556 | } |
616 | if (INVALID_SOCKET == (udpsock = make_udp_socket(&external))) | 557 | if (INVALID_SOCKET == (udpsock = make_udp_socket (&external))) |
617 | { | 558 | { |
618 | closesocket (icmpsock); | 559 | closesocket (icmpsock); |
619 | closesocket (rawsock); | 560 | closesocket (rawsock); |
620 | return 3; | 561 | return 3; |
621 | } | 562 | } |
622 | while (1) | 563 | while (1) |
564 | { | ||
565 | FD_ZERO (&rs); | ||
566 | FD_SET (icmpsock, &rs); | ||
567 | tv.tv_sec = 0; | ||
568 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | ||
569 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
623 | { | 570 | { |
624 | FD_ZERO (&rs); | 571 | if (errno == EINTR) |
625 | FD_SET (icmpsock, &rs); | 572 | continue; |
626 | tv.tv_sec = 0; | 573 | fprintf (stderr, "select failed: %s\n", strerror (errno)); |
627 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | 574 | break; |
628 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
629 | { | ||
630 | if (errno == EINTR) | ||
631 | continue; | ||
632 | fprintf (stderr, | ||
633 | "select failed: %s\n", | ||
634 | strerror (errno)); | ||
635 | break; | ||
636 | } | ||
637 | if (FD_ISSET (icmpsock, &rs)) | ||
638 | process_icmp_response (); | ||
639 | if (0 == (++alt % 2)) | ||
640 | send_icmp_echo (&external); | ||
641 | else | ||
642 | send_udp (); | ||
643 | } | 575 | } |
576 | if (FD_ISSET (icmpsock, &rs)) | ||
577 | process_icmp_response (); | ||
578 | if (0 == (++alt % 2)) | ||
579 | send_icmp_echo (&external); | ||
580 | else | ||
581 | send_udp (); | ||
582 | } | ||
644 | /* select failed (internal error or OS out of resources) */ | 583 | /* select failed (internal error or OS out of resources) */ |
645 | closesocket(icmpsock); | 584 | closesocket (icmpsock); |
646 | closesocket(rawsock); | 585 | closesocket (rawsock); |
647 | closesocket(udpsock); | 586 | closesocket (udpsock); |
648 | WSACleanup (); | 587 | WSACleanup (); |
649 | return 4; | 588 | return 4; |
650 | } | 589 | } |
diff --git a/src/nat/gnunet-helper-nat-server.c b/src/nat/gnunet-helper-nat-server.c index 945c98735..636ae6003 100644 --- a/src/nat/gnunet-helper-nat-server.c +++ b/src/nat/gnunet-helper-nat-server.c | |||
@@ -212,17 +212,16 @@ static struct in_addr dummy; | |||
212 | * @return the CRC 16. | 212 | * @return the CRC 16. |
213 | */ | 213 | */ |
214 | static uint16_t | 214 | static uint16_t |
215 | calc_checksum(const uint16_t *data, | 215 | calc_checksum (const uint16_t * data, unsigned int bytes) |
216 | unsigned int bytes) | ||
217 | { | 216 | { |
218 | uint32_t sum; | 217 | uint32_t sum; |
219 | unsigned int i; | 218 | unsigned int i; |
220 | 219 | ||
221 | sum = 0; | 220 | sum = 0; |
222 | for (i=0;i<bytes/2;i++) | 221 | for (i = 0; i < bytes / 2; i++) |
223 | sum += data[i]; | 222 | sum += data[i]; |
224 | sum = (sum & 0xffff) + (sum >> 16); | 223 | sum = (sum & 0xffff) + (sum >> 16); |
225 | sum = htons(0xffff - sum); | 224 | sum = htons (0xffff - sum); |
226 | return sum; | 225 | return sum; |
227 | } | 226 | } |
228 | 227 | ||
@@ -253,22 +252,18 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
253 | ip_pkt.checksum = 0; | 252 | ip_pkt.checksum = 0; |
254 | ip_pkt.src_ip = my_ip->s_addr; | 253 | ip_pkt.src_ip = my_ip->s_addr; |
255 | ip_pkt.dst_ip = dummy.s_addr; | 254 | ip_pkt.dst_ip = dummy.s_addr; |
256 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 255 | ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt, |
257 | sizeof (struct ip_header))); | 256 | sizeof (struct ip_header))); |
258 | memcpy (&packet[off], | 257 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); |
259 | &ip_pkt, | ||
260 | sizeof (struct ip_header)); | ||
261 | off += sizeof (struct ip_header); | 258 | off += sizeof (struct ip_header); |
262 | 259 | ||
263 | icmp_echo.type = ICMP_ECHO; | 260 | icmp_echo.type = ICMP_ECHO; |
264 | icmp_echo.code = 0; | 261 | icmp_echo.code = 0; |
265 | icmp_echo.checksum = 0; | 262 | icmp_echo.checksum = 0; |
266 | icmp_echo.reserved = 0; | 263 | icmp_echo.reserved = 0; |
267 | icmp_echo.checksum = htons(calc_checksum((uint16_t*)&icmp_echo, | 264 | icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo, |
268 | sizeof (struct icmp_echo_header))); | 265 | sizeof (struct icmp_echo_header))); |
269 | memcpy (&packet[off], | 266 | memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header)); |
270 | &icmp_echo, | ||
271 | sizeof (struct icmp_echo_header)); | ||
272 | off += sizeof (struct icmp_echo_header); | 267 | off += sizeof (struct icmp_echo_header); |
273 | 268 | ||
274 | memset (&dst, 0, sizeof (dst)); | 269 | memset (&dst, 0, sizeof (dst)); |
@@ -277,22 +272,18 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
277 | dst.sin_len = sizeof (struct sockaddr_in); | 272 | dst.sin_len = sizeof (struct sockaddr_in); |
278 | #endif | 273 | #endif |
279 | dst.sin_addr = dummy; | 274 | dst.sin_addr = dummy; |
280 | err = sendto(rawsock, | 275 | err = sendto (rawsock, |
281 | packet, off, 0, | 276 | packet, off, 0, (struct sockaddr *) &dst, sizeof (dst)); |
282 | (struct sockaddr*)&dst, | ||
283 | sizeof(dst)); | ||
284 | if (err < 0) | 277 | if (err < 0) |
285 | { | 278 | { |
286 | #if VERBOSE | 279 | #if VERBOSE |
287 | fprintf(stderr, | 280 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
288 | "sendto failed: %s\n", strerror(errno)); | ||
289 | #endif | 281 | #endif |
290 | } | 282 | } |
291 | else if (sizeof (packet) != err) | 283 | else if (sizeof (packet) != err) |
292 | { | 284 | { |
293 | fprintf(stderr, | 285 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
294 | "Error: partial send of ICMP message\n"); | 286 | } |
295 | } | ||
296 | } | 287 | } |
297 | 288 | ||
298 | 289 | ||
@@ -312,22 +303,17 @@ send_udp () | |||
312 | #endif | 303 | #endif |
313 | dst.sin_addr = dummy; | 304 | dst.sin_addr = dummy; |
314 | dst.sin_port = htons (NAT_TRAV_PORT); | 305 | dst.sin_port = htons (NAT_TRAV_PORT); |
315 | err = sendto(udpsock, | 306 | err = sendto (udpsock, NULL, 0, 0, (struct sockaddr *) &dst, sizeof (dst)); |
316 | NULL, 0, 0, | ||
317 | (struct sockaddr*)&dst, | ||
318 | sizeof(dst)); | ||
319 | if (err < 0) | 307 | if (err < 0) |
320 | { | 308 | { |
321 | #if VERBOSE | 309 | #if VERBOSE |
322 | fprintf(stderr, | 310 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); |
323 | "sendto failed: %s\n", strerror(errno)); | ||
324 | #endif | 311 | #endif |
325 | } | 312 | } |
326 | else if (0 != err) | 313 | else if (0 != err) |
327 | { | 314 | { |
328 | fprintf(stderr, | 315 | fprintf (stderr, "Error: partial send of ICMP message\n"); |
329 | "Error: partial send of ICMP message\n"); | 316 | } |
330 | } | ||
331 | } | 317 | } |
332 | 318 | ||
333 | 319 | ||
@@ -349,96 +335,75 @@ process_icmp_response () | |||
349 | 335 | ||
350 | have = read (icmpsock, buf, sizeof (buf)); | 336 | have = read (icmpsock, buf, sizeof (buf)); |
351 | if (-1 == have) | 337 | if (-1 == have) |
352 | { | 338 | { |
353 | fprintf (stderr, | 339 | fprintf (stderr, "Error reading raw socket: %s\n", strerror (errno)); |
354 | "Error reading raw socket: %s\n", | 340 | return; |
355 | strerror (errno)); | 341 | } |
356 | return; | ||
357 | } | ||
358 | #if VERBOSE | 342 | #if VERBOSE |
359 | fprintf (stderr, | 343 | fprintf (stderr, "Received message of %u bytes\n", (unsigned int) have); |
360 | "Received message of %u bytes\n", | ||
361 | (unsigned int) have); | ||
362 | #endif | 344 | #endif |
363 | if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct ip_header))) | 345 | if (have < |
364 | { | 346 | (ssize_t) (sizeof (struct ip_header) + |
365 | /* malformed */ | 347 | sizeof (struct icmp_ttl_exceeded_header) + |
366 | return; | 348 | sizeof (struct ip_header))) |
367 | } | 349 | { |
350 | /* malformed */ | ||
351 | return; | ||
352 | } | ||
368 | off = 0; | 353 | off = 0; |
369 | memcpy (&ip_pkt, | 354 | memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header)); |
370 | &buf[off], | ||
371 | sizeof (struct ip_header)); | ||
372 | off += sizeof (struct ip_header); | 355 | off += sizeof (struct ip_header); |
373 | memcpy(&source_ip, | 356 | memcpy (&source_ip, &ip_pkt.src_ip, sizeof (source_ip)); |
374 | &ip_pkt.src_ip, | 357 | memcpy (&icmp_ttl, &buf[off], sizeof (struct icmp_ttl_exceeded_header)); |
375 | sizeof (source_ip)); | ||
376 | memcpy (&icmp_ttl, | ||
377 | &buf[off], | ||
378 | sizeof (struct icmp_ttl_exceeded_header)); | ||
379 | off += sizeof (struct icmp_ttl_exceeded_header); | 358 | off += sizeof (struct icmp_ttl_exceeded_header); |
380 | if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) || | 359 | if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code)) |
381 | (0 != icmp_ttl.code) ) | 360 | { |
382 | { | 361 | /* different type than what we want */ |
383 | /* different type than what we want */ | 362 | return; |
384 | return; | 363 | } |
385 | } | ||
386 | /* skip 2nd IP header */ | 364 | /* skip 2nd IP header */ |
387 | memcpy (&ip_pkt, | 365 | memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header)); |
388 | &buf[off], | ||
389 | sizeof (struct ip_header)); | ||
390 | off += sizeof (struct ip_header); | 366 | off += sizeof (struct ip_header); |
391 | 367 | ||
392 | switch (ip_pkt.proto) | 368 | switch (ip_pkt.proto) |
369 | { | ||
370 | case IPPROTO_ICMP: | ||
371 | if (have != (sizeof (struct ip_header) * 2 + | ||
372 | sizeof (struct icmp_ttl_exceeded_header) + | ||
373 | sizeof (struct icmp_echo_header))) | ||
393 | { | 374 | { |
394 | case IPPROTO_ICMP: | 375 | /* malformed */ |
395 | if (have != (sizeof (struct ip_header) * 2 + | ||
396 | sizeof (struct icmp_ttl_exceeded_header) + | ||
397 | sizeof (struct icmp_echo_header)) ) | ||
398 | { | ||
399 | /* malformed */ | ||
400 | return; | ||
401 | } | ||
402 | /* grab ICMP ECHO content */ | ||
403 | memcpy (&icmp_echo, | ||
404 | &buf[off], | ||
405 | sizeof (struct icmp_echo_header)); | ||
406 | port = (uint16_t) ntohl (icmp_echo.reserved); | ||
407 | break; | ||
408 | case IPPROTO_UDP: | ||
409 | if (have != (sizeof (struct ip_header) * 2 + | ||
410 | sizeof (struct icmp_ttl_exceeded_header) + | ||
411 | sizeof (struct udp_header)) ) | ||
412 | { | ||
413 | /* malformed */ | ||
414 | return; | ||
415 | } | ||
416 | /* grab UDP content */ | ||
417 | memcpy (&udp_pkt, | ||
418 | &buf[off], | ||
419 | sizeof (struct udp_header)); | ||
420 | port = ntohs (udp_pkt.length); | ||
421 | break; | ||
422 | default: | ||
423 | /* different type than what we want */ | ||
424 | return; | 376 | return; |
425 | } | 377 | } |
378 | /* grab ICMP ECHO content */ | ||
379 | memcpy (&icmp_echo, &buf[off], sizeof (struct icmp_echo_header)); | ||
380 | port = (uint16_t) ntohl (icmp_echo.reserved); | ||
381 | break; | ||
382 | case IPPROTO_UDP: | ||
383 | if (have != (sizeof (struct ip_header) * 2 + | ||
384 | sizeof (struct icmp_ttl_exceeded_header) + | ||
385 | sizeof (struct udp_header))) | ||
386 | { | ||
387 | /* malformed */ | ||
388 | return; | ||
389 | } | ||
390 | /* grab UDP content */ | ||
391 | memcpy (&udp_pkt, &buf[off], sizeof (struct udp_header)); | ||
392 | port = ntohs (udp_pkt.length); | ||
393 | break; | ||
394 | default: | ||
395 | /* different type than what we want */ | ||
396 | return; | ||
397 | } | ||
426 | 398 | ||
427 | if (port == 0) | 399 | if (port == 0) |
428 | fprintf (stdout, | 400 | fprintf (stdout, |
429 | "%s\n", | 401 | "%s\n", inet_ntop (AF_INET, &source_ip, buf, sizeof (buf))); |
430 | inet_ntop (AF_INET, | ||
431 | &source_ip, | ||
432 | buf, | ||
433 | sizeof (buf))); | ||
434 | else | 402 | else |
435 | fprintf (stdout, | 403 | fprintf (stdout, |
436 | "%s:%u\n", | 404 | "%s:%u\n", |
437 | inet_ntop (AF_INET, | 405 | inet_ntop (AF_INET, |
438 | &source_ip, | 406 | &source_ip, buf, sizeof (buf)), (unsigned int) port); |
439 | buf, | ||
440 | sizeof (buf)), | ||
441 | (unsigned int) port); | ||
442 | fflush (stdout); | 407 | fflush (stdout); |
443 | } | 408 | } |
444 | 409 | ||
@@ -455,21 +420,18 @@ make_icmp_socket () | |||
455 | 420 | ||
456 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | 421 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); |
457 | if (-1 == ret) | 422 | if (-1 == ret) |
458 | { | 423 | { |
459 | fprintf (stderr, | 424 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); |
460 | "Error opening RAW socket: %s\n", | 425 | return -1; |
461 | strerror (errno)); | 426 | } |
462 | return -1; | ||
463 | } | ||
464 | if (ret >= FD_SETSIZE) | 427 | if (ret >= FD_SETSIZE) |
465 | { | 428 | { |
466 | fprintf (stderr, | 429 | fprintf (stderr, |
467 | "Socket number too large (%d > %u)\n", | 430 | "Socket number too large (%d > %u)\n", |
468 | ret, | 431 | ret, (unsigned int) FD_SETSIZE); |
469 | (unsigned int) FD_SETSIZE); | 432 | close (ret); |
470 | close (ret); | 433 | return -1; |
471 | return -1; | 434 | } |
472 | } | ||
473 | return ret; | 435 | return ret; |
474 | } | 436 | } |
475 | 437 | ||
@@ -487,34 +449,24 @@ make_raw_socket () | |||
487 | 449 | ||
488 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); | 450 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); |
489 | if (-1 == ret) | 451 | if (-1 == ret) |
490 | { | 452 | { |
491 | fprintf (stderr, | 453 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); |
492 | "Error opening RAW socket: %s\n", | 454 | return -1; |
493 | strerror (errno)); | 455 | } |
494 | return -1; | 456 | if (-1 == setsockopt (ret, |
495 | } | 457 | SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof (one))) |
496 | if (-1 == setsockopt(ret, | 458 | { |
497 | SOL_SOCKET, | 459 | fprintf (stderr, "setsockopt failed: %s\n", strerror (errno)); |
498 | SO_BROADCAST, | 460 | close (ret); |
499 | (char *)&one, sizeof(one))) | 461 | return -1; |
500 | { | 462 | } |
501 | fprintf(stderr, | 463 | if (-1 == setsockopt (ret, |
502 | "setsockopt failed: %s\n", | 464 | IPPROTO_IP, IP_HDRINCL, (char *) &one, sizeof (one))) |
503 | strerror (errno)); | 465 | { |
504 | close (ret); | 466 | fprintf (stderr, "setsockopt failed: %s\n", strerror (errno)); |
505 | return -1; | 467 | close (ret); |
506 | } | 468 | return -1; |
507 | if (-1 == setsockopt(ret, | 469 | } |
508 | IPPROTO_IP, | ||
509 | IP_HDRINCL, | ||
510 | (char *)&one, sizeof(one))) | ||
511 | { | ||
512 | fprintf(stderr, | ||
513 | "setsockopt failed: %s\n", | ||
514 | strerror (errno)); | ||
515 | close (ret); | ||
516 | return -1; | ||
517 | } | ||
518 | return ret; | 470 | return ret; |
519 | } | 471 | } |
520 | 472 | ||
@@ -533,15 +485,11 @@ make_udp_socket (const struct in_addr *my_ip) | |||
533 | 485 | ||
534 | ret = socket (AF_INET, SOCK_DGRAM, 0); | 486 | ret = socket (AF_INET, SOCK_DGRAM, 0); |
535 | if (-1 == ret) | 487 | if (-1 == ret) |
536 | { | 488 | { |
537 | fprintf (stderr, | 489 | fprintf (stderr, "Error opening UDP socket: %s\n", strerror (errno)); |
538 | "Error opening UDP socket: %s\n", | 490 | return -1; |
539 | strerror (errno)); | 491 | } |
540 | return -1; | 492 | memset (&addr, 0, sizeof (addr)); |
541 | } | ||
542 | memset (&addr, | ||
543 | 0, | ||
544 | sizeof (addr)); | ||
545 | addr.sin_family = AF_INET; | 493 | addr.sin_family = AF_INET; |
546 | #if HAVE_SOCKADDR_IN_SIN_LEN | 494 | #if HAVE_SOCKADDR_IN_SIN_LEN |
547 | addr.sin_len = sizeof (struct sockaddr_in); | 495 | addr.sin_len = sizeof (struct sockaddr_in); |
@@ -549,23 +497,19 @@ make_udp_socket (const struct in_addr *my_ip) | |||
549 | addr.sin_addr = *my_ip; | 497 | addr.sin_addr = *my_ip; |
550 | addr.sin_port = htons (NAT_TRAV_PORT); | 498 | addr.sin_port = htons (NAT_TRAV_PORT); |
551 | 499 | ||
552 | if (0 != bind (ret, | 500 | if (0 != bind (ret, &addr, sizeof (addr))) |
553 | &addr, | 501 | { |
554 | sizeof(addr))) | 502 | fprintf (stderr, |
555 | { | 503 | "Error binding UDP socket to port %u: %s\n", |
556 | fprintf (stderr, | 504 | NAT_TRAV_PORT, strerror (errno)); |
557 | "Error binding UDP socket to port %u: %s\n", | 505 | /* likely problematic, but not certain, try to continue */ |
558 | NAT_TRAV_PORT, | 506 | } |
559 | strerror (errno)); | ||
560 | /* likely problematic, but not certain, try to continue */ | ||
561 | } | ||
562 | return ret; | 507 | return ret; |
563 | } | 508 | } |
564 | 509 | ||
565 | 510 | ||
566 | int | 511 | int |
567 | main (int argc, | 512 | main (int argc, char *const *argv) |
568 | char *const *argv) | ||
569 | { | 513 | { |
570 | struct in_addr external; | 514 | struct in_addr external; |
571 | fd_set rs; | 515 | fd_set rs; |
@@ -574,72 +518,65 @@ main (int argc, | |||
574 | unsigned int alt; | 518 | unsigned int alt; |
575 | 519 | ||
576 | if (2 != argc) | 520 | if (2 != argc) |
577 | { | 521 | { |
578 | fprintf (stderr, | 522 | fprintf (stderr, |
579 | "This program must be started with our (internal NAT) IP as the only argument.\n"); | 523 | "This program must be started with our (internal NAT) IP as the only argument.\n"); |
580 | return 1; | 524 | return 1; |
581 | } | 525 | } |
582 | if (1 != inet_pton (AF_INET, argv[1], &external)) | 526 | if (1 != inet_pton (AF_INET, argv[1], &external)) |
583 | { | 527 | { |
584 | fprintf (stderr, | 528 | fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno)); |
585 | "Error parsing IPv4 address: %s\n", | 529 | return 1; |
586 | strerror (errno)); | 530 | } |
587 | return 1; | ||
588 | } | ||
589 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 531 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) |
590 | { | 532 | { |
591 | fprintf (stderr, | 533 | fprintf (stderr, "Internal error converting dummy IP to binary.\n"); |
592 | "Internal error converting dummy IP to binary.\n"); | 534 | return 2; |
593 | return 2; | 535 | } |
594 | } | 536 | if (-1 == (icmpsock = make_icmp_socket ())) |
595 | if (-1 == (icmpsock = make_icmp_socket())) | 537 | { |
596 | { | 538 | return 3; |
597 | return 3; | 539 | } |
598 | } | 540 | if (-1 == (rawsock = make_raw_socket ())) |
599 | if (-1 == (rawsock = make_raw_socket())) | 541 | { |
600 | { | 542 | close (icmpsock); |
601 | close (icmpsock); | 543 | return 3; |
602 | return 3; | 544 | } |
603 | } | ||
604 | uid = getuid (); | 545 | uid = getuid (); |
605 | if (0 != setresuid (uid, uid, uid)) | 546 | if (0 != setresuid (uid, uid, uid)) |
606 | { | 547 | { |
607 | fprintf (stderr, | 548 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); |
608 | "Failed to setresuid: %s\n", | 549 | /* not critical, continue anyway */ |
609 | strerror (errno)); | 550 | } |
610 | /* not critical, continue anyway */ | 551 | if (-1 == (udpsock = make_udp_socket (&external))) |
611 | } | 552 | { |
612 | if (-1 == (udpsock = make_udp_socket(&external))) | 553 | close (icmpsock); |
613 | { | 554 | close (rawsock); |
614 | close (icmpsock); | 555 | return 3; |
615 | close (rawsock); | 556 | } |
616 | return 3; | ||
617 | } | ||
618 | alt = 0; | 557 | alt = 0; |
619 | while (1) | 558 | while (1) |
559 | { | ||
560 | FD_ZERO (&rs); | ||
561 | FD_SET (icmpsock, &rs); | ||
562 | tv.tv_sec = 0; | ||
563 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | ||
564 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
620 | { | 565 | { |
621 | FD_ZERO (&rs); | 566 | if (errno == EINTR) |
622 | FD_SET (icmpsock, &rs); | 567 | continue; |
623 | tv.tv_sec = 0; | 568 | fprintf (stderr, "select failed: %s\n", strerror (errno)); |
624 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | 569 | break; |
625 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
626 | { | ||
627 | if (errno == EINTR) | ||
628 | continue; | ||
629 | fprintf (stderr, | ||
630 | "select failed: %s\n", | ||
631 | strerror (errno)); | ||
632 | break; | ||
633 | } | ||
634 | if (1 == getppid()) /* Check the parent process id, if 1 the parent has died, so we should die too */ | ||
635 | break; | ||
636 | if (FD_ISSET (icmpsock, &rs)) | ||
637 | process_icmp_response (); | ||
638 | if (0 == (++alt % 2)) | ||
639 | send_icmp_echo (&external); | ||
640 | else | ||
641 | send_udp (); | ||
642 | } | 570 | } |
571 | if (1 == getppid ()) /* Check the parent process id, if 1 the parent has died, so we should die too */ | ||
572 | break; | ||
573 | if (FD_ISSET (icmpsock, &rs)) | ||
574 | process_icmp_response (); | ||
575 | if (0 == (++alt % 2)) | ||
576 | send_icmp_echo (&external); | ||
577 | else | ||
578 | send_udp (); | ||
579 | } | ||
643 | /* select failed (internal error or OS out of resources) */ | 580 | /* select failed (internal error or OS out of resources) */ |
644 | close (icmpsock); | 581 | close (icmpsock); |
645 | close (rawsock); | 582 | close (rawsock); |
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 | } |
diff --git a/src/nat/nat.c b/src/nat/nat.c index a4efb7084..ed72be9f8 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c | |||
@@ -62,40 +62,39 @@ | |||
62 | * we reevaluate the source. | 62 | * we reevaluate the source. |
63 | */ | 63 | */ |
64 | enum LocalAddressSource | 64 | enum LocalAddressSource |
65 | { | 65 | { |
66 | /** | 66 | /** |
67 | * Address was obtained by DNS resolution of the external hostname | 67 | * Address was obtained by DNS resolution of the external hostname |
68 | * given in the configuration (i.e. hole-punched DynDNS setup). | 68 | * given in the configuration (i.e. hole-punched DynDNS setup). |
69 | */ | 69 | */ |
70 | LAL_EXTERNAL_IP, | 70 | LAL_EXTERNAL_IP, |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * Address was obtained by looking up our own hostname in DNS. | 73 | * Address was obtained by looking up our own hostname in DNS. |
74 | */ | 74 | */ |
75 | LAL_HOSTNAME_DNS, | 75 | LAL_HOSTNAME_DNS, |
76 | 76 | ||
77 | /** | 77 | /** |
78 | * Address was obtained by scanning our hosts's network interfaces | 78 | * Address was obtained by scanning our hosts's network interfaces |
79 | * and taking their address (no DNS involved). | 79 | * and taking their address (no DNS involved). |
80 | */ | 80 | */ |
81 | LAL_INTERFACE_ADDRESS, | 81 | LAL_INTERFACE_ADDRESS, |
82 | 82 | ||
83 | /** | 83 | /** |
84 | * Addresses we were explicitly bound to. | 84 | * Addresses we were explicitly bound to. |
85 | */ | 85 | */ |
86 | LAL_BINDTO_ADDRESS, | 86 | LAL_BINDTO_ADDRESS, |
87 | 87 | ||
88 | /** | 88 | /** |
89 | * Addresses from UPnP or PMP | 89 | * Addresses from UPnP or PMP |
90 | */ | 90 | */ |
91 | LAL_UPNP, | 91 | LAL_UPNP, |
92 | 92 | ||
93 | /** | 93 | /** |
94 | * End of the list. | 94 | * End of the list. |
95 | */ | 95 | */ |
96 | LAL_END | 96 | LAL_END |
97 | 97 | }; | |
98 | }; | ||
99 | 98 | ||
100 | 99 | ||
101 | /** | 100 | /** |
@@ -114,7 +113,7 @@ struct LocalAddressList | |||
114 | 113 | ||
115 | /** | 114 | /** |
116 | * Previous entry. | 115 | * Previous entry. |
117 | */ | 116 | */ |
118 | struct LocalAddressList *prev; | 117 | struct LocalAddressList *prev; |
119 | 118 | ||
120 | /** | 119 | /** |
@@ -168,7 +167,7 @@ struct GNUNET_NAT_Handle | |||
168 | * Configuration to use. | 167 | * Configuration to use. |
169 | */ | 168 | */ |
170 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 169 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
171 | 170 | ||
172 | /** | 171 | /** |
173 | * Function to call when we learn about a new address. | 172 | * Function to call when we learn about a new address. |
174 | */ | 173 | */ |
@@ -345,7 +344,7 @@ struct GNUNET_NAT_Handle | |||
345 | 344 | ||
346 | /** | 345 | /** |
347 | * Is this TCP or UDP? | 346 | * Is this TCP or UDP? |
348 | */ | 347 | */ |
349 | int is_tcp; | 348 | int is_tcp; |
350 | 349 | ||
351 | /** | 350 | /** |
@@ -362,8 +361,7 @@ struct GNUNET_NAT_Handle | |||
362 | * | 361 | * |
363 | * @param h handle to NAT | 362 | * @param h handle to NAT |
364 | */ | 363 | */ |
365 | static void | 364 | static void start_gnunet_nat_server (struct GNUNET_NAT_Handle *h); |
366 | start_gnunet_nat_server (struct GNUNET_NAT_Handle *h); | ||
367 | 365 | ||
368 | 366 | ||
369 | /** | 367 | /** |
@@ -375,27 +373,24 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h); | |||
375 | */ | 373 | */ |
376 | static void | 374 | static void |
377 | remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h, | 375 | remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h, |
378 | enum LocalAddressSource src) | 376 | enum LocalAddressSource src) |
379 | { | 377 | { |
380 | struct LocalAddressList *pos; | 378 | struct LocalAddressList *pos; |
381 | struct LocalAddressList *next; | 379 | struct LocalAddressList *next; |
382 | 380 | ||
383 | next = h->lal_head; | 381 | next = h->lal_head; |
384 | while (NULL != (pos = next)) | 382 | while (NULL != (pos = next)) |
385 | { | 383 | { |
386 | next = pos->next; | 384 | next = pos->next; |
387 | if (pos->source != src) | 385 | if (pos->source != src) |
388 | continue; | 386 | continue; |
389 | GNUNET_CONTAINER_DLL_remove (h->lal_head, | 387 | GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos); |
390 | h->lal_tail, | 388 | if (NULL != h->address_callback) |
391 | pos); | 389 | h->address_callback (h->callback_cls, |
392 | if (NULL != h->address_callback) | 390 | GNUNET_NO, |
393 | h->address_callback (h->callback_cls, | 391 | (const struct sockaddr *) &pos[1], pos->addrlen); |
394 | GNUNET_NO, | 392 | GNUNET_free (pos); |
395 | (const struct sockaddr* ) &pos[1], | 393 | } |
396 | pos->addrlen); | ||
397 | GNUNET_free (pos); | ||
398 | } | ||
399 | } | 394 | } |
400 | 395 | ||
401 | 396 | ||
@@ -410,9 +405,8 @@ remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h, | |||
410 | */ | 405 | */ |
411 | static void | 406 | static void |
412 | add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, | 407 | add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, |
413 | enum LocalAddressSource src, | 408 | enum LocalAddressSource src, |
414 | const struct sockaddr *arg, | 409 | const struct sockaddr *arg, socklen_t arg_size) |
415 | socklen_t arg_size) | ||
416 | { | 410 | { |
417 | struct LocalAddressList *lal; | 411 | struct LocalAddressList *lal; |
418 | 412 | ||
@@ -420,21 +414,15 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, | |||
420 | memcpy (&lal[1], arg, arg_size); | 414 | memcpy (&lal[1], arg, arg_size); |
421 | lal->addrlen = arg_size; | 415 | lal->addrlen = arg_size; |
422 | lal->source = src; | 416 | lal->source = src; |
423 | GNUNET_CONTAINER_DLL_insert (h->lal_head, | 417 | GNUNET_CONTAINER_DLL_insert (h->lal_head, h->lal_tail, lal); |
424 | h->lal_tail, | ||
425 | lal); | ||
426 | #if DEBUG_NAT | 418 | #if DEBUG_NAT |
427 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 419 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
428 | "nat", | 420 | "nat", |
429 | "Adding address `%s' from source %d\n", | 421 | "Adding address `%s' from source %d\n", |
430 | GNUNET_a2s (arg, arg_size), | 422 | GNUNET_a2s (arg, arg_size), src); |
431 | src); | ||
432 | #endif | 423 | #endif |
433 | if (NULL != h->address_callback) | 424 | if (NULL != h->address_callback) |
434 | h->address_callback (h->callback_cls, | 425 | h->address_callback (h->callback_cls, GNUNET_YES, arg, arg_size); |
435 | GNUNET_YES, | ||
436 | arg, | ||
437 | arg_size); | ||
438 | } | 426 | } |
439 | 427 | ||
440 | 428 | ||
@@ -451,9 +439,8 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, | |||
451 | */ | 439 | */ |
452 | static void | 440 | static void |
453 | add_to_address_list (struct GNUNET_NAT_Handle *h, | 441 | add_to_address_list (struct GNUNET_NAT_Handle *h, |
454 | enum LocalAddressSource src, | 442 | enum LocalAddressSource src, |
455 | const struct sockaddr *arg, | 443 | const struct sockaddr *arg, socklen_t arg_size) |
456 | socklen_t arg_size) | ||
457 | { | 444 | { |
458 | struct sockaddr_in s4; | 445 | struct sockaddr_in s4; |
459 | const struct sockaddr_in *in4; | 446 | const struct sockaddr_in *in4; |
@@ -461,41 +448,41 @@ add_to_address_list (struct GNUNET_NAT_Handle *h, | |||
461 | const struct sockaddr_in6 *in6; | 448 | const struct sockaddr_in6 *in6; |
462 | 449 | ||
463 | if (arg_size == sizeof (struct sockaddr_in)) | 450 | if (arg_size == sizeof (struct sockaddr_in)) |
451 | { | ||
452 | in4 = (const struct sockaddr_in *) arg; | ||
453 | s4 = *in4; | ||
454 | s4.sin_port = htons (h->adv_port); | ||
455 | add_to_address_list_as_is (h, | ||
456 | src, | ||
457 | (const struct sockaddr *) &s4, | ||
458 | sizeof (struct sockaddr_in)); | ||
459 | if (GNUNET_YES == h->enable_nat_server) | ||
464 | { | 460 | { |
465 | in4 = (const struct sockaddr_in *) arg; | 461 | /* also add with PORT = 0 to indicate NAT server is enabled */ |
466 | s4 = *in4; | 462 | s4.sin_port = htons (0); |
467 | s4.sin_port = htons (h->adv_port); | 463 | add_to_address_list_as_is (h, |
468 | add_to_address_list_as_is (h, | 464 | src, |
469 | src, | 465 | (const struct sockaddr *) &s4, |
470 | (const struct sockaddr*) &s4, | 466 | sizeof (struct sockaddr_in)); |
471 | sizeof (struct sockaddr_in)); | ||
472 | if (GNUNET_YES == h->enable_nat_server) | ||
473 | { | ||
474 | /* also add with PORT = 0 to indicate NAT server is enabled */ | ||
475 | s4.sin_port = htons(0); | ||
476 | add_to_address_list_as_is (h, | ||
477 | src, | ||
478 | (const struct sockaddr*) &s4, | ||
479 | sizeof (struct sockaddr_in)); | ||
480 | } | ||
481 | } | 467 | } |
468 | } | ||
482 | else if (arg_size == sizeof (struct sockaddr_in6)) | 469 | else if (arg_size == sizeof (struct sockaddr_in6)) |
470 | { | ||
471 | if (GNUNET_YES != h->disable_ipv6) | ||
483 | { | 472 | { |
484 | if (GNUNET_YES != h->disable_ipv6) | 473 | in6 = (const struct sockaddr_in6 *) arg; |
485 | { | 474 | s6 = *in6; |
486 | in6 = (const struct sockaddr_in6 *) arg; | 475 | s6.sin6_port = htons (h->adv_port); |
487 | s6 = *in6; | 476 | add_to_address_list_as_is (h, |
488 | s6.sin6_port = htons(h->adv_port); | 477 | src, |
489 | add_to_address_list_as_is (h, | 478 | (const struct sockaddr *) &s6, |
490 | src, | 479 | sizeof (struct sockaddr_in6)); |
491 | (const struct sockaddr*) &s6, | ||
492 | sizeof (struct sockaddr_in6)); | ||
493 | } | ||
494 | } | 480 | } |
481 | } | ||
495 | else | 482 | else |
496 | { | 483 | { |
497 | GNUNET_assert (0); | 484 | GNUNET_assert (0); |
498 | } | 485 | } |
499 | } | 486 | } |
500 | 487 | ||
501 | 488 | ||
@@ -510,9 +497,8 @@ add_to_address_list (struct GNUNET_NAT_Handle *h, | |||
510 | */ | 497 | */ |
511 | static void | 498 | static void |
512 | add_ip_to_address_list (struct GNUNET_NAT_Handle *h, | 499 | add_ip_to_address_list (struct GNUNET_NAT_Handle *h, |
513 | enum LocalAddressSource src, | 500 | enum LocalAddressSource src, |
514 | const void *addr, | 501 | const void *addr, socklen_t addrlen) |
515 | socklen_t addrlen) | ||
516 | { | 502 | { |
517 | struct sockaddr_in s4; | 503 | struct sockaddr_in s4; |
518 | const struct in_addr *in4; | 504 | const struct in_addr *in4; |
@@ -520,52 +506,52 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h, | |||
520 | const struct in6_addr *in6; | 506 | const struct in6_addr *in6; |
521 | 507 | ||
522 | if (addrlen == sizeof (struct in_addr)) | 508 | if (addrlen == sizeof (struct in_addr)) |
523 | { | 509 | { |
524 | in4 = (const struct in_addr *) addr; | 510 | in4 = (const struct in_addr *) addr; |
525 | memset (&s4, 0, sizeof (s4)); | 511 | memset (&s4, 0, sizeof (s4)); |
526 | s4.sin_family = AF_INET; | 512 | s4.sin_family = AF_INET; |
527 | s4.sin_port = 0; | 513 | s4.sin_port = 0; |
528 | #if HAVE_SOCKADDR_IN_SIN_LEN | 514 | #if HAVE_SOCKADDR_IN_SIN_LEN |
529 | s4.sin_len = (u_char) sizeof (struct sockaddr_in); | 515 | s4.sin_len = (u_char) sizeof (struct sockaddr_in); |
530 | #endif | 516 | #endif |
531 | s4.sin_addr = *in4; | 517 | s4.sin_addr = *in4; |
532 | add_to_address_list (h, | 518 | add_to_address_list (h, |
533 | src, | 519 | src, |
534 | (const struct sockaddr*) &s4, | 520 | (const struct sockaddr *) &s4, |
535 | sizeof (struct sockaddr_in)); | 521 | sizeof (struct sockaddr_in)); |
536 | if (GNUNET_YES == h->enable_nat_server) | 522 | if (GNUNET_YES == h->enable_nat_server) |
537 | { | 523 | { |
538 | /* also add with PORT = 0 to indicate NAT server is enabled */ | 524 | /* also add with PORT = 0 to indicate NAT server is enabled */ |
539 | s4.sin_port = htons(0); | 525 | s4.sin_port = htons (0); |
540 | add_to_address_list (h, | 526 | add_to_address_list (h, |
541 | src, | 527 | src, |
542 | (const struct sockaddr*) &s4, | 528 | (const struct sockaddr *) &s4, |
543 | sizeof (struct sockaddr_in)); | 529 | sizeof (struct sockaddr_in)); |
544 | 530 | ||
545 | } | ||
546 | } | 531 | } |
532 | } | ||
547 | else if (addrlen == sizeof (struct in6_addr)) | 533 | else if (addrlen == sizeof (struct in6_addr)) |
534 | { | ||
535 | if (GNUNET_YES != h->disable_ipv6) | ||
548 | { | 536 | { |
549 | if (GNUNET_YES != h->disable_ipv6) | 537 | in6 = (const struct in6_addr *) addr; |
550 | { | 538 | memset (&s6, 0, sizeof (s6)); |
551 | in6 = (const struct in6_addr *) addr; | 539 | s6.sin6_family = AF_INET6; |
552 | memset (&s6, 0, sizeof (s6)); | 540 | s6.sin6_port = htons (h->adv_port); |
553 | s6.sin6_family = AF_INET6; | ||
554 | s6.sin6_port = htons(h->adv_port); | ||
555 | #if HAVE_SOCKADDR_IN_SIN_LEN | 541 | #if HAVE_SOCKADDR_IN_SIN_LEN |
556 | s6.sin6_len = (u_char) sizeof (struct sockaddr_in6); | 542 | s6.sin6_len = (u_char) sizeof (struct sockaddr_in6); |
557 | #endif | 543 | #endif |
558 | s6.sin6_addr = *in6; | 544 | s6.sin6_addr = *in6; |
559 | add_to_address_list (h, | 545 | add_to_address_list (h, |
560 | src, | 546 | src, |
561 | (const struct sockaddr*) &s6, | 547 | (const struct sockaddr *) &s6, |
562 | sizeof (struct sockaddr_in6)); | 548 | sizeof (struct sockaddr_in6)); |
563 | } | ||
564 | } | 549 | } |
550 | } | ||
565 | else | 551 | else |
566 | { | 552 | { |
567 | GNUNET_assert (0); | 553 | GNUNET_assert (0); |
568 | } | 554 | } |
569 | } | 555 | } |
570 | 556 | ||
571 | 557 | ||
@@ -577,8 +563,7 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h, | |||
577 | * @param tc scheduler context | 563 | * @param tc scheduler context |
578 | */ | 564 | */ |
579 | static void | 565 | static void |
580 | resolve_dns (void *cls, | 566 | resolve_dns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
581 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
582 | 567 | ||
583 | 568 | ||
584 | /** | 569 | /** |
@@ -590,24 +575,20 @@ resolve_dns (void *cls, | |||
590 | * @param addrlen number of bytes in addr | 575 | * @param addrlen number of bytes in addr |
591 | */ | 576 | */ |
592 | static void | 577 | static void |
593 | process_external_ip (void *cls, | 578 | process_external_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen) |
594 | const struct sockaddr *addr, | ||
595 | socklen_t addrlen) | ||
596 | { | 579 | { |
597 | struct GNUNET_NAT_Handle *h = cls; | 580 | struct GNUNET_NAT_Handle *h = cls; |
598 | struct in_addr dummy; | 581 | struct in_addr dummy; |
599 | 582 | ||
600 | if (addr == NULL) | 583 | if (addr == NULL) |
601 | { | 584 | { |
602 | h->ext_dns = NULL; | 585 | h->ext_dns = NULL; |
603 | if (1 == inet_pton (AF_INET, | 586 | if (1 == inet_pton (AF_INET, h->external_address, &dummy)) |
604 | h->external_address, | 587 | return; /* repated lookup pointless: was numeric! */ |
605 | &dummy)) | 588 | h->dns_task = GNUNET_SCHEDULER_add_delayed (h->dyndns_frequency, |
606 | return; /* repated lookup pointless: was numeric! */ | 589 | &resolve_dns, h); |
607 | h->dns_task = GNUNET_SCHEDULER_add_delayed (h->dyndns_frequency, | 590 | return; |
608 | &resolve_dns, h); | 591 | } |
609 | return; | ||
610 | } | ||
611 | add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen); | 592 | add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen); |
612 | } | 593 | } |
613 | 594 | ||
@@ -619,8 +600,7 @@ process_external_ip (void *cls, | |||
619 | * @param tc scheduler context | 600 | * @param tc scheduler context |
620 | */ | 601 | */ |
621 | static void | 602 | static void |
622 | resolve_hostname (void *cls, | 603 | resolve_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
623 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
624 | 604 | ||
625 | 605 | ||
626 | /** | 606 | /** |
@@ -633,18 +613,17 @@ resolve_hostname (void *cls, | |||
633 | * @param addrlen length of the address | 613 | * @param addrlen length of the address |
634 | */ | 614 | */ |
635 | static void | 615 | static void |
636 | process_hostname_ip (void *cls, | 616 | process_hostname_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen) |
637 | const struct sockaddr *addr, socklen_t addrlen) | ||
638 | { | 617 | { |
639 | struct GNUNET_NAT_Handle *h = cls; | 618 | struct GNUNET_NAT_Handle *h = cls; |
640 | 619 | ||
641 | if (addr == NULL) | 620 | if (addr == NULL) |
642 | { | 621 | { |
643 | h->hostname_dns = NULL; | 622 | h->hostname_dns = NULL; |
644 | h->hostname_task = GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency, | 623 | h->hostname_task = GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency, |
645 | &resolve_hostname, h); | 624 | &resolve_hostname, h); |
646 | return; | 625 | return; |
647 | } | 626 | } |
648 | add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen); | 627 | add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen); |
649 | } | 628 | } |
650 | 629 | ||
@@ -673,48 +652,44 @@ process_interfaces (void *cls, | |||
673 | char buf[INET6_ADDRSTRLEN]; | 652 | char buf[INET6_ADDRSTRLEN]; |
674 | 653 | ||
675 | switch (addr->sa_family) | 654 | switch (addr->sa_family) |
655 | { | ||
656 | case AF_INET: | ||
657 | s4 = (struct sockaddr_in *) addr; | ||
658 | ip = &s4->sin_addr; | ||
659 | if (GNUNET_YES == h->use_localaddresses) | ||
660 | add_ip_to_address_list (h, | ||
661 | LAL_INTERFACE_ADDRESS, | ||
662 | &s4->sin_addr, sizeof (struct in_addr)); | ||
663 | break; | ||
664 | case AF_INET6: | ||
665 | s6 = (struct sockaddr_in6 *) addr; | ||
666 | if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
676 | { | 667 | { |
677 | case AF_INET: | 668 | /* skip link local addresses */ |
678 | s4 = (struct sockaddr_in *) addr; | ||
679 | ip = &s4->sin_addr; | ||
680 | if (GNUNET_YES == h->use_localaddresses) | ||
681 | add_ip_to_address_list (h, | ||
682 | LAL_INTERFACE_ADDRESS, | ||
683 | &s4->sin_addr, | ||
684 | sizeof (struct in_addr)); | ||
685 | break; | ||
686 | case AF_INET6: | ||
687 | s6 = (struct sockaddr_in6 *) addr; | ||
688 | if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
689 | { | ||
690 | /* skip link local addresses */ | ||
691 | return GNUNET_OK; | ||
692 | } | ||
693 | ip = &s6->sin6_addr; | ||
694 | if (GNUNET_YES == h->use_localaddresses) | ||
695 | add_ip_to_address_list (h, | ||
696 | LAL_INTERFACE_ADDRESS, | ||
697 | &s6->sin6_addr, | ||
698 | sizeof (struct in6_addr)); | ||
699 | break; | ||
700 | default: | ||
701 | GNUNET_break (0); | ||
702 | return GNUNET_OK; | 669 | return GNUNET_OK; |
703 | } | 670 | } |
704 | if ( (h->internal_address == NULL) && | 671 | ip = &s6->sin6_addr; |
705 | (h->server_proc == NULL) && | 672 | if (GNUNET_YES == h->use_localaddresses) |
706 | (h->server_read_task == GNUNET_SCHEDULER_NO_TASK) && | 673 | add_ip_to_address_list (h, |
707 | (GNUNET_YES == isDefault) && | 674 | LAL_INTERFACE_ADDRESS, |
708 | ( (addr->sa_family == AF_INET) || (addr->sa_family == AF_INET6) ) ) | 675 | &s6->sin6_addr, sizeof (struct in6_addr)); |
709 | { | 676 | break; |
710 | /* no internal address configured, but we found a "default" | 677 | default: |
711 | interface, try using that as our 'internal' address */ | 678 | GNUNET_break (0); |
712 | h->internal_address = GNUNET_strdup (inet_ntop (addr->sa_family, | 679 | return GNUNET_OK; |
713 | ip, | 680 | } |
714 | buf, | 681 | if ((h->internal_address == NULL) && |
715 | sizeof (buf))); | 682 | (h->server_proc == NULL) && |
716 | start_gnunet_nat_server (h); | 683 | (h->server_read_task == GNUNET_SCHEDULER_NO_TASK) && |
717 | } | 684 | (GNUNET_YES == isDefault) && |
685 | ((addr->sa_family == AF_INET) || (addr->sa_family == AF_INET6))) | ||
686 | { | ||
687 | /* no internal address configured, but we found a "default" | ||
688 | * interface, try using that as our 'internal' address */ | ||
689 | h->internal_address = GNUNET_strdup (inet_ntop (addr->sa_family, | ||
690 | ip, buf, sizeof (buf))); | ||
691 | start_gnunet_nat_server (h); | ||
692 | } | ||
718 | return GNUNET_OK; | 693 | return GNUNET_OK; |
719 | } | 694 | } |
720 | 695 | ||
@@ -725,16 +700,15 @@ process_interfaces (void *cls, | |||
725 | * | 700 | * |
726 | * @param cls the 'struct GNUNET_NAT_Handle' | 701 | * @param cls the 'struct GNUNET_NAT_Handle' |
727 | * @param tc scheduler context | 702 | * @param tc scheduler context |
728 | */ | 703 | */ |
729 | static void | 704 | static void |
730 | restart_nat_server (void *cls, | 705 | restart_nat_server (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
731 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
732 | { | 706 | { |
733 | struct GNUNET_NAT_Handle *h = cls; | 707 | struct GNUNET_NAT_Handle *h = cls; |
734 | 708 | ||
735 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 709 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
736 | if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | 710 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) |
737 | return; | 711 | return; |
738 | start_gnunet_nat_server (h); | 712 | start_gnunet_nat_server (h); |
739 | } | 713 | } |
740 | 714 | ||
@@ -748,8 +722,7 @@ restart_nat_server (void *cls, | |||
748 | * @param tc the scheduling context | 722 | * @param tc the scheduling context |
749 | */ | 723 | */ |
750 | static void | 724 | static void |
751 | nat_server_read (void *cls, | 725 | nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
752 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
753 | { | 726 | { |
754 | struct GNUNET_NAT_Handle *h = cls; | 727 | struct GNUNET_NAT_Handle *h = cls; |
755 | char mybuf[40]; | 728 | char mybuf[40]; |
@@ -760,52 +733,53 @@ nat_server_read (void *cls, | |||
760 | struct sockaddr_in sin_addr; | 733 | struct sockaddr_in sin_addr; |
761 | 734 | ||
762 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 735 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
763 | if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | 736 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) |
764 | return; | 737 | return; |
765 | memset (mybuf, 0, sizeof(mybuf)); | 738 | memset (mybuf, 0, sizeof (mybuf)); |
766 | bytes = GNUNET_DISK_file_read(h->server_stdout_handle, | 739 | bytes = GNUNET_DISK_file_read (h->server_stdout_handle, |
767 | mybuf, | 740 | mybuf, sizeof (mybuf)); |
768 | sizeof(mybuf)); | ||
769 | if (bytes < 1) | 741 | if (bytes < 1) |
770 | { | 742 | { |
771 | #if DEBUG_NAT | 743 | #if DEBUG_NAT |
772 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 744 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
773 | "nat", | 745 | "nat", |
774 | "Finished reading from server stdout with code: %d\n", | 746 | "Finished reading from server stdout with code: %d\n", |
775 | bytes); | 747 | bytes); |
776 | #endif | 748 | #endif |
777 | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) | 749 | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) |
778 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 750 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
779 | GNUNET_OS_process_wait (h->server_proc); | 751 | GNUNET_OS_process_wait (h->server_proc); |
780 | GNUNET_OS_process_close (h->server_proc); | 752 | GNUNET_OS_process_close (h->server_proc); |
781 | h->server_proc = NULL; | 753 | h->server_proc = NULL; |
782 | GNUNET_DISK_pipe_close (h->server_stdout); | 754 | GNUNET_DISK_pipe_close (h->server_stdout); |
783 | h->server_stdout = NULL; | 755 | h->server_stdout = NULL; |
784 | h->server_stdout_handle = NULL; | 756 | h->server_stdout_handle = NULL; |
785 | /* now try to restart it */ | 757 | /* now try to restart it */ |
786 | h->server_retry_delay = GNUNET_TIME_relative_multiply (h->server_retry_delay, 2); | 758 | h->server_retry_delay = |
787 | h->server_retry_delay = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS, | 759 | GNUNET_TIME_relative_multiply (h->server_retry_delay, 2); |
788 | h->server_retry_delay); | 760 | h->server_retry_delay = |
789 | h->server_read_task = GNUNET_SCHEDULER_add_delayed (h->server_retry_delay, | 761 | GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS, |
790 | &restart_nat_server, | 762 | h->server_retry_delay); |
791 | h); | 763 | h->server_read_task = |
792 | return; | 764 | GNUNET_SCHEDULER_add_delayed (h->server_retry_delay, |
793 | } | 765 | &restart_nat_server, h); |
766 | return; | ||
767 | } | ||
794 | 768 | ||
795 | port_start = NULL; | 769 | port_start = NULL; |
796 | for (i = 0; i < sizeof(mybuf); i++) | 770 | for (i = 0; i < sizeof (mybuf); i++) |
771 | { | ||
772 | if (mybuf[i] == '\n') | ||
773 | { | ||
774 | mybuf[i] = '\0'; | ||
775 | break; | ||
776 | } | ||
777 | if ((mybuf[i] == ':') && (i + 1 < sizeof (mybuf))) | ||
797 | { | 778 | { |
798 | if (mybuf[i] == '\n') | 779 | mybuf[i] = '\0'; |
799 | { | 780 | port_start = &mybuf[i + 1]; |
800 | mybuf[i] = '\0'; | ||
801 | break; | ||
802 | } | ||
803 | if ( (mybuf[i] == ':') && (i + 1 < sizeof(mybuf)) ) | ||
804 | { | ||
805 | mybuf[i] = '\0'; | ||
806 | port_start = &mybuf[i + 1]; | ||
807 | } | ||
808 | } | 781 | } |
782 | } | ||
809 | 783 | ||
810 | /* construct socket address of sender */ | 784 | /* construct socket address of sender */ |
811 | memset (&sin_addr, 0, sizeof (sin_addr)); | 785 | memset (&sin_addr, 0, sizeof (sin_addr)); |
@@ -813,37 +787,34 @@ nat_server_read (void *cls, | |||
813 | #if HAVE_SOCKADDR_IN_SIN_LEN | 787 | #if HAVE_SOCKADDR_IN_SIN_LEN |
814 | sin_addr.sin_len = sizeof (sin_addr); | 788 | sin_addr.sin_len = sizeof (sin_addr); |
815 | #endif | 789 | #endif |
816 | if ( (NULL == port_start) || | 790 | if ((NULL == port_start) || |
817 | (1 != sscanf (port_start, "%d", &port)) || | 791 | (1 != sscanf (port_start, "%d", &port)) || |
818 | (-1 == inet_pton(AF_INET, mybuf, &sin_addr.sin_addr)) ) | 792 | (-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr))) |
819 | { | 793 | { |
820 | /* should we restart gnunet-helper-nat-server? */ | 794 | /* should we restart gnunet-helper-nat-server? */ |
821 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 795 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
822 | "nat", | 796 | "nat", |
823 | _("gnunet-helper-nat-server generated malformed address `%s'\n"), | 797 | _ |
824 | mybuf); | 798 | ("gnunet-helper-nat-server generated malformed address `%s'\n"), |
825 | h->server_read_task | 799 | mybuf); |
826 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 800 | h->server_read_task = |
827 | h->server_stdout_handle, | 801 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
828 | &nat_server_read, | 802 | h->server_stdout_handle, |
829 | h); | 803 | &nat_server_read, h); |
830 | return; | 804 | return; |
831 | } | 805 | } |
832 | sin_addr.sin_port = htons((uint16_t) port); | 806 | sin_addr.sin_port = htons ((uint16_t) port); |
833 | #if DEBUG_NAT | 807 | #if DEBUG_NAT |
834 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 808 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
835 | "nat", | 809 | "nat", |
836 | "gnunet-helper-nat-server read: %s:%d\n", | 810 | "gnunet-helper-nat-server read: %s:%d\n", mybuf, port); |
837 | mybuf, port); | ||
838 | #endif | 811 | #endif |
839 | h->reversal_callback (h->callback_cls, | 812 | h->reversal_callback (h->callback_cls, |
840 | (const struct sockaddr*) &sin_addr, | 813 | (const struct sockaddr *) &sin_addr, sizeof (sin_addr)); |
841 | sizeof (sin_addr)); | ||
842 | h->server_read_task = | 814 | h->server_read_task = |
843 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 815 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
844 | h->server_stdout_handle, | 816 | h->server_stdout_handle, |
845 | &nat_server_read, | 817 | &nat_server_read, h); |
846 | h); | ||
847 | } | 818 | } |
848 | 819 | ||
849 | 820 | ||
@@ -856,51 +827,45 @@ nat_server_read (void *cls, | |||
856 | static void | 827 | static void |
857 | start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) | 828 | start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) |
858 | { | 829 | { |
859 | if ( (h->behind_nat == GNUNET_YES) && | 830 | if ((h->behind_nat == GNUNET_YES) && |
860 | (h->enable_nat_server == GNUNET_YES) && | 831 | (h->enable_nat_server == GNUNET_YES) && |
861 | (h->internal_address != NULL) && | 832 | (h->internal_address != NULL) && |
862 | (NULL != (h->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, | 833 | (NULL != (h->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, |
863 | GNUNET_NO, | 834 | GNUNET_NO, GNUNET_YES)))) |
864 | GNUNET_YES))) ) | 835 | { |
865 | { | ||
866 | #if DEBUG_NAT | 836 | #if DEBUG_NAT |
867 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 837 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
868 | "nat" | 838 | "nat" |
869 | "Starting %s at `%s'\n", | 839 | "Starting %s at `%s'\n", |
870 | "gnunet-helper-nat-server", | 840 | "gnunet-helper-nat-server", h->internal_address); |
871 | h->internal_address); | ||
872 | #endif | 841 | #endif |
873 | /* Start the server process */ | 842 | /* Start the server process */ |
874 | h->server_proc = GNUNET_OS_start_process (NULL, | 843 | h->server_proc = GNUNET_OS_start_process (NULL, |
875 | h->server_stdout, | 844 | h->server_stdout, |
876 | "gnunet-helper-nat-server", | 845 | "gnunet-helper-nat-server", |
877 | "gnunet-helper-nat-server", | 846 | "gnunet-helper-nat-server", |
878 | h->internal_address, | 847 | h->internal_address, NULL); |
879 | NULL); | 848 | if (h->server_proc == NULL) |
880 | if (h->server_proc == NULL) | 849 | { |
881 | { | 850 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
882 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 851 | "nat", |
883 | "nat", | 852 | _("Failed to start %s\n"), "gnunet-helper-nat-server"); |
884 | _("Failed to start %s\n"), | 853 | GNUNET_DISK_pipe_close (h->server_stdout); |
885 | "gnunet-helper-nat-server"); | 854 | h->server_stdout = NULL; |
886 | GNUNET_DISK_pipe_close (h->server_stdout); | 855 | } |
887 | h->server_stdout = NULL; | 856 | else |
888 | } | 857 | { |
889 | else | 858 | /* Close the write end of the read pipe */ |
890 | { | 859 | GNUNET_DISK_pipe_close_end (h->server_stdout, GNUNET_DISK_PIPE_END_WRITE); |
891 | /* Close the write end of the read pipe */ | 860 | h->server_stdout_handle |
892 | GNUNET_DISK_pipe_close_end(h->server_stdout, | 861 | = GNUNET_DISK_pipe_handle (h->server_stdout, |
893 | GNUNET_DISK_PIPE_END_WRITE); | 862 | GNUNET_DISK_PIPE_END_READ); |
894 | h->server_stdout_handle | 863 | h->server_read_task |
895 | = GNUNET_DISK_pipe_handle (h->server_stdout, | 864 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
896 | GNUNET_DISK_PIPE_END_READ); | 865 | h->server_stdout_handle, |
897 | h->server_read_task | 866 | &nat_server_read, h); |
898 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 867 | } |
899 | h->server_stdout_handle, | 868 | } |
900 | &nat_server_read, | ||
901 | h); | ||
902 | } | ||
903 | } | ||
904 | } | 869 | } |
905 | 870 | ||
906 | 871 | ||
@@ -911,16 +876,15 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) | |||
911 | * @param tc scheduler context | 876 | * @param tc scheduler context |
912 | */ | 877 | */ |
913 | static void | 878 | static void |
914 | list_interfaces (void *cls, | 879 | list_interfaces (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
915 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
916 | { | 880 | { |
917 | struct GNUNET_NAT_Handle *h = cls; | 881 | struct GNUNET_NAT_Handle *h = cls; |
918 | 882 | ||
919 | h->ifc_task = GNUNET_SCHEDULER_NO_TASK; | 883 | h->ifc_task = GNUNET_SCHEDULER_NO_TASK; |
920 | remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS); | 884 | remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS); |
921 | GNUNET_OS_network_interfaces_list (&process_interfaces, h); | 885 | GNUNET_OS_network_interfaces_list (&process_interfaces, h); |
922 | h->ifc_task = GNUNET_SCHEDULER_add_delayed (h->ifc_scan_frequency, | 886 | h->ifc_task = GNUNET_SCHEDULER_add_delayed (h->ifc_scan_frequency, |
923 | &list_interfaces, h); | 887 | &list_interfaces, h); |
924 | } | 888 | } |
925 | 889 | ||
926 | 890 | ||
@@ -931,17 +895,15 @@ list_interfaces (void *cls, | |||
931 | * @param tc scheduler context | 895 | * @param tc scheduler context |
932 | */ | 896 | */ |
933 | static void | 897 | static void |
934 | resolve_hostname (void *cls, | 898 | resolve_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
935 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
936 | { | 899 | { |
937 | struct GNUNET_NAT_Handle *h = cls; | 900 | struct GNUNET_NAT_Handle *h = cls; |
938 | 901 | ||
939 | h->hostname_task = GNUNET_SCHEDULER_NO_TASK; | 902 | h->hostname_task = GNUNET_SCHEDULER_NO_TASK; |
940 | remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS); | 903 | remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS); |
941 | h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, | 904 | h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, |
942 | HOSTNAME_RESOLVE_TIMEOUT, | 905 | HOSTNAME_RESOLVE_TIMEOUT, |
943 | &process_hostname_ip, | 906 | &process_hostname_ip, h); |
944 | h); | ||
945 | } | 907 | } |
946 | 908 | ||
947 | 909 | ||
@@ -953,18 +915,16 @@ resolve_hostname (void *cls, | |||
953 | * @param tc scheduler context | 915 | * @param tc scheduler context |
954 | */ | 916 | */ |
955 | static void | 917 | static void |
956 | resolve_dns (void *cls, | 918 | resolve_dns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
957 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
958 | { | 919 | { |
959 | struct GNUNET_NAT_Handle *h = cls; | 920 | struct GNUNET_NAT_Handle *h = cls; |
960 | 921 | ||
961 | h->dns_task = GNUNET_SCHEDULER_NO_TASK; | 922 | h->dns_task = GNUNET_SCHEDULER_NO_TASK; |
962 | remove_from_address_list_by_source (h, LAL_EXTERNAL_IP); | 923 | remove_from_address_list_by_source (h, LAL_EXTERNAL_IP); |
963 | h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address, | 924 | h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address, |
964 | AF_INET, | 925 | AF_INET, |
965 | GNUNET_TIME_UNIT_MINUTES, | 926 | GNUNET_TIME_UNIT_MINUTES, |
966 | &process_external_ip, | 927 | &process_external_ip, h); |
967 | h); | ||
968 | } | 928 | } |
969 | 929 | ||
970 | 930 | ||
@@ -977,45 +937,35 @@ resolve_dns (void *cls, | |||
977 | * @param addr either the previous or the new public IP address | 937 | * @param addr either the previous or the new public IP address |
978 | * @param addrlen actual lenght of the address | 938 | * @param addrlen actual lenght of the address |
979 | */ | 939 | */ |
980 | static void | 940 | static void |
981 | upnp_add (void *cls, | 941 | upnp_add (void *cls, |
982 | int add_remove, | 942 | int add_remove, const struct sockaddr *addr, socklen_t addrlen) |
983 | const struct sockaddr *addr, | ||
984 | socklen_t addrlen) | ||
985 | { | 943 | { |
986 | struct GNUNET_NAT_Handle *h = cls; | 944 | struct GNUNET_NAT_Handle *h = cls; |
987 | struct LocalAddressList *pos; | 945 | struct LocalAddressList *pos; |
988 | struct LocalAddressList *next; | 946 | struct LocalAddressList *next; |
989 | 947 | ||
990 | if (GNUNET_YES == add_remove) | 948 | if (GNUNET_YES == add_remove) |
991 | { | 949 | { |
992 | add_to_address_list (h, | 950 | add_to_address_list (h, LAL_UPNP, addr, addrlen); |
993 | LAL_UPNP, | 951 | return; |
994 | addr, addrlen); | 952 | } |
995 | return; | ||
996 | } | ||
997 | /* remove address */ | 953 | /* remove address */ |
998 | next = h->lal_head; | 954 | next = h->lal_head; |
999 | while (NULL != (pos = next)) | 955 | while (NULL != (pos = next)) |
1000 | { | 956 | { |
1001 | next = pos->next; | 957 | next = pos->next; |
1002 | if ( (pos->source != LAL_UPNP) || | 958 | if ((pos->source != LAL_UPNP) || |
1003 | (pos->addrlen != addrlen) || | 959 | (pos->addrlen != addrlen) || (0 != memcmp (&pos[1], addr, addrlen))) |
1004 | (0 != memcmp (&pos[1], | 960 | continue; |
1005 | addr, | 961 | GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos); |
1006 | addrlen)) ) | 962 | if (NULL != h->address_callback) |
1007 | continue; | 963 | h->address_callback (h->callback_cls, |
1008 | GNUNET_CONTAINER_DLL_remove (h->lal_head, | 964 | GNUNET_NO, |
1009 | h->lal_tail, | 965 | (const struct sockaddr *) &pos[1], pos->addrlen); |
1010 | pos); | 966 | GNUNET_free (pos); |
1011 | if (NULL != h->address_callback) | 967 | return; /* only remove once */ |
1012 | h->address_callback (h->callback_cls, | 968 | } |
1013 | GNUNET_NO, | ||
1014 | (const struct sockaddr* ) &pos[1], | ||
1015 | pos->addrlen); | ||
1016 | GNUNET_free (pos); | ||
1017 | return; /* only remove once */ | ||
1018 | } | ||
1019 | /* asked to remove address that does not exist */ | 969 | /* asked to remove address that does not exist */ |
1020 | GNUNET_break (0); | 970 | GNUNET_break (0); |
1021 | } | 971 | } |
@@ -1028,26 +978,21 @@ upnp_add (void *cls, | |||
1028 | * @param port port to map with UPnP | 978 | * @param port port to map with UPnP |
1029 | */ | 979 | */ |
1030 | static void | 980 | static void |
1031 | add_minis (struct GNUNET_NAT_Handle *h, | 981 | add_minis (struct GNUNET_NAT_Handle *h, uint16_t port) |
1032 | uint16_t port) | ||
1033 | { | 982 | { |
1034 | struct MiniList *ml; | 983 | struct MiniList *ml; |
1035 | 984 | ||
1036 | ml = h->mini_head; | 985 | ml = h->mini_head; |
1037 | while (NULL != ml) | 986 | while (NULL != ml) |
1038 | { | 987 | { |
1039 | if (port == ml->port) | 988 | if (port == ml->port) |
1040 | return; /* already got this port */ | 989 | return; /* already got this port */ |
1041 | ml = ml->next; | 990 | ml = ml->next; |
1042 | } | 991 | } |
1043 | ml = GNUNET_malloc (sizeof (struct MiniList)); | 992 | ml = GNUNET_malloc (sizeof (struct MiniList)); |
1044 | ml->port = port; | 993 | ml->port = port; |
1045 | ml->mini = GNUNET_NAT_mini_map_start (port, | 994 | ml->mini = GNUNET_NAT_mini_map_start (port, h->is_tcp, &upnp_add, h); |
1046 | h->is_tcp, | 995 | GNUNET_CONTAINER_DLL_insert (h->mini_head, h->mini_tail, ml); |
1047 | &upnp_add, h); | ||
1048 | GNUNET_CONTAINER_DLL_insert (h->mini_head, | ||
1049 | h->mini_tail, | ||
1050 | ml); | ||
1051 | } | 996 | } |
1052 | 997 | ||
1053 | 998 | ||
@@ -1058,8 +1003,7 @@ add_minis (struct GNUNET_NAT_Handle *h, | |||
1058 | * @param tc scheduler context | 1003 | * @param tc scheduler context |
1059 | */ | 1004 | */ |
1060 | static void | 1005 | static void |
1061 | add_from_bind (void *cls, | 1006 | add_from_bind (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1062 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1063 | { | 1007 | { |
1064 | static struct in6_addr any = IN6ADDR_ANY_INIT; | 1008 | static struct in6_addr any = IN6ADDR_ANY_INIT; |
1065 | struct GNUNET_NAT_Handle *h = cls; | 1009 | struct GNUNET_NAT_Handle *h = cls; |
@@ -1068,38 +1012,39 @@ add_from_bind (void *cls, | |||
1068 | const struct sockaddr_in *v4; | 1012 | const struct sockaddr_in *v4; |
1069 | 1013 | ||
1070 | h->bind_task = GNUNET_SCHEDULER_NO_TASK; | 1014 | h->bind_task = GNUNET_SCHEDULER_NO_TASK; |
1071 | for (i=0;i<h->num_local_addrs;i++) | 1015 | for (i = 0; i < h->num_local_addrs; i++) |
1016 | { | ||
1017 | sa = h->local_addrs[i]; | ||
1018 | switch (sa->sa_family) | ||
1072 | { | 1019 | { |
1073 | sa = h->local_addrs[i]; | 1020 | case AF_INET: |
1074 | switch (sa->sa_family) | 1021 | if (sizeof (struct sockaddr_in) != h->local_addrlens[i]) |
1075 | { | 1022 | { |
1076 | case AF_INET: | 1023 | GNUNET_break (0); |
1077 | if (sizeof (struct sockaddr_in) != h->local_addrlens[i]) | 1024 | break; |
1078 | { | 1025 | } |
1079 | GNUNET_break (0); | 1026 | v4 = (const struct sockaddr_in *) sa; |
1080 | break; | 1027 | if (0 != v4->sin_addr.s_addr) |
1081 | } | 1028 | add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, |
1082 | v4 = (const struct sockaddr_in*) sa; | 1029 | sizeof (struct sockaddr_in)); |
1083 | if (0 != v4->sin_addr.s_addr) | 1030 | if (h->enable_upnp) |
1084 | add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in)); | 1031 | add_minis (h, ntohs (v4->sin_port)); |
1085 | if (h->enable_upnp) | 1032 | break; |
1086 | add_minis (h, ntohs (v4->sin_port)); | 1033 | case AF_INET6: |
1087 | break; | 1034 | if (sizeof (struct sockaddr_in6) != h->local_addrlens[i]) |
1088 | case AF_INET6: | 1035 | { |
1089 | if (sizeof (struct sockaddr_in6) != h->local_addrlens[i]) | 1036 | GNUNET_break (0); |
1090 | { | 1037 | break; |
1091 | GNUNET_break (0); | 1038 | } |
1092 | break; | 1039 | if (0 != memcmp (&((const struct sockaddr_in6 *) sa)->sin6_addr, |
1093 | } | 1040 | &any, sizeof (struct in6_addr))) |
1094 | if (0 != memcmp (&((const struct sockaddr_in6*) sa)->sin6_addr, | 1041 | add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, |
1095 | &any, | 1042 | sizeof (struct sockaddr_in6)); |
1096 | sizeof (struct in6_addr))) | 1043 | break; |
1097 | add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in6)); | 1044 | default: |
1098 | break; | 1045 | break; |
1099 | default: | ||
1100 | break; | ||
1101 | } | ||
1102 | } | 1046 | } |
1047 | } | ||
1103 | } | 1048 | } |
1104 | 1049 | ||
1105 | 1050 | ||
@@ -1124,14 +1069,14 @@ add_from_bind (void *cls, | |||
1124 | */ | 1069 | */ |
1125 | struct GNUNET_NAT_Handle * | 1070 | struct GNUNET_NAT_Handle * |
1126 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | 1071 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, |
1127 | int is_tcp, | 1072 | int is_tcp, |
1128 | uint16_t adv_port, | 1073 | uint16_t adv_port, |
1129 | unsigned int num_addrs, | 1074 | unsigned int num_addrs, |
1130 | const struct sockaddr **addrs, | 1075 | const struct sockaddr **addrs, |
1131 | const socklen_t *addrlens, | 1076 | const socklen_t * addrlens, |
1132 | GNUNET_NAT_AddressCallback address_callback, | 1077 | GNUNET_NAT_AddressCallback address_callback, |
1133 | GNUNET_NAT_ReversalCallback reversal_callback, | 1078 | GNUNET_NAT_ReversalCallback reversal_callback, |
1134 | void *callback_cls) | 1079 | void *callback_cls) |
1135 | { | 1080 | { |
1136 | struct GNUNET_NAT_Handle *h; | 1081 | struct GNUNET_NAT_Handle *h; |
1137 | struct in_addr in_addr; | 1082 | struct in_addr in_addr; |
@@ -1139,10 +1084,9 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1139 | 1084 | ||
1140 | #if DEBUG_NAT | 1085 | #if DEBUG_NAT |
1141 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1086 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1142 | "nat", | 1087 | "nat", |
1143 | "Registered with NAT service at port %u with %u IP bound local addresses\n", | 1088 | "Registered with NAT service at port %u with %u IP bound local addresses\n", |
1144 | (unsigned int) adv_port, | 1089 | (unsigned int) adv_port, num_addrs); |
1145 | num_addrs); | ||
1146 | #endif | 1090 | #endif |
1147 | h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); | 1091 | h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); |
1148 | h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; | 1092 | h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; |
@@ -1154,147 +1098,140 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1154 | h->num_local_addrs = num_addrs; | 1098 | h->num_local_addrs = num_addrs; |
1155 | h->adv_port = adv_port; | 1099 | h->adv_port = adv_port; |
1156 | if (num_addrs != 0) | 1100 | if (num_addrs != 0) |
1101 | { | ||
1102 | h->local_addrs = GNUNET_malloc (num_addrs * sizeof (struct sockaddr *)); | ||
1103 | h->local_addrlens = GNUNET_malloc (num_addrs * sizeof (socklen_t)); | ||
1104 | for (i = 0; i < num_addrs; i++) | ||
1157 | { | 1105 | { |
1158 | h->local_addrs = GNUNET_malloc (num_addrs * sizeof (struct sockaddr*)); | 1106 | GNUNET_assert (addrlens[i] > 0); |
1159 | h->local_addrlens = GNUNET_malloc (num_addrs * sizeof (socklen_t)); | 1107 | GNUNET_assert (addrs[i] != NULL); |
1160 | for (i=0;i<num_addrs;i++) | 1108 | h->local_addrlens[i] = addrlens[i]; |
1161 | { | 1109 | h->local_addrs[i] = GNUNET_malloc (addrlens[i]); |
1162 | GNUNET_assert (addrlens[i] > 0); | 1110 | memcpy (h->local_addrs[i], addrs[i], addrlens[i]); |
1163 | GNUNET_assert (addrs[i] != NULL); | ||
1164 | h->local_addrlens[i] = addrlens[i]; | ||
1165 | h->local_addrs[i] = GNUNET_malloc (addrlens[i]); | ||
1166 | memcpy (h->local_addrs[i], addrs[i], addrlens[i]); | ||
1167 | } | ||
1168 | } | 1111 | } |
1112 | } | ||
1169 | h->bind_task = GNUNET_SCHEDULER_add_now (&add_from_bind, h); | 1113 | h->bind_task = GNUNET_SCHEDULER_add_now (&add_from_bind, h); |
1170 | if (GNUNET_OK == | 1114 | if (GNUNET_OK == |
1171 | GNUNET_CONFIGURATION_have_value (cfg, | 1115 | GNUNET_CONFIGURATION_have_value (cfg, "nat", "INTERNAL_ADDRESS")) |
1172 | "nat", | 1116 | { |
1173 | "INTERNAL_ADDRESS")) | 1117 | (void) GNUNET_CONFIGURATION_get_value_string (cfg, |
1174 | { | 1118 | "nat", |
1175 | (void) GNUNET_CONFIGURATION_get_value_string (cfg, | 1119 | "INTERNAL_ADDRESS", |
1176 | "nat", | 1120 | &h->internal_address); |
1177 | "INTERNAL_ADDRESS", | 1121 | } |
1178 | &h->internal_address); | 1122 | if ((h->internal_address != NULL) && |
1179 | } | 1123 | (inet_pton (AF_INET, h->internal_address, &in_addr) != 1)) |
1180 | if ( (h->internal_address != NULL) && | 1124 | { |
1181 | (inet_pton(AF_INET, h->internal_address, &in_addr) != 1) ) | 1125 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
1182 | { | 1126 | "nat", |
1183 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 1127 | _("Malformed %s `%s' given in configuration!\n"), |
1184 | "nat", | 1128 | "INTERNAL_ADDRESS", h->internal_address); |
1185 | _("Malformed %s `%s' given in configuration!\n"), | 1129 | GNUNET_free (h->internal_address); |
1186 | "INTERNAL_ADDRESS", | 1130 | h->internal_address = NULL; |
1187 | h->internal_address); | 1131 | } |
1188 | GNUNET_free (h->internal_address); | ||
1189 | h->internal_address = NULL; | ||
1190 | } | ||
1191 | 1132 | ||
1192 | if (GNUNET_OK == | 1133 | if (GNUNET_OK == |
1193 | GNUNET_CONFIGURATION_have_value (cfg, | 1134 | GNUNET_CONFIGURATION_have_value (cfg, "nat", "EXTERNAL_ADDRESS")) |
1194 | "nat", | 1135 | { |
1195 | "EXTERNAL_ADDRESS")) | 1136 | (void) GNUNET_CONFIGURATION_get_value_string (cfg, |
1196 | { | 1137 | "nat", |
1197 | (void) GNUNET_CONFIGURATION_get_value_string (cfg, | 1138 | "EXTERNAL_ADDRESS", |
1198 | "nat", | 1139 | &h->external_address); |
1199 | "EXTERNAL_ADDRESS", | 1140 | } |
1200 | &h->external_address); | 1141 | if ((h->external_address != NULL) && |
1201 | } | 1142 | (inet_pton (AF_INET, h->external_address, &in_addr) != 1)) |
1202 | if ( (h->external_address != NULL) && | 1143 | { |
1203 | (inet_pton(AF_INET, h->external_address, &in_addr) != 1) ) | 1144 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
1204 | { | 1145 | "nat", |
1205 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 1146 | _("Malformed %s `%s' given in configuration!\n"), |
1206 | "nat", | 1147 | "EXTERNAL_ADDRESS", h->external_address); |
1207 | _("Malformed %s `%s' given in configuration!\n"), | 1148 | GNUNET_free (h->external_address); |
1208 | "EXTERNAL_ADDRESS", | 1149 | h->external_address = NULL; |
1209 | h->external_address); | 1150 | } |
1210 | GNUNET_free (h->external_address); | ||
1211 | h->external_address = NULL; | ||
1212 | } | ||
1213 | h->behind_nat = GNUNET_CONFIGURATION_get_value_yesno (cfg, | 1151 | h->behind_nat = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1214 | "nat", | 1152 | "nat", "BEHIND_NAT"); |
1215 | "BEHIND_NAT"); | ||
1216 | h->nat_punched = GNUNET_CONFIGURATION_get_value_yesno (cfg, | 1153 | h->nat_punched = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1217 | "nat", | 1154 | "nat", "PUNCHED_NAT"); |
1218 | "PUNCHED_NAT"); | ||
1219 | h->enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (cfg, | 1155 | h->enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1220 | "nat", | 1156 | "nat", |
1221 | "ENABLE_NAT_CLIENT"); | 1157 | "ENABLE_NAT_CLIENT"); |
1222 | h->enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (cfg, | 1158 | h->enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1223 | "nat", | 1159 | "nat", |
1224 | "ENABLE_NAT_SERVER"); | 1160 | "ENABLE_NAT_SERVER"); |
1225 | h->enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (cfg, | 1161 | h->enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1226 | "nat", | 1162 | "nat", "ENABLE_UPNP"); |
1227 | "ENABLE_UPNP"); | ||
1228 | h->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (cfg, | 1163 | h->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1229 | "nat", | 1164 | "nat", |
1230 | "USE_LOCALADDR"); | 1165 | "USE_LOCALADDR"); |
1231 | h->use_hostname = GNUNET_CONFIGURATION_get_value_yesno (cfg, | 1166 | h->use_hostname = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1232 | "nat", | 1167 | "nat", |
1233 | "USE_HOSTNAME"); | 1168 | "USE_HOSTNAME"); |
1234 | h->disable_ipv6 = GNUNET_CONFIGURATION_get_value_yesno(cfg, | 1169 | h->disable_ipv6 = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
1235 | "nat", | 1170 | "nat", "DISABLEV6"); |
1236 | "DISABLEV6"); | ||
1237 | if (GNUNET_OK != | 1171 | if (GNUNET_OK != |
1238 | GNUNET_CONFIGURATION_get_value_time (cfg, | 1172 | GNUNET_CONFIGURATION_get_value_time (cfg, |
1239 | "nat", | 1173 | "nat", |
1240 | "DYNDNS_FREQUENCY", | 1174 | "DYNDNS_FREQUENCY", |
1241 | &h->dyndns_frequency)) | 1175 | &h->dyndns_frequency)) |
1242 | h->dyndns_frequency = DYNDNS_FREQUENCY; | 1176 | h->dyndns_frequency = DYNDNS_FREQUENCY; |
1243 | if (GNUNET_OK != | 1177 | if (GNUNET_OK != |
1244 | GNUNET_CONFIGURATION_get_value_time (cfg, | 1178 | GNUNET_CONFIGURATION_get_value_time (cfg, |
1245 | "nat", | 1179 | "nat", |
1246 | "IFC_SCAN_FREQUENCY", | 1180 | "IFC_SCAN_FREQUENCY", |
1247 | &h->ifc_scan_frequency)) | 1181 | &h->ifc_scan_frequency)) |
1248 | h->ifc_scan_frequency = IFC_SCAN_FREQUENCY; | 1182 | h->ifc_scan_frequency = IFC_SCAN_FREQUENCY; |
1249 | if (GNUNET_OK != | 1183 | if (GNUNET_OK != |
1250 | GNUNET_CONFIGURATION_get_value_time (cfg, | 1184 | GNUNET_CONFIGURATION_get_value_time (cfg, |
1251 | "nat", | 1185 | "nat", |
1252 | "HOSTNAME_DNS_FREQUENCY", | 1186 | "HOSTNAME_DNS_FREQUENCY", |
1253 | &h->hostname_dns_frequency)) | 1187 | &h->hostname_dns_frequency)) |
1254 | h->hostname_dns_frequency = HOSTNAME_DNS_FREQUENCY; | 1188 | h->hostname_dns_frequency = HOSTNAME_DNS_FREQUENCY; |
1255 | 1189 | ||
1256 | if (NULL == reversal_callback) | 1190 | if (NULL == reversal_callback) |
1257 | h->enable_nat_server = GNUNET_NO; | 1191 | h->enable_nat_server = GNUNET_NO; |
1258 | 1192 | ||
1259 | /* Check if NAT was hole-punched */ | 1193 | /* Check if NAT was hole-punched */ |
1260 | if ( (NULL != h->address_callback) && | 1194 | if ((NULL != h->address_callback) && |
1261 | (h->external_address != NULL) && | 1195 | (h->external_address != NULL) && (h->nat_punched == GNUNET_YES)) |
1262 | (h->nat_punched == GNUNET_YES) ) | 1196 | { |
1263 | { | 1197 | h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h); |
1264 | h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h); | 1198 | h->enable_nat_server = GNUNET_NO; |
1265 | h->enable_nat_server = GNUNET_NO; | 1199 | h->enable_upnp = GNUNET_NO; |
1266 | h->enable_upnp = GNUNET_NO; | 1200 | } |
1267 | } | ||
1268 | 1201 | ||
1269 | /* Test for SUID binaries */ | 1202 | /* Test for SUID binaries */ |
1270 | if ( (h->behind_nat == GNUNET_YES) && | 1203 | if ((h->behind_nat == GNUNET_YES) && |
1271 | (GNUNET_YES == h->enable_nat_server) && | 1204 | (GNUNET_YES == h->enable_nat_server) && |
1272 | (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-server")) ) | 1205 | (GNUNET_YES != |
1273 | { | 1206 | GNUNET_OS_check_helper_binary ("gnunet-helper-nat-server"))) |
1274 | h->enable_nat_server = GNUNET_NO; | 1207 | { |
1275 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1208 | h->enable_nat_server = GNUNET_NO; |
1276 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), | 1209 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1277 | "gnunet-helper-nat-server"); | 1210 | _ |
1278 | } | 1211 | ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), |
1279 | if ( (GNUNET_YES == h->enable_nat_client) && | 1212 | "gnunet-helper-nat-server"); |
1280 | (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-client")) ) | 1213 | } |
1281 | { | 1214 | if ((GNUNET_YES == h->enable_nat_client) && |
1282 | h->enable_nat_client = GNUNET_NO; | 1215 | (GNUNET_YES != |
1283 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1216 | GNUNET_OS_check_helper_binary ("gnunet-helper-nat-client"))) |
1284 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), | 1217 | { |
1285 | "gnunet-helper-nat-client"); | 1218 | h->enable_nat_client = GNUNET_NO; |
1286 | } | 1219 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1220 | _ | ||
1221 | ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), | ||
1222 | "gnunet-helper-nat-client"); | ||
1223 | } | ||
1287 | 1224 | ||
1288 | start_gnunet_nat_server (h); | 1225 | start_gnunet_nat_server (h); |
1289 | 1226 | ||
1290 | /* FIXME: add support for UPnP, etc */ | 1227 | /* FIXME: add support for UPnP, etc */ |
1291 | 1228 | ||
1292 | if (NULL != h->address_callback) | 1229 | if (NULL != h->address_callback) |
1293 | { | 1230 | { |
1294 | h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); | 1231 | h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); |
1295 | if (GNUNET_YES == h->use_hostname) | 1232 | if (GNUNET_YES == h->use_hostname) |
1296 | h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h); | 1233 | h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h); |
1297 | } | 1234 | } |
1298 | 1235 | ||
1299 | return h; | 1236 | return h; |
1300 | } | 1237 | } |
@@ -1314,84 +1251,79 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) | |||
1314 | struct MiniList *ml; | 1251 | struct MiniList *ml; |
1315 | 1252 | ||
1316 | while (NULL != (ml = h->mini_head)) | 1253 | while (NULL != (ml = h->mini_head)) |
1317 | { | 1254 | { |
1318 | GNUNET_CONTAINER_DLL_remove (h->mini_head, | 1255 | GNUNET_CONTAINER_DLL_remove (h->mini_head, h->mini_tail, ml); |
1319 | h->mini_tail, | 1256 | if (NULL != ml->mini) |
1320 | ml); | 1257 | GNUNET_NAT_mini_map_stop (ml->mini); |
1321 | if (NULL != ml->mini) | 1258 | GNUNET_free (ml); |
1322 | GNUNET_NAT_mini_map_stop (ml->mini); | 1259 | } |
1323 | GNUNET_free (ml); | ||
1324 | } | ||
1325 | if (h->ext_dns != NULL) | 1260 | if (h->ext_dns != NULL) |
1326 | { | 1261 | { |
1327 | GNUNET_RESOLVER_request_cancel (h->ext_dns); | 1262 | GNUNET_RESOLVER_request_cancel (h->ext_dns); |
1328 | h->ext_dns = NULL; | 1263 | h->ext_dns = NULL; |
1329 | } | 1264 | } |
1330 | if (NULL != h->hostname_dns) | 1265 | if (NULL != h->hostname_dns) |
1331 | { | 1266 | { |
1332 | GNUNET_RESOLVER_request_cancel (h->hostname_dns); | 1267 | GNUNET_RESOLVER_request_cancel (h->hostname_dns); |
1333 | h->hostname_dns = NULL; | 1268 | h->hostname_dns = NULL; |
1334 | } | 1269 | } |
1335 | if (GNUNET_SCHEDULER_NO_TASK != h->server_read_task) | 1270 | if (GNUNET_SCHEDULER_NO_TASK != h->server_read_task) |
1336 | { | 1271 | { |
1337 | GNUNET_SCHEDULER_cancel (h->server_read_task); | 1272 | GNUNET_SCHEDULER_cancel (h->server_read_task); |
1338 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 1273 | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
1339 | } | 1274 | } |
1340 | if (GNUNET_SCHEDULER_NO_TASK != h->bind_task) | 1275 | if (GNUNET_SCHEDULER_NO_TASK != h->bind_task) |
1341 | { | 1276 | { |
1342 | GNUNET_SCHEDULER_cancel (h->bind_task); | 1277 | GNUNET_SCHEDULER_cancel (h->bind_task); |
1343 | h->bind_task = GNUNET_SCHEDULER_NO_TASK; | 1278 | h->bind_task = GNUNET_SCHEDULER_NO_TASK; |
1344 | } | 1279 | } |
1345 | if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task) | 1280 | if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task) |
1346 | { | 1281 | { |
1347 | GNUNET_SCHEDULER_cancel (h->ifc_task); | 1282 | GNUNET_SCHEDULER_cancel (h->ifc_task); |
1348 | h->ifc_task = GNUNET_SCHEDULER_NO_TASK; | 1283 | h->ifc_task = GNUNET_SCHEDULER_NO_TASK; |
1349 | } | 1284 | } |
1350 | if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task) | 1285 | if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task) |
1351 | { | 1286 | { |
1352 | GNUNET_SCHEDULER_cancel (h->hostname_task); | 1287 | GNUNET_SCHEDULER_cancel (h->hostname_task); |
1353 | h->hostname_task = GNUNET_SCHEDULER_NO_TASK; | 1288 | h->hostname_task = GNUNET_SCHEDULER_NO_TASK; |
1354 | } | 1289 | } |
1355 | if (GNUNET_SCHEDULER_NO_TASK != h->dns_task) | 1290 | if (GNUNET_SCHEDULER_NO_TASK != h->dns_task) |
1356 | { | 1291 | { |
1357 | GNUNET_SCHEDULER_cancel (h->dns_task); | 1292 | GNUNET_SCHEDULER_cancel (h->dns_task); |
1358 | h->dns_task = GNUNET_SCHEDULER_NO_TASK; | 1293 | h->dns_task = GNUNET_SCHEDULER_NO_TASK; |
1359 | } | 1294 | } |
1360 | if (NULL != h->server_proc) | 1295 | if (NULL != h->server_proc) |
1361 | { | 1296 | { |
1362 | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) | 1297 | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) |
1363 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 1298 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
1364 | GNUNET_OS_process_wait (h->server_proc); | 1299 | GNUNET_OS_process_wait (h->server_proc); |
1365 | GNUNET_OS_process_close (h->server_proc); | 1300 | GNUNET_OS_process_close (h->server_proc); |
1366 | h->server_proc = NULL; | 1301 | h->server_proc = NULL; |
1367 | GNUNET_DISK_pipe_close (h->server_stdout); | 1302 | GNUNET_DISK_pipe_close (h->server_stdout); |
1368 | h->server_stdout = NULL; | 1303 | h->server_stdout = NULL; |
1369 | h->server_stdout_handle = NULL; | 1304 | h->server_stdout_handle = NULL; |
1370 | } | 1305 | } |
1371 | if (NULL != h->server_stdout) | 1306 | if (NULL != h->server_stdout) |
1372 | { | 1307 | { |
1373 | GNUNET_DISK_pipe_close (h->server_stdout); | 1308 | GNUNET_DISK_pipe_close (h->server_stdout); |
1374 | h->server_stdout = NULL; | 1309 | h->server_stdout = NULL; |
1375 | h->server_stdout_handle = NULL; | 1310 | h->server_stdout_handle = NULL; |
1376 | } | 1311 | } |
1377 | while (NULL != (lal = h->lal_head)) | 1312 | while (NULL != (lal = h->lal_head)) |
1378 | { | 1313 | { |
1379 | GNUNET_CONTAINER_DLL_remove (h->lal_head, | 1314 | GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, lal); |
1380 | h->lal_tail, | 1315 | if (NULL != h->address_callback) |
1381 | lal); | 1316 | h->address_callback (h->callback_cls, |
1382 | if (NULL != h->address_callback) | 1317 | GNUNET_NO, |
1383 | h->address_callback (h->callback_cls, | 1318 | (const struct sockaddr *) &lal[1], lal->addrlen); |
1384 | GNUNET_NO, | 1319 | GNUNET_free (lal); |
1385 | (const struct sockaddr*) &lal[1], | 1320 | } |
1386 | lal->addrlen); | 1321 | for (i = 0; i < h->num_local_addrs; i++) |
1387 | GNUNET_free (lal); | ||
1388 | } | ||
1389 | for (i=0;i<h->num_local_addrs;i++) | ||
1390 | GNUNET_free (h->local_addrs[i]); | 1322 | GNUNET_free (h->local_addrs[i]); |
1391 | GNUNET_free_non_null (h->local_addrs); | 1323 | GNUNET_free_non_null (h->local_addrs); |
1392 | GNUNET_free_non_null (h->local_addrlens); | 1324 | GNUNET_free_non_null (h->local_addrlens); |
1393 | GNUNET_free_non_null (h->external_address); | 1325 | GNUNET_free_non_null (h->external_address); |
1394 | GNUNET_free_non_null (h->internal_address); | 1326 | GNUNET_free_non_null (h->internal_address); |
1395 | GNUNET_free (h); | 1327 | GNUNET_free (h); |
1396 | } | 1328 | } |
1397 | 1329 | ||
@@ -1406,54 +1338,46 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) | |||
1406 | */ | 1338 | */ |
1407 | void | 1339 | void |
1408 | GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, | 1340 | GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, |
1409 | const struct sockaddr_in *sa) | 1341 | const struct sockaddr_in *sa) |
1410 | { | 1342 | { |
1411 | char inet4[INET_ADDRSTRLEN]; | 1343 | char inet4[INET_ADDRSTRLEN]; |
1412 | char port_as_string[6]; | 1344 | char port_as_string[6]; |
1413 | struct GNUNET_OS_Process *proc; | 1345 | struct GNUNET_OS_Process *proc; |
1414 | 1346 | ||
1415 | if (GNUNET_YES != h->enable_nat_client) | 1347 | if (GNUNET_YES != h->enable_nat_client) |
1416 | return; /* not permitted / possible */ | 1348 | return; /* not permitted / possible */ |
1417 | 1349 | ||
1418 | if (h->internal_address == NULL) | 1350 | if (h->internal_address == NULL) |
1419 | { | 1351 | { |
1420 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 1352 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
1421 | "nat", | 1353 | "nat", |
1422 | _("Internal IP address not known, cannot use ICMP NAT traversal method\n")); | 1354 | _ |
1423 | return; | 1355 | ("Internal IP address not known, cannot use ICMP NAT traversal method\n")); |
1424 | } | 1356 | return; |
1357 | } | ||
1425 | GNUNET_assert (sa->sin_family == AF_INET); | 1358 | GNUNET_assert (sa->sin_family == AF_INET); |
1426 | if (NULL == inet_ntop (AF_INET, | 1359 | if (NULL == inet_ntop (AF_INET, &sa->sin_addr, inet4, INET_ADDRSTRLEN)) |
1427 | &sa->sin_addr, | 1360 | { |
1428 | inet4, INET_ADDRSTRLEN)) | 1361 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); |
1429 | { | 1362 | return; |
1430 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); | 1363 | } |
1431 | return; | 1364 | GNUNET_snprintf (port_as_string, sizeof (port_as_string), "%d", h->adv_port); |
1432 | } | ||
1433 | GNUNET_snprintf (port_as_string, | ||
1434 | sizeof (port_as_string), | ||
1435 | "%d", | ||
1436 | h->adv_port); | ||
1437 | #if DEBUG_NAT | 1365 | #if DEBUG_NAT |
1438 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1366 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1439 | "nat", | 1367 | "nat", |
1440 | _("Running gnunet-helper-nat-client %s %s %u\n"), | 1368 | _("Running gnunet-helper-nat-client %s %s %u\n"), |
1441 | h->internal_address, | 1369 | h->internal_address, inet4, (unsigned int) h->adv_port); |
1442 | inet4, | ||
1443 | (unsigned int) h->adv_port); | ||
1444 | #endif | 1370 | #endif |
1445 | proc = GNUNET_OS_start_process (NULL, | 1371 | proc = GNUNET_OS_start_process (NULL, |
1446 | NULL, | 1372 | NULL, |
1447 | "gnunet-helper-nat-client", | 1373 | "gnunet-helper-nat-client", |
1448 | "gnunet-helper-nat-client", | 1374 | "gnunet-helper-nat-client", |
1449 | h->internal_address, | 1375 | h->internal_address, |
1450 | inet4, | 1376 | inet4, port_as_string, NULL); |
1451 | port_as_string, | ||
1452 | NULL); | ||
1453 | if (NULL == proc) | 1377 | if (NULL == proc) |
1454 | return; | 1378 | return; |
1455 | /* we know that the gnunet-helper-nat-client will terminate virtually | 1379 | /* we know that the gnunet-helper-nat-client will terminate virtually |
1456 | instantly */ | 1380 | * instantly */ |
1457 | GNUNET_OS_process_wait (proc); | 1381 | GNUNET_OS_process_wait (proc); |
1458 | GNUNET_OS_process_close (proc); | 1382 | GNUNET_OS_process_close (proc); |
1459 | } | 1383 | } |
@@ -1471,44 +1395,43 @@ GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, | |||
1471 | */ | 1395 | */ |
1472 | int | 1396 | int |
1473 | GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, | 1397 | GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, |
1474 | const void *addr, | 1398 | const void *addr, socklen_t addrlen) |
1475 | socklen_t addrlen) | ||
1476 | { | 1399 | { |
1477 | struct LocalAddressList *pos; | 1400 | struct LocalAddressList *pos; |
1478 | const struct sockaddr_in *in4; | 1401 | const struct sockaddr_in *in4; |
1479 | const struct sockaddr_in6 *in6; | 1402 | const struct sockaddr_in6 *in6; |
1480 | 1403 | ||
1481 | if ( (addrlen != sizeof (struct in_addr)) && | 1404 | if ((addrlen != sizeof (struct in_addr)) && |
1482 | (addrlen != sizeof (struct in6_addr)) ) | 1405 | (addrlen != sizeof (struct in6_addr))) |
1483 | { | 1406 | { |
1484 | GNUNET_break (0); | 1407 | GNUNET_break (0); |
1485 | return GNUNET_SYSERR; | 1408 | return GNUNET_SYSERR; |
1486 | } | 1409 | } |
1487 | pos = h->lal_head; | 1410 | pos = h->lal_head; |
1488 | while (NULL != pos) | 1411 | while (NULL != pos) |
1412 | { | ||
1413 | if (pos->addrlen == sizeof (struct sockaddr_in)) | ||
1489 | { | 1414 | { |
1490 | if (pos->addrlen == sizeof (struct sockaddr_in)) | 1415 | in4 = (struct sockaddr_in *) &pos[1]; |
1491 | { | 1416 | if ((addrlen == sizeof (struct in_addr)) && |
1492 | in4 = (struct sockaddr_in* ) &pos[1]; | 1417 | (0 == memcmp (&in4->sin_addr, addr, sizeof (struct in_addr)))) |
1493 | if ( (addrlen == sizeof (struct in_addr)) && | 1418 | return GNUNET_YES; |
1494 | (0 == memcmp (&in4->sin_addr, addr, sizeof (struct in_addr))) ) | 1419 | } |
1495 | return GNUNET_YES; | 1420 | else if (pos->addrlen == sizeof (struct sockaddr_in6)) |
1496 | } | 1421 | { |
1497 | else if (pos->addrlen == sizeof (struct sockaddr_in6)) | 1422 | in6 = (struct sockaddr_in6 *) &pos[1]; |
1498 | { | 1423 | if ((addrlen == sizeof (struct in6_addr)) && |
1499 | in6 = (struct sockaddr_in6* ) &pos[1]; | 1424 | (0 == memcmp (&in6->sin6_addr, addr, sizeof (struct in6_addr)))) |
1500 | if ( (addrlen == sizeof (struct in6_addr)) && | 1425 | return GNUNET_YES; |
1501 | (0 == memcmp (&in6->sin6_addr, addr, sizeof (struct in6_addr))) ) | 1426 | } |
1502 | return GNUNET_YES; | 1427 | else |
1503 | } | 1428 | { |
1504 | else | 1429 | GNUNET_assert (0); |
1505 | { | ||
1506 | GNUNET_assert (0); | ||
1507 | } | ||
1508 | pos = pos->next; | ||
1509 | } | 1430 | } |
1431 | pos = pos->next; | ||
1432 | } | ||
1510 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1433 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1511 | "Asked to validate one of my addresses and validation failed!\n"); | 1434 | "Asked to validate one of my addresses and validation failed!\n"); |
1512 | return GNUNET_NO; | 1435 | return GNUNET_NO; |
1513 | } | 1436 | } |
1514 | 1437 | ||
diff --git a/src/nat/nat.h b/src/nat/nat.h index bff444e6d..bb13e5274 100644 --- a/src/nat/nat.h +++ b/src/nat/nat.h | |||
@@ -35,17 +35,17 @@ struct GNUNET_NAT_TestMessage | |||
35 | { | 35 | { |
36 | /** | 36 | /** |
37 | * Header with type "GNUNET_MESSAGE_TYPE_NAT_TEST" | 37 | * Header with type "GNUNET_MESSAGE_TYPE_NAT_TEST" |
38 | */ | 38 | */ |
39 | struct GNUNET_MessageHeader header; | 39 | struct GNUNET_MessageHeader header; |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * IPv4 target IP address | 42 | * IPv4 target IP address |
43 | */ | 43 | */ |
44 | uint32_t dst_ipv4; | 44 | uint32_t dst_ipv4; |
45 | 45 | ||
46 | /** | 46 | /** |
47 | * Port to use, 0 to send dummy ICMP response. | 47 | * Port to use, 0 to send dummy ICMP response. |
48 | */ | 48 | */ |
49 | uint16_t dport; | 49 | uint16_t dport; |
50 | 50 | ||
51 | /** | 51 | /** |
diff --git a/src/nat/nat_mini.c b/src/nat/nat_mini.c index 058e8dda2..c40231067 100644 --- a/src/nat/nat_mini.c +++ b/src/nat/nat_mini.c | |||
@@ -109,8 +109,7 @@ struct GNUNET_NAT_ExternalHandle | |||
109 | * @param tc scheduler context | 109 | * @param tc scheduler context |
110 | */ | 110 | */ |
111 | static void | 111 | static void |
112 | read_external_ipv4 (void *cls, | 112 | read_external_ipv4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
113 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
114 | { | 113 | { |
115 | struct GNUNET_NAT_ExternalHandle *eh = cls; | 114 | struct GNUNET_NAT_ExternalHandle *eh = cls; |
116 | ssize_t ret; | 115 | ssize_t ret; |
@@ -118,39 +117,34 @@ read_external_ipv4 (void *cls, | |||
118 | int iret; | 117 | int iret; |
119 | 118 | ||
120 | eh->task = GNUNET_SCHEDULER_NO_TASK; | 119 | eh->task = GNUNET_SCHEDULER_NO_TASK; |
121 | if (GNUNET_YES == | 120 | if (GNUNET_YES == GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, eh->r)) |
122 | GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, | ||
123 | eh->r)) | ||
124 | ret = GNUNET_DISK_file_read (eh->r, | 121 | ret = GNUNET_DISK_file_read (eh->r, |
125 | &eh->buf[eh->off], | 122 | &eh->buf[eh->off], sizeof (eh->buf) - eh->off); |
126 | sizeof (eh->buf)-eh->off); | ||
127 | else | 123 | else |
128 | ret = -1; /* error reading, timeout, etc. */ | 124 | ret = -1; /* error reading, timeout, etc. */ |
129 | if (ret > 0) | 125 | if (ret > 0) |
130 | { | 126 | { |
131 | /* try to read more */ | 127 | /* try to read more */ |
132 | eh->off += ret; | 128 | eh->off += ret; |
133 | eh->task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining (eh->timeout), | 129 | eh->task = |
134 | eh->r, | 130 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining |
135 | &read_external_ipv4, | 131 | (eh->timeout), eh->r, |
136 | eh); | 132 | &read_external_ipv4, eh); |
137 | return; | 133 | return; |
138 | } | 134 | } |
139 | iret = GNUNET_NO; | 135 | iret = GNUNET_NO; |
140 | if ( (eh->off > 7) && | 136 | if ((eh->off > 7) && (eh->buf[eh->off - 1] == '\n')) |
141 | (eh->buf[eh->off-1] == '\n') ) | 137 | { |
138 | eh->buf[eh->off - 1] = '\0'; | ||
139 | if (1 == inet_pton (AF_INET, eh->buf, &addr)) | ||
142 | { | 140 | { |
143 | eh->buf[eh->off-1] = '\0'; | 141 | if (addr.s_addr == 0) |
144 | if (1 == inet_pton (AF_INET, eh->buf, &addr)) | 142 | iret = GNUNET_NO; /* got 0.0.0.0 */ |
145 | { | 143 | else |
146 | if (addr.s_addr == 0) | 144 | iret = GNUNET_OK; |
147 | iret = GNUNET_NO; /* got 0.0.0.0 */ | ||
148 | else | ||
149 | iret = GNUNET_OK; | ||
150 | } | ||
151 | } | 145 | } |
152 | eh->cb (eh->cb_cls, | 146 | } |
153 | (iret == GNUNET_OK) ? &addr : NULL); | 147 | eh->cb (eh->cb_cls, (iret == GNUNET_OK) ? &addr : NULL); |
154 | GNUNET_NAT_mini_get_external_ipv4_cancel (eh); | 148 | GNUNET_NAT_mini_get_external_ipv4_cancel (eh); |
155 | } | 149 | } |
156 | 150 | ||
@@ -165,40 +159,33 @@ read_external_ipv4 (void *cls, | |||
165 | */ | 159 | */ |
166 | struct GNUNET_NAT_ExternalHandle * | 160 | struct GNUNET_NAT_ExternalHandle * |
167 | GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, | 161 | GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, |
168 | GNUNET_NAT_IPCallback cb, | 162 | GNUNET_NAT_IPCallback cb, void *cb_cls) |
169 | void *cb_cls) | ||
170 | { | 163 | { |
171 | struct GNUNET_NAT_ExternalHandle *eh; | 164 | struct GNUNET_NAT_ExternalHandle *eh; |
172 | 165 | ||
173 | eh = GNUNET_malloc (sizeof (struct GNUNET_NAT_ExternalHandle)); | 166 | eh = GNUNET_malloc (sizeof (struct GNUNET_NAT_ExternalHandle)); |
174 | eh->cb = cb; | 167 | eh->cb = cb; |
175 | eh->cb_cls = cb_cls; | 168 | eh->cb_cls = cb_cls; |
176 | eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, | 169 | eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES); |
177 | GNUNET_NO, | ||
178 | GNUNET_YES); | ||
179 | if (NULL == eh->opipe) | 170 | if (NULL == eh->opipe) |
180 | { | 171 | { |
181 | GNUNET_free (eh); | 172 | GNUNET_free (eh); |
182 | return NULL; | 173 | return NULL; |
183 | } | 174 | } |
184 | eh->eip = GNUNET_OS_start_process (NULL, | 175 | eh->eip = GNUNET_OS_start_process (NULL, |
185 | eh->opipe, | 176 | eh->opipe, |
186 | "external-ip", | 177 | "external-ip", "external-ip", NULL); |
187 | "external-ip", NULL); | ||
188 | if (NULL == eh->eip) | 178 | if (NULL == eh->eip) |
189 | { | 179 | { |
190 | GNUNET_DISK_pipe_close (eh->opipe); | 180 | GNUNET_DISK_pipe_close (eh->opipe); |
191 | GNUNET_free (eh); | 181 | GNUNET_free (eh); |
192 | return NULL; | 182 | return NULL; |
193 | } | 183 | } |
194 | GNUNET_DISK_pipe_close_end (eh->opipe, GNUNET_DISK_PIPE_END_WRITE); | 184 | GNUNET_DISK_pipe_close_end (eh->opipe, GNUNET_DISK_PIPE_END_WRITE); |
195 | eh->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 185 | eh->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
196 | eh->r = GNUNET_DISK_pipe_handle (eh->opipe, | 186 | eh->r = GNUNET_DISK_pipe_handle (eh->opipe, GNUNET_DISK_PIPE_END_READ); |
197 | GNUNET_DISK_PIPE_END_READ); | ||
198 | eh->task = GNUNET_SCHEDULER_add_read_file (timeout, | 187 | eh->task = GNUNET_SCHEDULER_add_read_file (timeout, |
199 | eh->r, | 188 | eh->r, &read_external_ipv4, eh); |
200 | &read_external_ipv4, | ||
201 | eh); | ||
202 | return eh; | 189 | return eh; |
203 | } | 190 | } |
204 | 191 | ||
@@ -222,7 +209,7 @@ GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh) | |||
222 | 209 | ||
223 | /** | 210 | /** |
224 | * Handle to a mapping created with upnpc. | 211 | * Handle to a mapping created with upnpc. |
225 | */ | 212 | */ |
226 | struct GNUNET_NAT_MiniHandle | 213 | struct GNUNET_NAT_MiniHandle |
227 | { | 214 | { |
228 | 215 | ||
@@ -274,7 +261,7 @@ struct GNUNET_NAT_MiniHandle | |||
274 | 261 | ||
275 | /** | 262 | /** |
276 | * Did we find our mapping during refresh scan? | 263 | * Did we find our mapping during refresh scan? |
277 | */ | 264 | */ |
278 | int found; | 265 | int found; |
279 | 266 | ||
280 | /** | 267 | /** |
@@ -292,8 +279,7 @@ struct GNUNET_NAT_MiniHandle | |||
292 | * @param tc scheduler context | 279 | * @param tc scheduler context |
293 | */ | 280 | */ |
294 | static void | 281 | static void |
295 | do_refresh (void *cls, | 282 | do_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
296 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
297 | 283 | ||
298 | 284 | ||
299 | /** | 285 | /** |
@@ -302,9 +288,7 @@ do_refresh (void *cls, | |||
302 | * @param cls the 'struct GNUNET_NAT_MiniHandle' | 288 | * @param cls the 'struct GNUNET_NAT_MiniHandle' |
303 | * @param line line of output, NULL at the end | 289 | * @param line line of output, NULL at the end |
304 | */ | 290 | */ |
305 | static void | 291 | static void process_map_output (void *cls, const char *line); |
306 | process_map_output (void *cls, | ||
307 | const char *line); | ||
308 | 292 | ||
309 | 293 | ||
310 | /** | 294 | /** |
@@ -315,8 +299,7 @@ process_map_output (void *cls, | |||
315 | * @param line line of output, NULL at the end | 299 | * @param line line of output, NULL at the end |
316 | */ | 300 | */ |
317 | static void | 301 | static void |
318 | process_refresh_output (void *cls, | 302 | process_refresh_output (void *cls, const char *line) |
319 | const char *line) | ||
320 | { | 303 | { |
321 | struct GNUNET_NAT_MiniHandle *mini = cls; | 304 | struct GNUNET_NAT_MiniHandle *mini = cls; |
322 | char pstr[9]; | 305 | char pstr[9]; |
@@ -325,99 +308,92 @@ process_refresh_output (void *cls, | |||
325 | struct in_addr exip; | 308 | struct in_addr exip; |
326 | 309 | ||
327 | if (NULL == line) | 310 | if (NULL == line) |
311 | { | ||
312 | GNUNET_OS_command_stop (mini->refresh_cmd); | ||
313 | mini->refresh_cmd = NULL; | ||
314 | if (mini->found == GNUNET_NO) | ||
328 | { | 315 | { |
329 | GNUNET_OS_command_stop (mini->refresh_cmd); | 316 | /* mapping disappeared, try to re-create */ |
330 | mini->refresh_cmd = NULL; | 317 | if (mini->did_map) |
331 | if (mini->found == GNUNET_NO) | 318 | { |
332 | { | 319 | mini->ac (mini->ac_cls, GNUNET_NO, |
333 | /* mapping disappeared, try to re-create */ | 320 | (const struct sockaddr *) &mini->current_addr, |
334 | if (mini->did_map) | 321 | sizeof (mini->current_addr)); |
335 | { | 322 | mini->did_map = GNUNET_NO; |
336 | mini->ac (mini->ac_cls, GNUNET_NO, | 323 | } |
337 | (const struct sockaddr*) &mini->current_addr, | 324 | GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) mini->port); |
338 | sizeof (mini->current_addr)); | 325 | mini->map_cmd = GNUNET_OS_command_run (&process_map_output, |
339 | mini->did_map = GNUNET_NO; | 326 | mini, |
340 | } | 327 | MAP_TIMEOUT, |
341 | GNUNET_snprintf (pstr, sizeof (pstr), | 328 | "upnpc", |
342 | "%u", | 329 | "upnpc", |
343 | (unsigned int) mini->port); | 330 | "-r", pstr, |
344 | mini->map_cmd = GNUNET_OS_command_run (&process_map_output, | 331 | mini->is_tcp ? "tcp" : "udp", |
345 | mini, | 332 | NULL); |
346 | MAP_TIMEOUT, | 333 | if (NULL != mini->map_cmd) |
347 | "upnpc", | 334 | return; |
348 | "upnpc", | ||
349 | "-r", pstr, | ||
350 | mini->is_tcp ? "tcp" : "udp", | ||
351 | NULL); | ||
352 | if (NULL != mini->map_cmd) | ||
353 | return; | ||
354 | } | ||
355 | mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, | ||
356 | &do_refresh, | ||
357 | mini); | ||
358 | return; | ||
359 | } | 335 | } |
360 | if (! mini->did_map) | 336 | mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, |
361 | return; /* never mapped, won't find our mapping anyway */ | 337 | &do_refresh, mini); |
338 | return; | ||
339 | } | ||
340 | if (!mini->did_map) | ||
341 | return; /* never mapped, won't find our mapping anyway */ | ||
362 | 342 | ||
363 | /* we're looking for output of the form: | 343 | /* we're looking for output of the form: |
364 | "ExternalIPAddress = 12.134.41.124" */ | 344 | * "ExternalIPAddress = 12.134.41.124" */ |
365 | 345 | ||
366 | s = strstr (line, "ExternalIPAddress = "); | 346 | s = strstr (line, "ExternalIPAddress = "); |
367 | if (NULL != s) | 347 | if (NULL != s) |
368 | { | 348 | { |
369 | s += strlen ("ExternalIPAddress = "); | 349 | s += strlen ("ExternalIPAddress = "); |
370 | if (1 != inet_pton (AF_INET, | 350 | if (1 != inet_pton (AF_INET, s, &exip)) |
371 | s, &exip)) | 351 | return; /* skip */ |
372 | return; /* skip */ | 352 | if (exip.s_addr == mini->current_addr.sin_addr.s_addr) |
373 | if (exip.s_addr == mini->current_addr.sin_addr.s_addr) | 353 | return; /* no change */ |
374 | return; /* no change */ | 354 | /* update mapping */ |
375 | /* update mapping */ | 355 | mini->ac (mini->ac_cls, GNUNET_NO, |
376 | mini->ac (mini->ac_cls, GNUNET_NO, | 356 | (const struct sockaddr *) &mini->current_addr, |
377 | (const struct sockaddr*) &mini->current_addr, | 357 | sizeof (mini->current_addr)); |
378 | sizeof (mini->current_addr)); | 358 | mini->current_addr.sin_addr = exip; |
379 | mini->current_addr.sin_addr = exip; | 359 | mini->ac (mini->ac_cls, GNUNET_YES, |
380 | mini->ac (mini->ac_cls, GNUNET_YES, | 360 | (const struct sockaddr *) &mini->current_addr, |
381 | (const struct sockaddr*) &mini->current_addr, | 361 | sizeof (mini->current_addr)); |
382 | sizeof (mini->current_addr)); | 362 | return; |
383 | return; | 363 | } |
384 | } | ||
385 | /* | 364 | /* |
386 | we're looking for output of the form: | 365 | * we're looking for output of the form: |
387 | 366 | * | |
388 | "0 TCP 3000->192.168.2.150:3000 'libminiupnpc' ''" | 367 | * "0 TCP 3000->192.168.2.150:3000 'libminiupnpc' ''" |
389 | "1 UDP 3001->192.168.2.150:3001 'libminiupnpc' ''" | 368 | * "1 UDP 3001->192.168.2.150:3001 'libminiupnpc' ''" |
390 | 369 | * | |
391 | the pattern we look for is: | 370 | * the pattern we look for is: |
392 | 371 | * | |
393 | "%s TCP PORT->STRING:OURPORT *" or | 372 | * "%s TCP PORT->STRING:OURPORT *" or |
394 | "%s UDP PORT->STRING:OURPORT *" | 373 | * "%s UDP PORT->STRING:OURPORT *" |
395 | */ | 374 | */ |
396 | GNUNET_snprintf (pstr, sizeof (pstr), | 375 | GNUNET_snprintf (pstr, sizeof (pstr), ":%u ", mini->port); |
397 | ":%u ", | ||
398 | mini->port); | ||
399 | if (NULL == (s = strstr (line, "->"))) | 376 | if (NULL == (s = strstr (line, "->"))) |
400 | return; /* skip */ | 377 | return; /* skip */ |
401 | if (NULL == strstr (s, pstr)) | 378 | if (NULL == strstr (s, pstr)) |
402 | return; /* skip */ | 379 | return; /* skip */ |
403 | if (1 != sscanf (line, | 380 | if (1 != sscanf (line, |
404 | (mini->is_tcp) | 381 | (mini->is_tcp) |
405 | ? "%*u TCP %u->%*s:%*u %*s" | 382 | ? "%*u TCP %u->%*s:%*u %*s" |
406 | : "%*u UDP %u->%*s:%*u %*s", | 383 | : "%*u UDP %u->%*s:%*u %*s", &nport)) |
407 | &nport)) | 384 | return; /* skip */ |
408 | return; /* skip */ | ||
409 | mini->found = GNUNET_YES; | 385 | mini->found = GNUNET_YES; |
410 | if (nport == ntohs (mini->current_addr.sin_port)) | 386 | if (nport == ntohs (mini->current_addr.sin_port)) |
411 | return; /* no change */ | 387 | return; /* no change */ |
412 | 388 | ||
413 | /* external port changed, update mapping */ | 389 | /* external port changed, update mapping */ |
414 | mini->ac (mini->ac_cls, GNUNET_NO, | 390 | mini->ac (mini->ac_cls, GNUNET_NO, |
415 | (const struct sockaddr*) &mini->current_addr, | 391 | (const struct sockaddr *) &mini->current_addr, |
416 | sizeof (mini->current_addr)); | 392 | sizeof (mini->current_addr)); |
417 | mini->current_addr.sin_port = htons ((uint16_t) nport); | 393 | mini->current_addr.sin_port = htons ((uint16_t) nport); |
418 | mini->ac (mini->ac_cls, GNUNET_YES, | 394 | mini->ac (mini->ac_cls, GNUNET_YES, |
419 | (const struct sockaddr*) &mini->current_addr, | 395 | (const struct sockaddr *) &mini->current_addr, |
420 | sizeof (mini->current_addr)); | 396 | sizeof (mini->current_addr)); |
421 | } | 397 | } |
422 | 398 | ||
423 | 399 | ||
@@ -428,20 +404,16 @@ process_refresh_output (void *cls, | |||
428 | * @param tc scheduler context | 404 | * @param tc scheduler context |
429 | */ | 405 | */ |
430 | static void | 406 | static void |
431 | do_refresh (void *cls, | 407 | do_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
432 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
433 | { | 408 | { |
434 | struct GNUNET_NAT_MiniHandle *mini = cls; | 409 | struct GNUNET_NAT_MiniHandle *mini = cls; |
435 | 410 | ||
436 | mini->refresh_task = GNUNET_SCHEDULER_NO_TASK; | 411 | mini->refresh_task = GNUNET_SCHEDULER_NO_TASK; |
437 | mini->found = GNUNET_NO; | 412 | mini->found = GNUNET_NO; |
438 | mini->refresh_cmd = GNUNET_OS_command_run (&process_refresh_output, | 413 | mini->refresh_cmd = GNUNET_OS_command_run (&process_refresh_output, |
439 | mini, | 414 | mini, |
440 | MAP_TIMEOUT, | 415 | MAP_TIMEOUT, |
441 | "upnpc", | 416 | "upnpc", "upnpc", "-l", NULL); |
442 | "upnpc", | ||
443 | "-l", | ||
444 | NULL); | ||
445 | } | 417 | } |
446 | 418 | ||
447 | 419 | ||
@@ -452,8 +424,7 @@ do_refresh (void *cls, | |||
452 | * @param line line of output, NULL at the end | 424 | * @param line line of output, NULL at the end |
453 | */ | 425 | */ |
454 | static void | 426 | static void |
455 | process_map_output (void *cls, | 427 | process_map_output (void *cls, const char *line) |
456 | const char *line) | ||
457 | { | 428 | { |
458 | struct GNUNET_NAT_MiniHandle *mini = cls; | 429 | struct GNUNET_NAT_MiniHandle *mini = cls; |
459 | const char *ipaddr; | 430 | const char *ipaddr; |
@@ -462,35 +433,32 @@ process_map_output (void *cls, | |||
462 | unsigned int port; | 433 | unsigned int port; |
463 | 434 | ||
464 | if (NULL == line) | 435 | if (NULL == line) |
465 | { | 436 | { |
466 | GNUNET_OS_command_stop (mini->map_cmd); | 437 | GNUNET_OS_command_stop (mini->map_cmd); |
467 | mini->map_cmd = NULL; | 438 | mini->map_cmd = NULL; |
468 | mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, | 439 | mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, |
469 | &do_refresh, | 440 | &do_refresh, mini); |
470 | mini); | 441 | return; |
471 | return; | 442 | } |
472 | } | ||
473 | /* | 443 | /* |
474 | The upnpc output we're after looks like this: | 444 | * The upnpc output we're after looks like this: |
475 | 445 | * | |
476 | "external 87.123.42.204:3000 TCP is redirected to internal 192.168.2.150:3000" | 446 | * "external 87.123.42.204:3000 TCP is redirected to internal 192.168.2.150:3000" |
477 | */ | 447 | */ |
478 | if ( (NULL == (ipaddr = strstr (line, " "))) || | 448 | if ((NULL == (ipaddr = strstr (line, " "))) || |
479 | (NULL == (pstr = strstr (ipaddr, ":"))) || | 449 | (NULL == (pstr = strstr (ipaddr, ":"))) || |
480 | (1 != sscanf (pstr + 1, "%u", &port)) ) | 450 | (1 != sscanf (pstr + 1, "%u", &port))) |
481 | { | 451 | { |
482 | return; /* skip line */ | 452 | return; /* skip line */ |
483 | } | 453 | } |
484 | ipa = GNUNET_strdup (ipaddr + 1); | 454 | ipa = GNUNET_strdup (ipaddr + 1); |
485 | strstr (ipa, ":")[0] = '\0'; | 455 | strstr (ipa, ":")[0] = '\0'; |
486 | if (1 != inet_pton (AF_INET, | 456 | if (1 != inet_pton (AF_INET, ipa, &mini->current_addr.sin_addr)) |
487 | ipa, | 457 | { |
488 | &mini->current_addr.sin_addr)) | 458 | GNUNET_free (ipa); |
489 | { | 459 | return; /* skip line */ |
490 | GNUNET_free (ipa); | 460 | } |
491 | return; /* skip line */ | 461 | GNUNET_free (ipa); |
492 | } | ||
493 | GNUNET_free (ipa); | ||
494 | 462 | ||
495 | mini->current_addr.sin_port = htons (port); | 463 | mini->current_addr.sin_port = htons (port); |
496 | mini->current_addr.sin_family = AF_INET; | 464 | mini->current_addr.sin_family = AF_INET; |
@@ -499,8 +467,8 @@ process_map_output (void *cls, | |||
499 | #endif | 467 | #endif |
500 | mini->did_map = GNUNET_YES; | 468 | mini->did_map = GNUNET_YES; |
501 | mini->ac (mini->ac_cls, GNUNET_YES, | 469 | mini->ac (mini->ac_cls, GNUNET_YES, |
502 | (const struct sockaddr*) &mini->current_addr, | 470 | (const struct sockaddr *) &mini->current_addr, |
503 | sizeof (mini->current_addr)); | 471 | sizeof (mini->current_addr)); |
504 | } | 472 | } |
505 | 473 | ||
506 | 474 | ||
@@ -519,37 +487,31 @@ process_map_output (void *cls, | |||
519 | */ | 487 | */ |
520 | struct GNUNET_NAT_MiniHandle * | 488 | struct GNUNET_NAT_MiniHandle * |
521 | GNUNET_NAT_mini_map_start (uint16_t port, | 489 | GNUNET_NAT_mini_map_start (uint16_t port, |
522 | int is_tcp, | 490 | int is_tcp, |
523 | GNUNET_NAT_AddressCallback ac, | 491 | GNUNET_NAT_AddressCallback ac, void *ac_cls) |
524 | void *ac_cls) | ||
525 | { | 492 | { |
526 | struct GNUNET_NAT_MiniHandle *ret; | 493 | struct GNUNET_NAT_MiniHandle *ret; |
527 | char pstr[6]; | 494 | char pstr[6]; |
528 | 495 | ||
529 | if (GNUNET_SYSERR == | 496 | if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary ("upnpc")) |
530 | GNUNET_OS_check_helper_binary ("upnpc")) | ||
531 | return NULL; | 497 | return NULL; |
532 | ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_MiniHandle)); | 498 | ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_MiniHandle)); |
533 | ret->ac = ac; | 499 | ret->ac = ac; |
534 | ret->ac_cls = ac_cls; | 500 | ret->ac_cls = ac_cls; |
535 | ret->is_tcp = is_tcp; | 501 | ret->is_tcp = is_tcp; |
536 | ret->port = port; | 502 | ret->port = port; |
537 | GNUNET_snprintf (pstr, sizeof (pstr), | 503 | GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) port); |
538 | "%u", | ||
539 | (unsigned int) port); | ||
540 | ret->map_cmd = GNUNET_OS_command_run (&process_map_output, | 504 | ret->map_cmd = GNUNET_OS_command_run (&process_map_output, |
541 | ret, | 505 | ret, |
542 | MAP_TIMEOUT, | 506 | MAP_TIMEOUT, |
543 | "upnpc", | 507 | "upnpc", |
544 | "upnpc", | 508 | "upnpc", |
545 | "-r", pstr, | 509 | "-r", pstr, |
546 | is_tcp ? "tcp" : "udp", | 510 | is_tcp ? "tcp" : "udp", NULL); |
547 | NULL); | ||
548 | if (NULL != ret->map_cmd) | 511 | if (NULL != ret->map_cmd) |
549 | return ret; | 512 | return ret; |
550 | ret->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, | 513 | ret->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, |
551 | &do_refresh, | 514 | &do_refresh, ret); |
552 | ret); | ||
553 | 515 | ||
554 | return ret; | 516 | return ret; |
555 | } | 517 | } |
@@ -562,23 +524,20 @@ GNUNET_NAT_mini_map_start (uint16_t port, | |||
562 | * @param line line of output, NULL at the end | 524 | * @param line line of output, NULL at the end |
563 | */ | 525 | */ |
564 | static void | 526 | static void |
565 | process_unmap_output (void *cls, | 527 | process_unmap_output (void *cls, const char *line) |
566 | const char *line) | ||
567 | { | 528 | { |
568 | struct GNUNET_NAT_MiniHandle *mini = cls; | 529 | struct GNUNET_NAT_MiniHandle *mini = cls; |
569 | 530 | ||
570 | if (NULL == line) | 531 | if (NULL == line) |
571 | { | 532 | { |
572 | #if DEBUG_NAT | 533 | #if DEBUG_NAT |
573 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 534 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "nat", "UPnP unmap done\n"); |
574 | "nat", | ||
575 | "UPnP unmap done\n"); | ||
576 | #endif | 535 | #endif |
577 | GNUNET_OS_command_stop (mini->unmap_cmd); | 536 | GNUNET_OS_command_stop (mini->unmap_cmd); |
578 | mini->unmap_cmd = NULL; | 537 | mini->unmap_cmd = NULL; |
579 | GNUNET_free (mini); | 538 | GNUNET_free (mini); |
580 | return; | 539 | return; |
581 | } | 540 | } |
582 | /* we don't really care about the output... */ | 541 | /* we don't really care about the output... */ |
583 | } | 542 | } |
584 | 543 | ||
@@ -597,48 +556,46 @@ GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini) | |||
597 | char pstr[6]; | 556 | char pstr[6]; |
598 | 557 | ||
599 | if (GNUNET_SCHEDULER_NO_TASK != mini->refresh_task) | 558 | if (GNUNET_SCHEDULER_NO_TASK != mini->refresh_task) |
600 | { | 559 | { |
601 | GNUNET_SCHEDULER_cancel (mini->refresh_task); | 560 | GNUNET_SCHEDULER_cancel (mini->refresh_task); |
602 | mini->refresh_task = GNUNET_SCHEDULER_NO_TASK; | 561 | mini->refresh_task = GNUNET_SCHEDULER_NO_TASK; |
603 | } | 562 | } |
604 | if (mini->refresh_cmd != NULL) | 563 | if (mini->refresh_cmd != NULL) |
564 | { | ||
565 | GNUNET_OS_command_stop (mini->refresh_cmd); | ||
566 | mini->refresh_cmd = NULL; | ||
567 | } | ||
568 | if (!mini->did_map) | ||
569 | { | ||
570 | if (mini->map_cmd != NULL) | ||
605 | { | 571 | { |
606 | GNUNET_OS_command_stop (mini->refresh_cmd); | 572 | GNUNET_OS_command_stop (mini->map_cmd); |
607 | mini->refresh_cmd = NULL; | 573 | mini->map_cmd = NULL; |
608 | } | ||
609 | if (! mini->did_map) | ||
610 | { | ||
611 | if (mini->map_cmd != NULL) | ||
612 | { | ||
613 | GNUNET_OS_command_stop (mini->map_cmd); | ||
614 | mini->map_cmd = NULL; | ||
615 | } | ||
616 | GNUNET_free (mini); | ||
617 | return; | ||
618 | } | 574 | } |
575 | GNUNET_free (mini); | ||
576 | return; | ||
577 | } | ||
619 | mini->ac (mini->ac_cls, GNUNET_NO, | 578 | mini->ac (mini->ac_cls, GNUNET_NO, |
620 | (const struct sockaddr*) &mini->current_addr, | 579 | (const struct sockaddr *) &mini->current_addr, |
621 | sizeof (mini->current_addr)); | 580 | sizeof (mini->current_addr)); |
622 | /* Note: oddly enough, deletion uses the external port whereas | 581 | /* Note: oddly enough, deletion uses the external port whereas |
623 | addition uses the internal port; this rarely matters since they | 582 | * addition uses the internal port; this rarely matters since they |
624 | often are the same, but it might... */ | 583 | * often are the same, but it might... */ |
625 | GNUNET_snprintf (pstr, sizeof (pstr), | 584 | GNUNET_snprintf (pstr, sizeof (pstr), |
626 | "%u", | 585 | "%u", (unsigned int) ntohs (mini->current_addr.sin_port)); |
627 | (unsigned int) ntohs (mini->current_addr.sin_port)); | ||
628 | #if DEBUG_NAT | 586 | #if DEBUG_NAT |
629 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 587 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
630 | "nat", | 588 | "nat", |
631 | "Unmapping port %u with UPnP\n", | 589 | "Unmapping port %u with UPnP\n", |
632 | ntohs (mini->current_addr.sin_port)); | 590 | ntohs (mini->current_addr.sin_port)); |
633 | #endif | 591 | #endif |
634 | mini->unmap_cmd = GNUNET_OS_command_run (&process_unmap_output, | 592 | mini->unmap_cmd = GNUNET_OS_command_run (&process_unmap_output, |
635 | mini, | 593 | mini, |
636 | UNMAP_TIMEOUT, | 594 | UNMAP_TIMEOUT, |
637 | "upnpc", | 595 | "upnpc", |
638 | "upnpc", | 596 | "upnpc", |
639 | "-d", pstr, | 597 | "-d", pstr, |
640 | mini->is_tcp ? "tcp" : "udp", | 598 | mini->is_tcp ? "tcp" : "udp", NULL); |
641 | NULL); | ||
642 | } | 599 | } |
643 | 600 | ||
644 | 601 | ||
diff --git a/src/nat/nat_test.c b/src/nat/nat_test.c index 8c9933cdb..30db00803 100644 --- a/src/nat/nat_test.c +++ b/src/nat/nat_test.c | |||
@@ -99,7 +99,7 @@ struct GNUNET_NAT_Test | |||
99 | * Function to call with success report | 99 | * Function to call with success report |
100 | */ | 100 | */ |
101 | GNUNET_NAT_TestCallback report; | 101 | GNUNET_NAT_TestCallback report; |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * Closure for 'report'. | 104 | * Closure for 'report'. |
105 | */ | 105 | */ |
@@ -167,9 +167,7 @@ struct GNUNET_NAT_Test | |||
167 | * @param addrlen actual lenght of the address | 167 | * @param addrlen actual lenght of the address |
168 | */ | 168 | */ |
169 | static void | 169 | static void |
170 | reversal_cb (void *cls, | 170 | reversal_cb (void *cls, const struct sockaddr *addr, socklen_t addrlen) |
171 | const struct sockaddr *addr, | ||
172 | socklen_t addrlen) | ||
173 | { | 171 | { |
174 | struct GNUNET_NAT_Test *h = cls; | 172 | struct GNUNET_NAT_Test *h = cls; |
175 | const struct sockaddr_in *sa; | 173 | const struct sockaddr_in *sa; |
@@ -178,14 +176,14 @@ reversal_cb (void *cls, | |||
178 | return; | 176 | return; |
179 | sa = (const struct sockaddr_in *) addr; | 177 | sa = (const struct sockaddr_in *) addr; |
180 | if (h->data != sa->sin_port) | 178 | if (h->data != sa->sin_port) |
181 | { | 179 | { |
182 | #if DEBUG_NAT | 180 | #if DEBUG_NAT |
183 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 181 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
184 | "nat", | 182 | "nat", |
185 | "Received connection reversal request for wrong port\n"); | 183 | "Received connection reversal request for wrong port\n"); |
186 | #endif | 184 | #endif |
187 | return; /* wrong port */ | 185 | return; /* wrong port */ |
188 | } | 186 | } |
189 | /* report success */ | 187 | /* report success */ |
190 | h->report (h->report_cls, GNUNET_OK); | 188 | h->report (h->report_cls, GNUNET_OK); |
191 | } | 189 | } |
@@ -199,38 +197,31 @@ reversal_cb (void *cls, | |||
199 | * @param tc scheduler context | 197 | * @param tc scheduler context |
200 | */ | 198 | */ |
201 | static void | 199 | static void |
202 | do_udp_read (void *cls, | 200 | do_udp_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
203 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
204 | { | 201 | { |
205 | struct GNUNET_NAT_Test *tst = cls; | 202 | struct GNUNET_NAT_Test *tst = cls; |
206 | uint16_t data; | 203 | uint16_t data; |
207 | 204 | ||
208 | tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | 205 | tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
209 | tst->lsock, | 206 | tst->lsock, &do_udp_read, tst); |
210 | &do_udp_read, | 207 | if ((NULL != tc->write_ready) && |
211 | tst); | 208 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, |
212 | if ( (NULL != tc->write_ready) && | 209 | tst->lsock)) && |
213 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, | 210 | (sizeof (data) == |
214 | tst->lsock)) && | 211 | GNUNET_NETWORK_socket_recv (tst->lsock, &data, sizeof (data)))) |
215 | (sizeof (data) == | 212 | { |
216 | GNUNET_NETWORK_socket_recv (tst->lsock, | 213 | if (data == tst->data) |
217 | &data, | 214 | tst->report (tst->report_cls, GNUNET_OK); |
218 | sizeof (data))) ) | ||
219 | { | ||
220 | if (data == tst->data) | ||
221 | tst->report (tst->report_cls, GNUNET_OK); | ||
222 | #if DEBUG_NAT | 215 | #if DEBUG_NAT |
223 | else | 216 | else |
224 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 217 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
225 | "nat", | 218 | "nat", "Received data mismatches expected value\n"); |
226 | "Received data mismatches expected value\n"); | ||
227 | #endif | 219 | #endif |
228 | } | 220 | } |
229 | #if DEBUG_NAT | 221 | #if DEBUG_NAT |
230 | else | 222 | else |
231 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 223 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
232 | "nat", | 224 | "nat", "Failed to receive data from inbound connection\n"); |
233 | "Failed to receive data from inbound connection\n"); | ||
234 | #endif | 225 | #endif |
235 | } | 226 | } |
236 | 227 | ||
@@ -243,8 +234,7 @@ do_udp_read (void *cls, | |||
243 | * @param tc scheduler context | 234 | * @param tc scheduler context |
244 | */ | 235 | */ |
245 | static void | 236 | static void |
246 | do_read (void *cls, | 237 | do_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
247 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
248 | { | 238 | { |
249 | struct NatActivity *na = cls; | 239 | struct NatActivity *na = cls; |
250 | struct GNUNET_NAT_Test *tst; | 240 | struct GNUNET_NAT_Test *tst; |
@@ -252,31 +242,25 @@ do_read (void *cls, | |||
252 | 242 | ||
253 | na->rtask = GNUNET_SCHEDULER_NO_TASK; | 243 | na->rtask = GNUNET_SCHEDULER_NO_TASK; |
254 | tst = na->h; | 244 | tst = na->h; |
255 | GNUNET_CONTAINER_DLL_remove (tst->na_head, | 245 | GNUNET_CONTAINER_DLL_remove (tst->na_head, tst->na_tail, na); |
256 | tst->na_tail, | 246 | if ((NULL != tc->write_ready) && |
257 | na); | 247 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, |
258 | if ( (NULL != tc->write_ready) && | 248 | na->sock)) && |
259 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, | 249 | (sizeof (data) == |
260 | na->sock)) && | 250 | GNUNET_NETWORK_socket_recv (na->sock, &data, sizeof (data)))) |
261 | (sizeof (data) == | 251 | { |
262 | GNUNET_NETWORK_socket_recv (na->sock, | 252 | if (data == tst->data) |
263 | &data, | 253 | tst->report (tst->report_cls, GNUNET_OK); |
264 | sizeof (data))) ) | ||
265 | { | ||
266 | if (data == tst->data) | ||
267 | tst->report (tst->report_cls, GNUNET_OK); | ||
268 | #if DEBUG_NAT | 254 | #if DEBUG_NAT |
269 | else | 255 | else |
270 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 256 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
271 | "nat" | 257 | "nat" "Received data mismatches expected value\n"); |
272 | "Received data mismatches expected value\n"); | ||
273 | #endif | 258 | #endif |
274 | } | 259 | } |
275 | #if DEBUG_NAT | 260 | #if DEBUG_NAT |
276 | else | 261 | else |
277 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 262 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
278 | "nat", | 263 | "nat", "Failed to receive data from inbound connection\n"); |
279 | "Failed to receive data from inbound connection\n"); | ||
280 | #endif | 264 | #endif |
281 | GNUNET_NETWORK_socket_close (na->sock); | 265 | GNUNET_NETWORK_socket_close (na->sock); |
282 | GNUNET_free (na); | 266 | GNUNET_free (na); |
@@ -291,8 +275,7 @@ do_read (void *cls, | |||
291 | * @param tc scheduler context | 275 | * @param tc scheduler context |
292 | */ | 276 | */ |
293 | static void | 277 | static void |
294 | do_accept (void *cls, | 278 | do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
295 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
296 | { | 279 | { |
297 | struct GNUNET_NAT_Test *tst = cls; | 280 | struct GNUNET_NAT_Test *tst = cls; |
298 | struct GNUNET_NETWORK_Handle *s; | 281 | struct GNUNET_NETWORK_Handle *s; |
@@ -300,32 +283,25 @@ do_accept (void *cls, | |||
300 | 283 | ||
301 | tst->ltask = GNUNET_SCHEDULER_NO_TASK; | 284 | tst->ltask = GNUNET_SCHEDULER_NO_TASK; |
302 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 285 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
303 | return; | 286 | return; |
304 | tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | 287 | tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
305 | tst->lsock, | 288 | tst->lsock, &do_accept, tst); |
306 | &do_accept, | ||
307 | tst); | ||
308 | s = GNUNET_NETWORK_socket_accept (tst->lsock, NULL, NULL); | 289 | s = GNUNET_NETWORK_socket_accept (tst->lsock, NULL, NULL); |
309 | if (NULL == s) | 290 | if (NULL == s) |
310 | { | 291 | { |
311 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept"); | 292 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept"); |
312 | return; /* odd error */ | 293 | return; /* odd error */ |
313 | } | 294 | } |
314 | #if DEBUG_NAT | 295 | #if DEBUG_NAT |
315 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 296 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
316 | "nat", | 297 | "nat", "Got an inbound connection, waiting for data\n"); |
317 | "Got an inbound connection, waiting for data\n"); | ||
318 | #endif | 298 | #endif |
319 | wl = GNUNET_malloc (sizeof (struct NatActivity)); | 299 | wl = GNUNET_malloc (sizeof (struct NatActivity)); |
320 | wl->sock = s; | 300 | wl->sock = s; |
321 | wl->h = tst; | 301 | wl->h = tst; |
322 | wl->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | 302 | wl->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
323 | wl->sock, | 303 | wl->sock, &do_read, wl); |
324 | &do_read, | 304 | GNUNET_CONTAINER_DLL_insert (tst->na_head, tst->na_tail, wl); |
325 | wl); | ||
326 | GNUNET_CONTAINER_DLL_insert (tst->na_head, | ||
327 | tst->na_tail, | ||
328 | wl); | ||
329 | } | 305 | } |
330 | 306 | ||
331 | 307 | ||
@@ -338,11 +314,9 @@ do_accept (void *cls, | |||
338 | * @param addr either the previous or the new public IP address | 314 | * @param addr either the previous or the new public IP address |
339 | * @param addrlen actual lenght of the address | 315 | * @param addrlen actual lenght of the address |
340 | */ | 316 | */ |
341 | static void | 317 | static void |
342 | addr_cb (void *cls, | 318 | addr_cb (void *cls, |
343 | int add_remove, | 319 | int add_remove, const struct sockaddr *addr, socklen_t addrlen) |
344 | const struct sockaddr *addr, | ||
345 | socklen_t addrlen) | ||
346 | { | 320 | { |
347 | struct GNUNET_NAT_Test *h = cls; | 321 | struct GNUNET_NAT_Test *h = cls; |
348 | struct ClientActivity *ca; | 322 | struct ClientActivity *ca; |
@@ -353,40 +327,37 @@ addr_cb (void *cls, | |||
353 | if (GNUNET_YES != add_remove) | 327 | if (GNUNET_YES != add_remove) |
354 | return; | 328 | return; |
355 | if (addrlen != sizeof (struct sockaddr_in)) | 329 | if (addrlen != sizeof (struct sockaddr_in)) |
356 | return; /* ignore IPv6 here */ | 330 | return; /* ignore IPv6 here */ |
357 | #if DEBUG_NAT | 331 | #if DEBUG_NAT |
358 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 332 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
359 | "nat", | 333 | "nat", |
360 | "Asking gnunet-nat-server to connect to `%s'\n", | 334 | "Asking gnunet-nat-server to connect to `%s'\n", |
361 | GNUNET_a2s (addr, addrlen)); | 335 | GNUNET_a2s (addr, addrlen)); |
362 | #endif | 336 | #endif |
363 | sa = (const struct sockaddr_in*) addr; | 337 | sa = (const struct sockaddr_in *) addr; |
364 | msg.header.size = htons (sizeof(struct GNUNET_NAT_TestMessage)); | 338 | msg.header.size = htons (sizeof (struct GNUNET_NAT_TestMessage)); |
365 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAT_TEST); | 339 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAT_TEST); |
366 | msg.dst_ipv4 = sa->sin_addr.s_addr; | 340 | msg.dst_ipv4 = sa->sin_addr.s_addr; |
367 | msg.dport = sa->sin_port; | 341 | msg.dport = sa->sin_port; |
368 | msg.data = h->data; | 342 | msg.data = h->data; |
369 | msg.is_tcp = htonl ((uint32_t) h->is_tcp); | 343 | msg.is_tcp = htonl ((uint32_t) h->is_tcp); |
370 | 344 | ||
371 | client = GNUNET_CLIENT_connect ("gnunet-nat-server", | 345 | client = GNUNET_CLIENT_connect ("gnunet-nat-server", h->cfg); |
372 | h->cfg); | ||
373 | if (NULL == client) | 346 | if (NULL == client) |
374 | { | 347 | { |
375 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 348 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
376 | _("Failed to connect to `gnunet-nat-server'\n")); | 349 | _("Failed to connect to `gnunet-nat-server'\n")); |
377 | return; | 350 | return; |
378 | } | 351 | } |
379 | ca = GNUNET_malloc (sizeof (struct ClientActivity)); | 352 | ca = GNUNET_malloc (sizeof (struct ClientActivity)); |
380 | ca->client = client; | 353 | ca->client = client; |
381 | GNUNET_CONTAINER_DLL_insert (h->ca_head, | 354 | GNUNET_CONTAINER_DLL_insert (h->ca_head, h->ca_tail, ca); |
382 | h->ca_tail, | ||
383 | ca); | ||
384 | GNUNET_break (GNUNET_OK == | 355 | GNUNET_break (GNUNET_OK == |
385 | GNUNET_CLIENT_transmit_and_get_response (client, | 356 | GNUNET_CLIENT_transmit_and_get_response (client, |
386 | &msg.header, | 357 | &msg.header, |
387 | GNUNET_TIME_UNIT_SECONDS, | 358 | GNUNET_TIME_UNIT_SECONDS, |
388 | GNUNET_YES, | 359 | GNUNET_YES, |
389 | NULL, NULL)); | 360 | NULL, NULL)); |
390 | } | 361 | } |
391 | 362 | ||
392 | 363 | ||
@@ -404,15 +375,14 @@ addr_cb (void *cls, | |||
404 | */ | 375 | */ |
405 | struct GNUNET_NAT_Test * | 376 | struct GNUNET_NAT_Test * |
406 | GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | 377 | GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, |
407 | int is_tcp, | 378 | int is_tcp, |
408 | uint16_t bnd_port, | 379 | uint16_t bnd_port, |
409 | uint16_t adv_port, | 380 | uint16_t adv_port, |
410 | GNUNET_NAT_TestCallback report, | 381 | GNUNET_NAT_TestCallback report, void *report_cls) |
411 | void *report_cls) | ||
412 | { | 382 | { |
413 | struct GNUNET_NAT_Test *ret; | 383 | struct GNUNET_NAT_Test *ret; |
414 | struct sockaddr_in sa; | 384 | struct sockaddr_in sa; |
415 | const struct sockaddr *addrs[] = { (const struct sockaddr*) &sa }; | 385 | const struct sockaddr *addrs[] = { (const struct sockaddr *) &sa }; |
416 | const socklen_t addrlens[] = { sizeof (sa) }; | 386 | const socklen_t addrlens[] = { sizeof (sa) }; |
417 | 387 | ||
418 | memset (&sa, 0, sizeof (sa)); | 388 | memset (&sa, 0, sizeof (sa)); |
@@ -421,7 +391,7 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
421 | #if HAVE_SOCKADDR_IN_SIN_LEN | 391 | #if HAVE_SOCKADDR_IN_SIN_LEN |
422 | sa.sin_len = sizeof (sa); | 392 | sa.sin_len = sizeof (sa); |
423 | #endif | 393 | #endif |
424 | 394 | ||
425 | ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_Test)); | 395 | ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_Test)); |
426 | ret->cfg = cfg; | 396 | ret->cfg = cfg; |
427 | ret->is_tcp = is_tcp; | 397 | ret->is_tcp = is_tcp; |
@@ -430,54 +400,47 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
430 | ret->report = report; | 400 | ret->report = report; |
431 | ret->report_cls = report_cls; | 401 | ret->report_cls = report_cls; |
432 | if (bnd_port == 0) | 402 | if (bnd_port == 0) |
433 | { | 403 | { |
434 | ret->nat = GNUNET_NAT_register (cfg, is_tcp, | 404 | ret->nat = GNUNET_NAT_register (cfg, is_tcp, |
435 | 0, | 405 | 0, |
436 | 0, NULL, NULL, | 406 | 0, NULL, NULL, &addr_cb, &reversal_cb, ret); |
437 | &addr_cb, &reversal_cb, ret); | 407 | } |
438 | } | ||
439 | else | 408 | else |
409 | { | ||
410 | ret->lsock = GNUNET_NETWORK_socket_create (AF_INET, | ||
411 | (is_tcp == GNUNET_YES) | ||
412 | ? SOCK_STREAM : SOCK_DGRAM, 0); | ||
413 | if ((ret->lsock == NULL) || | ||
414 | (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret->lsock, | ||
415 | (const struct sockaddr *) &sa, | ||
416 | sizeof (sa)))) | ||
417 | { | ||
418 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
419 | _ | ||
420 | ("Failed to create listen socket bound to `%s' for NAT test: %s\n"), | ||
421 | GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa)), | ||
422 | STRERROR (errno)); | ||
423 | if (NULL != ret->lsock) | ||
424 | GNUNET_NETWORK_socket_close (ret->lsock); | ||
425 | GNUNET_free (ret); | ||
426 | return NULL; | ||
427 | } | ||
428 | if (GNUNET_YES == is_tcp) | ||
429 | { | ||
430 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_listen (ret->lsock, 5)); | ||
431 | ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
432 | ret->lsock, &do_accept, ret); | ||
433 | } | ||
434 | else | ||
440 | { | 435 | { |
441 | ret->lsock = GNUNET_NETWORK_socket_create (AF_INET, | 436 | ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
442 | (is_tcp==GNUNET_YES) | 437 | ret->lsock, |
443 | ? SOCK_STREAM | 438 | &do_udp_read, ret); |
444 | : SOCK_DGRAM, 0); | ||
445 | if ( (ret->lsock == NULL) || | ||
446 | (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret->lsock, | ||
447 | (const struct sockaddr*) &sa, | ||
448 | sizeof (sa))) ) | ||
449 | { | ||
450 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
451 | _("Failed to create listen socket bound to `%s' for NAT test: %s\n"), | ||
452 | GNUNET_a2s ((const struct sockaddr*)&sa, | ||
453 | sizeof(sa)), | ||
454 | STRERROR (errno)); | ||
455 | if (NULL != ret->lsock) | ||
456 | GNUNET_NETWORK_socket_close (ret->lsock); | ||
457 | GNUNET_free (ret); | ||
458 | return NULL; | ||
459 | } | ||
460 | if (GNUNET_YES == is_tcp) | ||
461 | { | ||
462 | GNUNET_break (GNUNET_OK == | ||
463 | GNUNET_NETWORK_socket_listen (ret->lsock, 5)); | ||
464 | ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
465 | ret->lsock, | ||
466 | &do_accept, | ||
467 | ret); | ||
468 | } | ||
469 | else | ||
470 | { | ||
471 | ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
472 | ret->lsock, | ||
473 | &do_udp_read, | ||
474 | ret); | ||
475 | } | ||
476 | ret->nat = GNUNET_NAT_register (cfg, is_tcp, | ||
477 | adv_port, | ||
478 | 1, addrs, addrlens, | ||
479 | &addr_cb, NULL, ret); | ||
480 | } | 439 | } |
440 | ret->nat = GNUNET_NAT_register (cfg, is_tcp, | ||
441 | adv_port, | ||
442 | 1, addrs, addrlens, &addr_cb, NULL, ret); | ||
443 | } | ||
481 | return ret; | 444 | return ret; |
482 | } | 445 | } |
483 | 446 | ||
@@ -494,22 +457,18 @@ GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst) | |||
494 | struct ClientActivity *cpos; | 457 | struct ClientActivity *cpos; |
495 | 458 | ||
496 | while (NULL != (cpos = tst->ca_head)) | 459 | while (NULL != (cpos = tst->ca_head)) |
497 | { | 460 | { |
498 | GNUNET_CONTAINER_DLL_remove (tst->ca_head, | 461 | GNUNET_CONTAINER_DLL_remove (tst->ca_head, tst->ca_tail, cpos); |
499 | tst->ca_tail, | 462 | GNUNET_CLIENT_disconnect (cpos->client, GNUNET_NO); |
500 | cpos); | 463 | GNUNET_free (cpos); |
501 | GNUNET_CLIENT_disconnect (cpos->client, GNUNET_NO); | 464 | } |
502 | GNUNET_free (cpos); | ||
503 | } | ||
504 | while (NULL != (pos = tst->na_head)) | 465 | while (NULL != (pos = tst->na_head)) |
505 | { | 466 | { |
506 | GNUNET_CONTAINER_DLL_remove (tst->na_head, | 467 | GNUNET_CONTAINER_DLL_remove (tst->na_head, tst->na_tail, pos); |
507 | tst->na_tail, | 468 | GNUNET_SCHEDULER_cancel (pos->rtask); |
508 | pos); | 469 | GNUNET_NETWORK_socket_close (pos->sock); |
509 | GNUNET_SCHEDULER_cancel (pos->rtask); | 470 | GNUNET_free (pos); |
510 | GNUNET_NETWORK_socket_close (pos->sock); | 471 | } |
511 | GNUNET_free (pos); | ||
512 | } | ||
513 | if (GNUNET_SCHEDULER_NO_TASK != tst->ltask) | 472 | if (GNUNET_SCHEDULER_NO_TASK != tst->ltask) |
514 | GNUNET_SCHEDULER_cancel (tst->ltask); | 473 | GNUNET_SCHEDULER_cancel (tst->ltask); |
515 | if (NULL != tst->lsock) | 474 | if (NULL != tst->lsock) |
diff --git a/src/nat/test_nat.c b/src/nat/test_nat.c index c58d83224..12ff30cac 100644 --- a/src/nat/test_nat.c +++ b/src/nat/test_nat.c | |||
@@ -58,11 +58,10 @@ static void | |||
58 | addr_callback (void *cls, int add_remove, | 58 | addr_callback (void *cls, int add_remove, |
59 | const struct sockaddr *addr, socklen_t addrlen) | 59 | const struct sockaddr *addr, socklen_t addrlen) |
60 | { | 60 | { |
61 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 61 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
62 | "Address changed: %s `%s' (%u bytes)\n", | 62 | "Address changed: %s `%s' (%u bytes)\n", |
63 | add_remove == GNUNET_YES ? "added" : "removed", | 63 | add_remove == GNUNET_YES ? "added" : "removed", |
64 | GNUNET_a2s (addr, addrlen), | 64 | GNUNET_a2s (addr, addrlen), (unsigned int) addrlen); |
65 | (unsigned int) addrlen); | ||
66 | } | 65 | } |
67 | 66 | ||
68 | 67 | ||
@@ -74,8 +73,7 @@ stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
74 | { | 73 | { |
75 | struct GNUNET_NAT_Handle *nat = cls; | 74 | struct GNUNET_NAT_Handle *nat = cls; |
76 | 75 | ||
77 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 76 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n"); |
78 | "Stopping NAT and quitting...\n"); | ||
79 | GNUNET_NAT_unregister (nat); | 77 | GNUNET_NAT_unregister (nat); |
80 | } | 78 | } |
81 | 79 | ||
@@ -132,11 +130,11 @@ run (void *cls, | |||
132 | data.addr = NULL; | 130 | data.addr = NULL; |
133 | GNUNET_OS_network_interfaces_list (process_if, &data); | 131 | GNUNET_OS_network_interfaces_list (process_if, &data); |
134 | if (NULL == data.addr) | 132 | if (NULL == data.addr) |
135 | { | 133 | { |
136 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 134 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
137 | "Could not find a valid interface address!\n"); | 135 | "Could not find a valid interface address!\n"); |
138 | exit (GNUNET_SYSERR); | 136 | exit (GNUNET_SYSERR); |
139 | } | 137 | } |
140 | addr = data.addr; | 138 | addr = data.addr; |
141 | GNUNET_assert (addr->sa_family == AF_INET || addr->sa_family == AF_INET6); | 139 | GNUNET_assert (addr->sa_family == AF_INET || addr->sa_family == AF_INET6); |
142 | if (addr->sa_family == AF_INET) | 140 | if (addr->sa_family == AF_INET) |
@@ -148,13 +146,11 @@ run (void *cls, | |||
148 | "Requesting NAT redirection from address %s...\n", | 146 | "Requesting NAT redirection from address %s...\n", |
149 | GNUNET_a2s (addr, data.addrlen)); | 147 | GNUNET_a2s (addr, data.addrlen)); |
150 | 148 | ||
151 | nat = GNUNET_NAT_register (cfg, | 149 | nat = GNUNET_NAT_register (cfg, GNUNET_YES /* tcp */ , |
152 | GNUNET_YES /* tcp */, | 150 | 2086, |
153 | 2086, | 151 | 1, |
154 | 1, | 152 | (const struct sockaddr **) &addr, |
155 | (const struct sockaddr**) &addr, | 153 | &data.addrlen, &addr_callback, NULL, NULL); |
156 | &data.addrlen, | ||
157 | &addr_callback, NULL, NULL); | ||
158 | GNUNET_free (addr); | 154 | GNUNET_free (addr); |
159 | GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, nat); | 155 | GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, nat); |
160 | } | 156 | } |
diff --git a/src/nat/test_nat_mini.c b/src/nat/test_nat_mini.c index a8381e497..8f689d6bc 100644 --- a/src/nat/test_nat_mini.c +++ b/src/nat/test_nat_mini.c | |||
@@ -50,10 +50,9 @@ addr_callback (void *cls, int add_remove, | |||
50 | const struct sockaddr *addr, socklen_t addrlen) | 50 | const struct sockaddr *addr, socklen_t addrlen) |
51 | { | 51 | { |
52 | fprintf (stderr, | 52 | fprintf (stderr, |
53 | "Address changed: %s `%s' (%u bytes)\n", | 53 | "Address changed: %s `%s' (%u bytes)\n", |
54 | add_remove == GNUNET_YES ? "added" : "removed", | 54 | add_remove == GNUNET_YES ? "added" : "removed", |
55 | GNUNET_a2s (addr, addrlen), | 55 | GNUNET_a2s (addr, addrlen), (unsigned int) addrlen); |
56 | (unsigned int) addrlen); | ||
57 | } | 56 | } |
58 | 57 | ||
59 | 58 | ||
@@ -65,8 +64,7 @@ stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
65 | { | 64 | { |
66 | struct GNUNET_NAT_MiniHandle *mini = cls; | 65 | struct GNUNET_NAT_MiniHandle *mini = cls; |
67 | 66 | ||
68 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 67 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n"); |
69 | "Stopping NAT and quitting...\n"); | ||
70 | GNUNET_NAT_mini_map_stop (mini); | 68 | GNUNET_NAT_mini_map_stop (mini); |
71 | } | 69 | } |
72 | 70 | ||
@@ -83,17 +81,14 @@ run (void *cls, | |||
83 | struct GNUNET_NAT_MiniHandle *mini; | 81 | struct GNUNET_NAT_MiniHandle *mini; |
84 | 82 | ||
85 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 83 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
86 | "Requesting NAT redirection for port %u...\n", | 84 | "Requesting NAT redirection for port %u...\n", PORT); |
87 | PORT); | 85 | mini = GNUNET_NAT_mini_map_start (PORT, GNUNET_YES /* tcp */ , |
88 | mini = GNUNET_NAT_mini_map_start (PORT, | 86 | &addr_callback, NULL); |
89 | GNUNET_YES /* tcp */, | ||
90 | &addr_callback, NULL); | ||
91 | if (NULL == mini) | 87 | if (NULL == mini) |
92 | { | 88 | { |
93 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 89 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Could not start UPnP interaction\n"); |
94 | "Could not start UPnP interaction\n"); | 90 | return; |
95 | return; | 91 | } |
96 | } | ||
97 | GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, mini); | 92 | GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, mini); |
98 | } | 93 | } |
99 | 94 | ||
@@ -127,9 +122,10 @@ main (int argc, char *const argv[]) | |||
127 | NULL); | 122 | NULL); |
128 | 123 | ||
129 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 124 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
130 | "UPnP test for NAT library, timeout set to %d seconds\n", TIMEOUT); | 125 | "UPnP test for NAT library, timeout set to %d seconds\n", |
131 | GNUNET_PROGRAM_run (5, argv_prog, "test-nat-mini", | 126 | TIMEOUT); |
132 | "nohelp", options, &run, NULL); | 127 | GNUNET_PROGRAM_run (5, argv_prog, "test-nat-mini", "nohelp", options, &run, |
128 | NULL); | ||
133 | return 0; | 129 | return 0; |
134 | } | 130 | } |
135 | 131 | ||
diff --git a/src/nat/test_nat_test.c b/src/nat/test_nat_test.c index 32c4fb2d8..520d82d92 100644 --- a/src/nat/test_nat_test.c +++ b/src/nat/test_nat_test.c | |||
@@ -47,15 +47,13 @@ static struct GNUNET_NAT_Test *tst; | |||
47 | static GNUNET_SCHEDULER_TaskIdentifier end; | 47 | static GNUNET_SCHEDULER_TaskIdentifier end; |
48 | 48 | ||
49 | static void | 49 | static void |
50 | end_test (void *cls, | 50 | end_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
51 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
52 | { | 51 | { |
53 | GNUNET_NAT_test_stop (tst); | 52 | GNUNET_NAT_test_stop (tst); |
54 | } | 53 | } |
55 | 54 | ||
56 | static void | 55 | static void |
57 | report_success (void *cls, | 56 | report_success (void *cls, int success) |
58 | int success) | ||
59 | { | 57 | { |
60 | GNUNET_assert (GNUNET_OK == success); | 58 | GNUNET_assert (GNUNET_OK == success); |
61 | ret = 0; | 59 | ret = 0; |
@@ -72,13 +70,10 @@ run (void *cls, | |||
72 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) | 70 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) |
73 | { | 71 | { |
74 | tst = GNUNET_NAT_test_start (cfg, GNUNET_YES, | 72 | tst = GNUNET_NAT_test_start (cfg, GNUNET_YES, |
75 | 1285, 1285, | 73 | 1285, 1285, &report_success, NULL); |
76 | &report_success, NULL); | ||
77 | if (NULL == tst) | 74 | if (NULL == tst) |
78 | return; | 75 | return; |
79 | end = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 76 | end = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_test, NULL); |
80 | &end_test, | ||
81 | NULL); | ||
82 | } | 77 | } |
83 | 78 | ||
84 | 79 | ||
@@ -89,6 +84,7 @@ main (int argc, char *const argv[]) | |||
89 | GNUNET_GETOPT_OPTION_END | 84 | GNUNET_GETOPT_OPTION_END |
90 | }; | 85 | }; |
91 | struct GNUNET_OS_Process *gns; | 86 | struct GNUNET_OS_Process *gns; |
87 | |||
92 | char *const argv_prog[] = { | 88 | char *const argv_prog[] = { |
93 | "test-nat-test", | 89 | "test-nat-test", |
94 | "-c", | 90 | "-c", |
@@ -110,23 +106,17 @@ main (int argc, char *const argv[]) | |||
110 | #endif | 106 | #endif |
111 | NULL); | 107 | NULL); |
112 | gns = GNUNET_OS_start_process (NULL, NULL, | 108 | gns = GNUNET_OS_start_process (NULL, NULL, |
113 | "gnunet-nat-server", | 109 | "gnunet-nat-server", "gnunet-nat-server", |
114 | "gnunet-nat-server", | ||
115 | #if VERBOSE | 110 | #if VERBOSE |
116 | "-L", | 111 | "-L", "DEBUG", |
117 | "DEBUG", | ||
118 | #endif | 112 | #endif |
119 | "-c", "test_nat_test_data.conf", | 113 | "-c", "test_nat_test_data.conf", |
120 | "12345", | 114 | "12345", NULL); |
121 | NULL); | ||
122 | GNUNET_assert (NULL != gns); | 115 | GNUNET_assert (NULL != gns); |
123 | GNUNET_PROGRAM_run (5, argv_prog, | 116 | GNUNET_PROGRAM_run (5, argv_prog, |
124 | "test-nat-test", "nohelp", | 117 | "test-nat-test", "nohelp", options, &run, NULL); |
125 | options, | ||
126 | &run, NULL); | ||
127 | GNUNET_break (0 == GNUNET_OS_process_kill (gns, SIGTERM)); | 118 | GNUNET_break (0 == GNUNET_OS_process_kill (gns, SIGTERM)); |
128 | GNUNET_break (GNUNET_OK == | 119 | GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (gns)); |
129 | GNUNET_OS_process_wait (gns)); | ||
130 | GNUNET_OS_process_close (gns); | 120 | GNUNET_OS_process_close (gns); |
131 | return ret; | 121 | return ret; |
132 | } | 122 | } |