aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-09-08 12:33:09 +0000
committerng0 <ng0@n0.is>2019-09-08 12:33:09 +0000
commitd41ed82a4ea0cc8e1674b6d5d2c49fd6462610bb (patch)
tree9efd18ea7d425652085ed0bd5e8e45604bc5f6b9 /src/vpn
parenta0fce305c565c0937d917a92712f15e9c5736260 (diff)
downloadgnunet-d41ed82a4ea0cc8e1674b6d5d2c49fd6462610bb.tar.gz
gnunet-d41ed82a4ea0cc8e1674b6d5d2c49fd6462610bb.zip
uncrustify as demanded.
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-helper-vpn-windows.c1106
-rw-r--r--src/vpn/gnunet-helper-vpn.c897
-rw-r--r--src/vpn/gnunet-service-vpn.c3814
-rw-r--r--src/vpn/gnunet-vpn.c375
-rw-r--r--src/vpn/vpn.h17
-rw-r--r--src/vpn/vpn_api.c339
6 files changed, 3304 insertions, 3244 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index 17f32c5a8..afa4fa139 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-windows.c
@@ -11,7 +11,7 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
@@ -66,7 +66,7 @@
66 66
67#if DEBUG 67#if DEBUG
68/* FIXME: define with varargs... */ 68/* FIXME: define with varargs... */
69#define LOG_DEBUG(msg) fprintf (stderr, "%s", msg); 69#define LOG_DEBUG(msg) fprintf(stderr, "%s", msg);
70#else 70#else
71#define LOG_DEBUG(msg) do {} while (0) 71#define LOG_DEBUG(msg) do {} while (0)
72#endif 72#endif
@@ -162,9 +162,7 @@ static char device_guid[256];
162/** 162/**
163 * Possible states of an IO facility. 163 * Possible states of an IO facility.
164 */ 164 */
165enum IO_State 165enum IO_State {
166{
167
168 /** 166 /**
169 * overlapped I/O is ready for work 167 * overlapped I/O is ready for work
170 */ 168 */
@@ -190,15 +188,13 @@ enum IO_State
190 * overlapped I/O has failed, stop processing 188 * overlapped I/O has failed, stop processing
191 */ 189 */
192 IOSTATE_FAILED 190 IOSTATE_FAILED
193
194}; 191};
195 192
196 193
197/** 194/**
198 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling 195 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling
199 */ 196 */
200struct io_facility 197struct io_facility {
201{
202 /** 198 /**
203 * The mode the state machine associated with this object is in. 199 * The mode the state machine associated with this object is in.
204 */ 200 */
@@ -243,12 +239,12 @@ struct io_facility
243/** 239/**
244 * ReOpenFile is only available as of XP SP2 and 2003 SP1 240 * ReOpenFile is only available as of XP SP2 and 2003 SP1
245 */ 241 */
246WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD); 242WINBASEAPI HANDLE WINAPI ReOpenFile(HANDLE, DWORD, DWORD, DWORD);
247 243
248/** 244/**
249 * IsWow64Process definition for our is_win64, as this is a kernel function 245 * IsWow64Process definition for our is_win64, as this is a kernel function
250 */ 246 */
251typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); 247typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
252 248
253 249
254/** 250/**
@@ -261,7 +257,7 @@ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
261 * @param n the length of the string to copy, including its terminating null 257 * @param n the length of the string to copy, including its terminating null
262 * byte 258 * byte
263 * @return the length of the string that was copied, excluding the terminating 259 * @return the length of the string that was copied, excluding the terminating
264 * null byte 260 * null byte
265 */ 261 */
266size_t 262size_t
267GNUNET_strlcpy(char *dst, const char *src, size_t n) 263GNUNET_strlcpy(char *dst, const char *src, size_t n)
@@ -269,9 +265,9 @@ GNUNET_strlcpy(char *dst, const char *src, size_t n)
269 size_t ret; 265 size_t ret;
270 size_t slen; 266 size_t slen;
271 267
272 GNUNET_assert (0 != n); 268 GNUNET_assert(0 != n);
273 slen = strnlen (src, n - 1); 269 slen = strnlen(src, n - 1);
274 memcpy (dst, src, slen); 270 memcpy(dst, src, slen);
275 dst[slen] = '\0'; 271 dst[slen] = '\0';
276 return slen; 272 return slen;
277} 273}
@@ -283,7 +279,7 @@ GNUNET_strlcpy(char *dst, const char *src, size_t n)
283 * @return true if 279 * @return true if
284 */ 280 */
285BOOL 281BOOL
286is_win64 () 282is_win64()
287{ 283{
288#if defined(_WIN64) 284#if defined(_WIN64)
289 //this is a win64 binary, 285 //this is a win64 binary,
@@ -292,10 +288,10 @@ is_win64 ()
292 //this is a 32bit binary, and we need to check if we are running in WOW64 288 //this is a 32bit binary, and we need to check if we are running in WOW64
293 BOOL success = FALSE; 289 BOOL success = FALSE;
294 BOOL on_wow64 = FALSE; 290 BOOL on_wow64 = FALSE;
295 LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle ("kernel32"), "IsWow64Process"); 291 LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
296 292
297 if (NULL != IsWow64Process) 293 if (NULL != IsWow64Process)
298 success = IsWow64Process (GetCurrentProcess (), &on_wow64); 294 success = IsWow64Process(GetCurrentProcess(), &on_wow64);
299 295
300 return success && on_wow64; 296 return success && on_wow64;
301#endif 297#endif
@@ -309,22 +305,22 @@ is_win64 ()
309 * * EPIPE (could not read STDOUT) 305 * * EPIPE (could not read STDOUT)
310 */ 306 */
311static int 307static int
312execute_shellcommand (const char *command) 308execute_shellcommand(const char *command)
313{ 309{
314 FILE *pipe; 310 FILE *pipe;
315 311
316 if ( (NULL == command) || 312 if ((NULL == command) ||
317 (NULL == (pipe = _popen (command, "rt"))) ) 313 (NULL == (pipe = _popen(command, "rt"))))
318 return EINVAL; 314 return EINVAL;
319 315
320#if DEBUG 316#if DEBUG
321 fprintf (stderr, "DEBUG: Command output: \n"); 317 fprintf(stderr, "DEBUG: Command output: \n");
322 char output[LINE_LEN]; 318 char output[LINE_LEN];
323 while (NULL != fgets (output, sizeof (output), pipe)) 319 while (NULL != fgets(output, sizeof(output), pipe))
324 fprintf (stderr, "%s", output); 320 fprintf(stderr, "%s", output);
325#endif 321#endif
326 322
327 return _pclose (pipe); 323 return _pclose(pipe);
328} 324}
329 325
330 326
@@ -335,7 +331,7 @@ execute_shellcommand (const char *command)
335 * @param prefix_len the length of the network-prefix 331 * @param prefix_len the length of the network-prefix
336 */ 332 */
337static int 333static int
338set_address6 (const char *address, unsigned long prefix_len) 334set_address6(const char *address, unsigned long prefix_len)
339{ 335{
340 int ret = EINVAL; 336 int ret = EINVAL;
341 char command[LINE_LEN]; 337 char command[LINE_LEN];
@@ -344,29 +340,29 @@ set_address6 (const char *address, unsigned long prefix_len)
344 /* 340 /*
345 * parse the new address 341 * parse the new address
346 */ 342 */
347 memset (&sa6, 0, sizeof (struct sockaddr_in6)); 343 memset(&sa6, 0, sizeof(struct sockaddr_in6));
348 sa6.sin6_family = AF_INET6; 344 sa6.sin6_family = AF_INET6;
349 if (1 != inet_pton (AF_INET6, address, &sa6.sin6_addr.s6_addr)) 345 if (1 != inet_pton(AF_INET6, address, &sa6.sin6_addr.s6_addr))
350 { 346 {
351 fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address, 347 fprintf(stderr, "ERROR: Failed to parse address `%s': %s\n", address,
352 strerror (errno)); 348 strerror(errno));
353 return -1; 349 return -1;
354 } 350 }
355 351
356 /* 352 /*
357 * prepare the command 353 * prepare the command
358 */ 354 */
359 snprintf (command, LINE_LEN, 355 snprintf(command, LINE_LEN,
360 "netsh interface ipv6 add address \"%s\" %s/%d store=active", 356 "netsh interface ipv6 add address \"%s\" %s/%d store=active",
361 device_visible_name, address, prefix_len); 357 device_visible_name, address, prefix_len);
362 /* 358 /*
363 * Set the address 359 * Set the address
364 */ 360 */
365 ret = execute_shellcommand (command); 361 ret = execute_shellcommand(command);
366 362
367 /* Did it work?*/ 363 /* Did it work?*/
368 if (0 != ret) 364 if (0 != ret)
369 fprintf (stderr, "FATAL: Setting IPv6 address failed: %s\n", strerror (ret)); 365 fprintf(stderr, "FATAL: Setting IPv6 address failed: %s\n", strerror(ret));
370 return ret; 366 return ret;
371} 367}
372 368
@@ -377,7 +373,7 @@ set_address6 (const char *address, unsigned long prefix_len)
377 * @param address the IPv4-Address 373 * @param address the IPv4-Address
378 */ 374 */
379static void 375static void
380remove_address6 (const char *address) 376remove_address6(const char *address)
381{ 377{
382 char command[LINE_LEN]; 378 char command[LINE_LEN];
383 int ret = EINVAL; 379 int ret = EINVAL;
@@ -386,19 +382,19 @@ remove_address6 (const char *address)
386 /* 382 /*
387 * prepare the command 383 * prepare the command
388 */ 384 */
389 snprintf (command, LINE_LEN, 385 snprintf(command, LINE_LEN,
390 "netsh interface ipv6 delete address \"%s\" store=persistent", 386 "netsh interface ipv6 delete address \"%s\" store=persistent",
391 device_visible_name); 387 device_visible_name);
392 /* 388 /*
393 * Set the address 389 * Set the address
394 */ 390 */
395 ret = execute_shellcommand (command); 391 ret = execute_shellcommand(command);
396 392
397 /* Did it work?*/ 393 /* Did it work?*/
398 if (0 != ret) 394 if (0 != ret)
399 fprintf (stderr, 395 fprintf(stderr,
400 "FATAL: removing IPv6 address failed: %s\n", 396 "FATAL: removing IPv6 address failed: %s\n",
401 strerror (ret)); 397 strerror(ret));
402} 398}
403 399
404 400
@@ -409,21 +405,22 @@ remove_address6 (const char *address)
409 * @param mask the netmask 405 * @param mask the netmask
410 */ 406 */
411static int 407static int
412set_address4 (const char *address, const char *mask) 408set_address4(const char *address, const char *mask)
413{ 409{
414 int ret = EINVAL; 410 int ret = EINVAL;
415 char command[LINE_LEN]; 411 char command[LINE_LEN];
416 412
417 struct sockaddr_in addr; 413 struct sockaddr_in addr;
414
418 addr.sin_family = AF_INET; 415 addr.sin_family = AF_INET;
419 416
420 /* 417 /*
421 * Parse the address 418 * Parse the address
422 */ 419 */
423 if (1 != inet_pton (AF_INET, address, &addr.sin_addr.s_addr)) 420 if (1 != inet_pton(AF_INET, address, &addr.sin_addr.s_addr))
424 { 421 {
425 fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address, 422 fprintf(stderr, "ERROR: Failed to parse address `%s': %s\n", address,
426 strerror (errno)); 423 strerror(errno));
427 return -1; 424 return -1;
428 } 425 }
429 // Set Device to Subnet-Mode? do we really need openvpn/tun.c:2925 ? 426 // Set Device to Subnet-Mode? do we really need openvpn/tun.c:2925 ?
@@ -431,19 +428,19 @@ set_address4 (const char *address, const char *mask)
431 /* 428 /*
432 * prepare the command 429 * prepare the command
433 */ 430 */
434 snprintf (command, LINE_LEN, 431 snprintf(command, LINE_LEN,
435 "netsh interface ipv4 add address \"%s\" %s %s store=active", 432 "netsh interface ipv4 add address \"%s\" %s %s store=active",
436 device_visible_name, address, mask); 433 device_visible_name, address, mask);
437 /* 434 /*
438 * Set the address 435 * Set the address
439 */ 436 */
440 ret = execute_shellcommand (command); 437 ret = execute_shellcommand(command);
441 438
442 /* Did it work?*/ 439 /* Did it work?*/
443 if (0 != ret) 440 if (0 != ret)
444 fprintf (stderr, 441 fprintf(stderr,
445 "FATAL: Setting IPv4 address failed: %s\n", 442 "FATAL: Setting IPv4 address failed: %s\n",
446 strerror (ret)); 443 strerror(ret));
447 return ret; 444 return ret;
448} 445}
449 446
@@ -454,7 +451,7 @@ set_address4 (const char *address, const char *mask)
454 * @param address the IPv4-Address 451 * @param address the IPv4-Address
455 */ 452 */
456static void 453static void
457remove_address4 (const char *address) 454remove_address4(const char *address)
458{ 455{
459 char command[LINE_LEN]; 456 char command[LINE_LEN];
460 int ret = EINVAL; 457 int ret = EINVAL;
@@ -464,17 +461,17 @@ remove_address4 (const char *address)
464 /* 461 /*
465 * prepare the command 462 * prepare the command
466 */ 463 */
467 snprintf (command, LINE_LEN, 464 snprintf(command, LINE_LEN,
468 "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent", 465 "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent",
469 device_visible_name); 466 device_visible_name);
470 /* 467 /*
471 * Set the address 468 * Set the address
472 */ 469 */
473 ret = execute_shellcommand (command); 470 ret = execute_shellcommand(command);
474 471
475 /* Did it work?*/ 472 /* Did it work?*/
476 if (0 != ret) 473 if (0 != ret)
477 fprintf (stderr, "FATAL: removing IPv4 address failed: %s\n", strerror (ret)); 474 fprintf(stderr, "FATAL: removing IPv4 address failed: %s\n", strerror(ret));
478} 475}
479 476
480 477
@@ -484,7 +481,7 @@ remove_address4 (const char *address)
484 * @return: TRUE if setup was successful, else FALSE 481 * @return: TRUE if setup was successful, else FALSE
485 */ 482 */
486static BOOL 483static BOOL
487setup_interface () 484setup_interface()
488{ 485{
489 /* 486 /*
490 * where to find our inf-file. (+ the "full" path, after windows found") 487 * where to find our inf-file. (+ the "full" path, after windows found")
@@ -503,19 +500,19 @@ setup_interface ()
503 * Set the device's hardware ID and add it to a list. 500 * Set the device's hardware ID and add it to a list.
504 * This information will later on identify this device in registry. 501 * This information will later on identify this device in registry.
505 */ 502 */
506 str_len = GNUNET_strlcpy (hwidlist, 503 str_len = GNUNET_strlcpy(hwidlist,
507 HARDWARE_ID, 504 HARDWARE_ID,
508 sizeof (hwidList)) + 1; 505 sizeof(hwidList)) + 1;
509 /** 506 /**
510 * this is kind of over-complicated, but allows keeps things independent of 507 * this is kind of over-complicated, but allows keeps things independent of
511 * how the openvpn-hwid is actually stored. 508 * how the openvpn-hwid is actually stored.
512 * 509 *
513 * A HWID list is double-\0 terminated and \0 separated 510 * A HWID list is double-\0 terminated and \0 separated
514 */ 511 */
515 str_len += GNUNET_strlcpy (&hwidlist[str_length], 512 str_len += GNUNET_strlcpy(&hwidlist[str_length],
516 secondary_hwid, 513 secondary_hwid,
517 sizeof (hwidlist) - str_len) + 1; 514 sizeof(hwidlist) - str_len) + 1;
518 GNUNET_assert (str_len < sizeof (hwidlist)); 515 GNUNET_assert(str_len < sizeof(hwidlist));
519 hwidlist[str_len] = '\0'; 516 hwidlist[str_len] = '\0';
520 ++str_len; 517 ++str_len;
521 518
@@ -524,62 +521,62 @@ setup_interface ()
524 * find it. We need to pick the correct driver for win32/win64. 521 * find it. We need to pick the correct driver for win32/win64.
525 */ 522 */
526 if (is_win64()) 523 if (is_win64())
527 GetFullPathNameA (INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename); 524 GetFullPathNameA(INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename);
528 else 525 else
529 GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); 526 GetFullPathNameA(INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename);
530 527
531 fprintf (stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path); 528 fprintf(stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path);
532 /** 529 /**
533 * Bootstrap our device info using the drivers inf-file 530 * Bootstrap our device info using the drivers inf-file
534 */ 531 */
535 if ( ! SetupDiGetINFClassA (inf_file_path, 532 if (!SetupDiGetINFClassA(inf_file_path,
536 &class_guid, 533 &class_guid,
537 class_name, sizeof (class_name) / sizeof (char), 534 class_name, sizeof(class_name) / sizeof(char),
538 NULL)) 535 NULL))
539 return FALSE; 536 return FALSE;
540 537
541 /** 538 /**
542 * Collect all the other needed information... 539 * Collect all the other needed information...
543 * let the system fill our this form 540 * let the system fill our this form
544 */ 541 */
545 DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); 542 DeviceInfo = SetupDiCreateDeviceInfoList(&class_guid, NULL);
546 if (DeviceInfo == INVALID_HANDLE_VALUE) 543 if (DeviceInfo == INVALID_HANDLE_VALUE)
547 return FALSE; 544 return FALSE;
548 545
549 DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); 546 DeviceNode.cbSize = sizeof(SP_DEVINFO_DATA);
550 if ( ! SetupDiCreateDeviceInfoA (DeviceInfo, 547 if (!SetupDiCreateDeviceInfoA(DeviceInfo,
551 class_name, 548 class_name,
552 &class_guid, 549 &class_guid,
553 NULL, 550 NULL,
554 0, 551 0,
555 DICD_GENERATE_ID, 552 DICD_GENERATE_ID,
556 &DeviceNode)) 553 &DeviceNode))
557 return FALSE; 554 return FALSE;
558 555
559 /* Deploy all the information collected into the registry */ 556 /* Deploy all the information collected into the registry */
560 if ( ! SetupDiSetDeviceRegistryPropertyA (DeviceInfo, 557 if (!SetupDiSetDeviceRegistryPropertyA(DeviceInfo,
561 &DeviceNode, 558 &DeviceNode,
562 SPDRP_HARDWAREID, 559 SPDRP_HARDWAREID,
563 (LPBYTE) hwidlist, 560 (LPBYTE)hwidlist,
564 str_length * sizeof (char))) 561 str_length * sizeof(char)))
565 return FALSE; 562 return FALSE;
566 563
567 /* Install our new class(=device) into the system */ 564 /* Install our new class(=device) into the system */
568 if ( ! SetupDiCallClassInstaller (DIF_REGISTERDEVICE, 565 if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
569 DeviceInfo, 566 DeviceInfo,
570 &DeviceNode)) 567 &DeviceNode))
571 return FALSE; 568 return FALSE;
572 569
573 /* This system call tends to take a while (several seconds!) on 570 /* This system call tends to take a while (several seconds!) on
574 "modern" Windoze systems */ 571 "modern" Windoze systems */
575 if ( ! UpdateDriverForPlugAndPlayDevicesA (NULL, 572 if (!UpdateDriverForPlugAndPlayDevicesA(NULL,
576 secondary_hwid, 573 secondary_hwid,
577 inf_file_path, 574 inf_file_path,
578 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, 575 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE,
579 NULL)) //reboot required? NEVER! 576 NULL)) //reboot required? NEVER!
580 return FALSE; 577 return FALSE;
581 578
582 fprintf (stderr, "DEBUG: successfully created a network device\n"); 579 fprintf(stderr, "DEBUG: successfully created a network device\n");
583 return TRUE; 580 return TRUE;
584} 581}
585 582
@@ -591,14 +588,14 @@ setup_interface ()
591 * @return: TRUE if destruction was successful, else FALSE 588 * @return: TRUE if destruction was successful, else FALSE
592 */ 589 */
593static BOOL 590static BOOL
594remove_interface () 591remove_interface()
595{ 592{
596 SP_REMOVEDEVICE_PARAMS remove; 593 SP_REMOVEDEVICE_PARAMS remove;
597 594
598 if (INVALID_HANDLE_VALUE == DeviceInfo) 595 if (INVALID_HANDLE_VALUE == DeviceInfo)
599 return FALSE; 596 return FALSE;
600 597
601 remove.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER); 598 remove.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
602 remove.HwProfile = 0; 599 remove.HwProfile = 0;
603 remove.Scope = DI_REMOVEDEVICE_GLOBAL; 600 remove.Scope = DI_REMOVEDEVICE_GLOBAL;
604 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE; 601 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE;
@@ -606,22 +603,22 @@ remove_interface ()
606 * 1. Prepare our existing device information set, and place the 603 * 1. Prepare our existing device information set, and place the
607 * uninstall related information into the structure 604 * uninstall related information into the structure
608 */ 605 */
609 if ( ! SetupDiSetClassInstallParamsA (DeviceInfo, 606 if (!SetupDiSetClassInstallParamsA(DeviceInfo,
610 (PSP_DEVINFO_DATA) & DeviceNode, 607 (PSP_DEVINFO_DATA)&DeviceNode,
611 &remove.ClassInstallHeader, 608 &remove.ClassInstallHeader,
612 sizeof (remove))) 609 sizeof(remove)))
613 return FALSE; 610 return FALSE;
614 /* 611 /*
615 * 2. Uninstall the virtual interface using the class installer 612 * 2. Uninstall the virtual interface using the class installer
616 */ 613 */
617 if ( ! SetupDiCallClassInstaller (DIF_REMOVE, 614 if (!SetupDiCallClassInstaller(DIF_REMOVE,
618 DeviceInfo, 615 DeviceInfo,
619 (PSP_DEVINFO_DATA) & DeviceNode)) 616 (PSP_DEVINFO_DATA)&DeviceNode))
620 return FALSE; 617 return FALSE;
621 618
622 SetupDiDestroyDeviceInfoList (DeviceInfo); 619 SetupDiDestroyDeviceInfoList(DeviceInfo);
623 620
624 fprintf (stderr, "DEBUG: removed interface successfully\n"); 621 fprintf(stderr, "DEBUG: removed interface successfully\n");
625 622
626 return TRUE; 623 return TRUE;
627} 624}
@@ -634,7 +631,7 @@ remove_interface ()
634 * @return: TRUE if we were able to lookup the interface's name, else FALSE 631 * @return: TRUE if we were able to lookup the interface's name, else FALSE
635 */ 632 */
636static BOOL 633static BOOL
637resolve_interface_name () 634resolve_interface_name()
638{ 635{
639 SP_DEVINFO_LIST_DETAIL_DATA device_details; 636 SP_DEVINFO_LIST_DETAIL_DATA device_details;
640 char pnp_instance_id [MAX_DEVICE_ID_LEN]; 637 char pnp_instance_id [MAX_DEVICE_ID_LEN];
@@ -647,29 +644,29 @@ resolve_interface_name ()
647 char adapter[] = INTERFACE_REGISTRY_LOCATION; 644 char adapter[] = INTERFACE_REGISTRY_LOCATION;
648 645
649 /* We can obtain the PNP instance ID from our setupapi handle */ 646 /* We can obtain the PNP instance ID from our setupapi handle */
650 device_details.cbSize = sizeof (device_details); 647 device_details.cbSize = sizeof(device_details);
651 if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst, 648 if (CR_SUCCESS != CM_Get_Device_ID_ExA(DeviceNode.DevInst,
652 (PCHAR) pnp_instance_id, 649 (PCHAR)pnp_instance_id,
653 MAX_DEVICE_ID_LEN, 650 MAX_DEVICE_ID_LEN,
654 0, //must be 0 651 0, //must be 0
655 NULL)) //hMachine, we are local 652 NULL)) //hMachine, we are local
656 return FALSE; 653 return FALSE;
657 654
658 fprintf (stderr, "DEBUG: Resolving interface name for network device %s\n",pnp_instance_id); 655 fprintf(stderr, "DEBUG: Resolving interface name for network device %s\n", pnp_instance_id);
659 656
660 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */ 657 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */
661 for (retrys = 0; retrys < 120 && !retval; retrys++) 658 for (retrys = 0; retrys < 120 && !retval; retrys++)
662 { 659 {
663 /* sleep for 250ms*/ 660 /* sleep for 250ms*/
664 Sleep (250); 661 Sleep(250);
665 662
666 /* Now we can use this ID to locate the correct networks interface in registry */ 663 /* Now we can use this ID to locate the correct networks interface in registry */
667 if (ERROR_SUCCESS != RegOpenKeyExA ( 664 if (ERROR_SUCCESS != RegOpenKeyExA(
668 HKEY_LOCAL_MACHINE, 665 HKEY_LOCAL_MACHINE,
669 adapter, 666 adapter,
670 0, 667 0,
671 KEY_READ, 668 KEY_READ,
672 &adapter_key_handle)) 669 &adapter_key_handle))
673 return FALSE; 670 return FALSE;
674 671
675 /* Of course there is a multitude of entries here, with arbitrary names, 672 /* Of course there is a multitude of entries here, with arbitrary names,
@@ -685,17 +682,17 @@ resolve_interface_name ()
685 char adaptername_name[] = "Name"; 682 char adaptername_name[] = "Name";
686 DWORD data_type; 683 DWORD data_type;
687 684
688 len = 256 * sizeof (char); 685 len = 256 * sizeof(char);
689 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ 686 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */
690 status = RegEnumKeyExA ( 687 status = RegEnumKeyExA(
691 adapter_key_handle, 688 adapter_key_handle,
692 i, 689 i,
693 instance_key, 690 instance_key,
694 &len, 691 &len,
695 NULL, 692 NULL,
696 NULL, 693 NULL,
697 NULL, 694 NULL,
698 NULL); 695 NULL);
699 696
700 /* this may fail due to one of two reasons: 697 /* this may fail due to one of two reasons:
701 * we are at the end of the list*/ 698 * we are at the end of the list*/
@@ -706,44 +703,44 @@ resolve_interface_name ()
706 goto cleanup; 703 goto cleanup;
707 704
708 /* prepare our new query string: */ 705 /* prepare our new query string: */
709 snprintf (query_key, 256, "%s\\%s\\Connection", 706 snprintf(query_key, 256, "%s\\%s\\Connection",
710 adapter, 707 adapter,
711 instance_key); 708 instance_key);
712 709
713 /* look inside instance_key\\Connection */ 710 /* look inside instance_key\\Connection */
714 if (ERROR_SUCCESS != RegOpenKeyExA ( 711 if (ERROR_SUCCESS != RegOpenKeyExA(
715 HKEY_LOCAL_MACHINE, 712 HKEY_LOCAL_MACHINE,
716 query_key, 713 query_key,
717 0, 714 0,
718 KEY_READ, 715 KEY_READ,
719 &instance_key_handle)) 716 &instance_key_handle))
720 goto cleanup; 717 goto cleanup;
721 718
722 /* now, read our PnpInstanceID */ 719 /* now, read our PnpInstanceID */
723 len = sizeof (pnpinstanceid_value); 720 len = sizeof(pnpinstanceid_value);
724 status = RegQueryValueExA (instance_key_handle, 721 status = RegQueryValueExA(instance_key_handle,
725 pnpinstanceid_name, 722 pnpinstanceid_name,
726 NULL, //reserved, always NULL according to MSDN 723 NULL, //reserved, always NULL according to MSDN
727 &data_type, 724 &data_type,
728 (LPBYTE) pnpinstanceid_value, 725 (LPBYTE)pnpinstanceid_value,
729 &len); 726 &len);
730 727
731 if (status != ERROR_SUCCESS || data_type != REG_SZ) 728 if (status != ERROR_SUCCESS || data_type != REG_SZ)
732 goto cleanup; 729 goto cleanup;
733 730
734 /* compare the value we got to our devices PNPInstanceID*/ 731 /* compare the value we got to our devices PNPInstanceID*/
735 if (0 != strncmp (pnpinstanceid_value, pnp_instance_id, 732 if (0 != strncmp(pnpinstanceid_value, pnp_instance_id,
736 sizeof (pnpinstanceid_value) / sizeof (char))) 733 sizeof(pnpinstanceid_value) / sizeof(char)))
737 goto cleanup; 734 goto cleanup;
738 735
739 len = sizeof (device_visible_name); 736 len = sizeof(device_visible_name);
740 status = RegQueryValueExA ( 737 status = RegQueryValueExA(
741 instance_key_handle, 738 instance_key_handle,
742 adaptername_name, 739 adaptername_name,
743 NULL, //reserved, always NULL according to MSDN 740 NULL, //reserved, always NULL according to MSDN
744 &data_type, 741 &data_type,
745 (LPBYTE) device_visible_name, 742 (LPBYTE)device_visible_name,
746 &len); 743 &len);
747 744
748 if (status != ERROR_SUCCESS || data_type != REG_SZ) 745 if (status != ERROR_SUCCESS || data_type != REG_SZ)
749 goto cleanup; 746 goto cleanup;
@@ -752,17 +749,17 @@ resolve_interface_name ()
752 * we have successfully found OUR instance, 749 * we have successfully found OUR instance,
753 * save the device GUID before exiting 750 * save the device GUID before exiting
754 */ 751 */
755 GNUNET_strlcpy (device_guid, instance_key, sizeof (device_guid)); 752 GNUNET_strlcpy(device_guid, instance_key, sizeof(device_guid));
756 retval = TRUE; 753 retval = TRUE;
757 fprintf (stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid); 754 fprintf(stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid);
758 755
759cleanup: 756cleanup:
760 RegCloseKey (instance_key_handle); 757 RegCloseKey(instance_key_handle);
761 758
762 ++i; 759 ++i;
763 } 760 }
764 761
765 RegCloseKey (adapter_key_handle); 762 RegCloseKey(adapter_key_handle);
766 } 763 }
767 return retval; 764 return retval;
768} 765}
@@ -775,25 +772,27 @@ cleanup:
775 * @return TRUE if the version is sufficient, else FALSE 772 * @return TRUE if the version is sufficient, else FALSE
776 */ 773 */
777static BOOL 774static BOOL
778check_tapw32_version (HANDLE handle) 775check_tapw32_version(HANDLE handle)
779{ 776{
780 ULONG version[3]; 777 ULONG version[3];
781 DWORD len; 778 DWORD len;
782 memset (&(version), 0, sizeof (version));
783 779
784 if (DeviceIoControl (handle, TAP_WIN_IOCTL_GET_VERSION, 780 memset(&(version), 0, sizeof(version));
785 &version, sizeof (version), 781
786 &version, sizeof (version), &len, NULL)) 782 if (DeviceIoControl(handle, TAP_WIN_IOCTL_GET_VERSION,
787 fprintf (stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n", 783 &version, sizeof(version),
788 (int) version[0], 784 &version, sizeof(version), &len, NULL))
789 (int) version[1], 785 fprintf(stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n",
790 (version[2] ? "(DEBUG)" : "")); 786 (int)version[0],
787 (int)version[1],
788 (version[2] ? "(DEBUG)" : ""));
791 789
792 if ((version[0] != TAP_WIN_MIN_MAJOR) || 790 if ((version[0] != TAP_WIN_MIN_MAJOR) ||
793 (version[1] < TAP_WIN_MIN_MINOR )){ 791 (version[1] < TAP_WIN_MIN_MINOR))
794 fprintf (stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n", 792 {
795 TAP_WIN_MIN_MAJOR, 793 fprintf(stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n",
796 TAP_WIN_MIN_MINOR); 794 TAP_WIN_MIN_MAJOR,
795 TAP_WIN_MIN_MINOR);
797 return FALSE; 796 return FALSE;
798 } 797 }
799 798
@@ -807,55 +806,55 @@ check_tapw32_version (HANDLE handle)
807 * @return the fd to the tun or -1 on error 806 * @return the fd to the tun or -1 on error
808 */ 807 */
809static HANDLE 808static HANDLE
810init_tun () 809init_tun()
811{ 810{
812 char device_path[256]; 811 char device_path[256];
813 HANDLE handle; 812 HANDLE handle;
814 813
815 if (! setup_interface ()) 814 if (!setup_interface())
816 { 815 {
817 errno = ENODEV; 816 errno = ENODEV;
818 return INVALID_HANDLE_VALUE; 817 return INVALID_HANDLE_VALUE;
819 } 818 }
820 819
821 if (! resolve_interface_name ()) 820 if (!resolve_interface_name())
822 { 821 {
823 errno = ENODEV; 822 errno = ENODEV;
824 return INVALID_HANDLE_VALUE; 823 return INVALID_HANDLE_VALUE;
825 } 824 }
826 825
827 /* Open Windows TAP-Windows adapter */ 826 /* Open Windows TAP-Windows adapter */
828 snprintf (device_path, sizeof (device_path), "%s%s%s", 827 snprintf(device_path, sizeof(device_path), "%s%s%s",
829 USERMODEDEVICEDIR, 828 USERMODEDEVICEDIR,
830 device_guid, 829 device_guid,
831 TAP_WIN_SUFFIX); 830 TAP_WIN_SUFFIX);
832 831
833 handle = CreateFile ( 832 handle = CreateFile(
834 device_path, 833 device_path,
835 GENERIC_READ | GENERIC_WRITE, 834 GENERIC_READ | GENERIC_WRITE,
836 0, /* was: FILE_SHARE_READ */ 835 0, /* was: FILE_SHARE_READ */
837 0, 836 0,
838 OPEN_EXISTING, 837 OPEN_EXISTING,
839 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 838 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
840 0 839 0
841 ); 840 );
842 841
843 if (INVALID_HANDLE_VALUE == handle) 842 if (INVALID_HANDLE_VALUE == handle)
844 { 843 {
845 fprintf (stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path); 844 fprintf(stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path);
846 return handle; 845 return handle;
847 } 846 }
848 847
849 /* get driver version info */ 848 /* get driver version info */
850 if (! check_tapw32_version (handle)) 849 if (!check_tapw32_version(handle))
851 { 850 {
852 CloseHandle (handle); 851 CloseHandle(handle);
853 return INVALID_HANDLE_VALUE; 852 return INVALID_HANDLE_VALUE;
854 } 853 }
855 854
856 /* TODO (opt?): get MTU-Size */ 855 /* TODO (opt?): get MTU-Size */
857 856
858 fprintf (stderr, "DEBUG: successfully opened TAP device\n"); 857 fprintf(stderr, "DEBUG: successfully opened TAP device\n");
859 return handle; 858 return handle;
860} 859}
861 860
@@ -867,21 +866,22 @@ init_tun ()
867 * @return True if the operation succeeded, else false 866 * @return True if the operation succeeded, else false
868 */ 867 */
869static BOOL 868static BOOL
870tun_up (HANDLE handle) 869tun_up(HANDLE handle)
871{ 870{
872 ULONG status = TRUE; 871 ULONG status = TRUE;
873 DWORD len; 872 DWORD len;
874 if (! DeviceIoControl (handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS, 873
875 &status, sizeof (status), 874 if (!DeviceIoControl(handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
876 &status, sizeof (status), &len, NULL)) 875 &status, sizeof(status),
876 &status, sizeof(status), &len, NULL))
877 { 877 {
878 fprintf (stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n"); 878 fprintf(stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n");
879 return FALSE; 879 return FALSE;
880 } 880 }
881 881
882 /* Wait for the device to go UP, might take some time. */ 882 /* Wait for the device to go UP, might take some time. */
883 Sleep (TAP32_POSTUP_WAITTIME * 1000); 883 Sleep(TAP32_POSTUP_WAITTIME * 1000);
884 fprintf (stderr, "DEBUG: successfully set TAP device to UP\n"); 884 fprintf(stderr, "DEBUG: successfully set TAP device to UP\n");
885 885
886 return TRUE; 886 return TRUE;
887} 887}
@@ -913,8 +913,8 @@ tun_up (HANDLE handle)
913 * @return false if an event reset was impossible (OS error), else true 913 * @return false if an event reset was impossible (OS error), else true
914 */ 914 */
915static BOOL 915static BOOL
916attempt_read_tap (struct io_facility * input_facility, 916attempt_read_tap(struct io_facility * input_facility,
917 struct io_facility * output_facility) 917 struct io_facility * output_facility)
918{ 918{
919 struct GNUNET_MessageHeader * hdr; 919 struct GNUNET_MessageHeader * hdr;
920 unsigned short size; 920 unsigned short size;
@@ -922,137 +922,139 @@ attempt_read_tap (struct io_facility * input_facility,
922 switch (input_facility->facility_state) 922 switch (input_facility->facility_state)
923 { 923 {
924 case IOSTATE_READY: 924 case IOSTATE_READY:
925 { 925 {
926 if (! ResetEvent (input_facility->overlapped.hEvent)) 926 if (!ResetEvent(input_facility->overlapped.hEvent))
927 { 927 {
928 return FALSE;
929 }
930
931 input_facility->buffer_size = 0;
932
933 /* Check how the task is handled */
934 if (ReadFile(input_facility->handle,
935 input_facility->buffer,
936 sizeof(input_facility->buffer) - sizeof(struct GNUNET_MessageHeader),
937 &input_facility->buffer_size,
938 &input_facility->overlapped))
939 { /* async event processed immediately*/
940 /* reset event manually*/
941 if (!SetEvent(input_facility->overlapped.hEvent))
928 return FALSE; 942 return FALSE;
929 } 943
930 944 fprintf(stderr, "DEBUG: tap read succeeded immediately\n");
931 input_facility->buffer_size = 0; 945
932 946 /* we successfully read something from the TAP and now need to
933 /* Check how the task is handled */ 947 * send it our via STDOUT. Is that possible at the moment? */
934 if (ReadFile (input_facility->handle, 948 if ((IOSTATE_READY == output_facility->facility_state ||
935 input_facility->buffer, 949 IOSTATE_WAITING == output_facility->facility_state)
936 sizeof (input_facility->buffer) - sizeof (struct GNUNET_MessageHeader), 950 && (0 < input_facility->buffer_size))
937 &input_facility->buffer_size, 951 { /* hand over this buffers content and apply message header for gnunet */
938 &input_facility->overlapped)) 952 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
939 {/* async event processed immediately*/ 953 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
940 954
941 /* reset event manually*/ 955 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
942 if (! SetEvent (input_facility->overlapped.hEvent)) 956 input_facility->buffer,
943 return FALSE; 957 input_facility->buffer_size);
944 958
945 fprintf (stderr, "DEBUG: tap read succeeded immediately\n"); 959 output_facility->buffer_size = size;
946 960 hdr->size = htons(size);
947 /* we successfully read something from the TAP and now need to 961 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
948 * send it our via STDOUT. Is that possible at the moment? */ 962 output_facility->facility_state = IOSTATE_READY;
949 if ((IOSTATE_READY == output_facility->facility_state || 963 }
950 IOSTATE_WAITING == output_facility->facility_state) 964 else if (0 < input_facility->buffer_size)
951 && (0 < input_facility->buffer_size)) 965 /* If we have have read our buffer, wait for our write-partner*/
952 { /* hand over this buffers content and apply message header for gnunet */ 966 input_facility->facility_state = IOSTATE_WAITING;
953 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 967 }
954 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 968 else /* operation was either queued or failed*/
955 969 {
956 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 970 int err = GetLastError();
957 input_facility->buffer, 971 if (ERROR_IO_PENDING == err)
958 input_facility->buffer_size); 972 { /* operation queued */
959 973 input_facility->facility_state = IOSTATE_QUEUED;
960 output_facility->buffer_size = size; 974 }
961 hdr->size = htons (size); 975 else
962 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 976 { /* error occurred, let the rest of the elements finish */
963 output_facility->facility_state = IOSTATE_READY; 977 input_facility->path_open = FALSE;
964 } 978 input_facility->facility_state = IOSTATE_FAILED;
965 else if (0 < input_facility->buffer_size) 979 if (IOSTATE_WAITING == output_facility->facility_state)
966 /* If we have have read our buffer, wait for our write-partner*/ 980 output_facility->path_open = FALSE;
967 input_facility->facility_state = IOSTATE_WAITING; 981
968 } 982 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
969 else /* operation was either queued or failed*/ 983 }
970 { 984 }
971 int err = GetLastError (); 985 }
972 if (ERROR_IO_PENDING == err)
973 { /* operation queued */
974 input_facility->facility_state = IOSTATE_QUEUED;
975 }
976 else
977 { /* error occurred, let the rest of the elements finish */
978 input_facility->path_open = FALSE;
979 input_facility->facility_state = IOSTATE_FAILED;
980 if (IOSTATE_WAITING == output_facility->facility_state)
981 output_facility->path_open = FALSE;
982
983 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n");
984 }
985 }
986 }
987 return TRUE; 986 return TRUE;
988 // We are queued and should check if the read has finished 987
988 // We are queued and should check if the read has finished
989 case IOSTATE_QUEUED: 989 case IOSTATE_QUEUED:
990 { 990 {
991 // there was an operation going on already, check if that has completed now. 991 // there was an operation going on already, check if that has completed now.
992 992
993 if (GetOverlappedResult (input_facility->handle, 993 if (GetOverlappedResult(input_facility->handle,
994 &input_facility->overlapped, 994 &input_facility->overlapped,
995 &input_facility->buffer_size, 995 &input_facility->buffer_size,
996 FALSE)) 996 FALSE))
997 {/* successful return for a queued operation */ 997 { /* successful return for a queued operation */
998 if (! ResetEvent (input_facility->overlapped.hEvent)) 998 if (!ResetEvent(input_facility->overlapped.hEvent))
999 return FALSE; 999 return FALSE;
1000 1000
1001 fprintf (stderr, "DEBUG: tap read succeeded delayed\n"); 1001 fprintf(stderr, "DEBUG: tap read succeeded delayed\n");
1002 1002
1003 /* we successfully read something from the TAP and now need to 1003 /* we successfully read something from the TAP and now need to
1004 * send it our via STDOUT. Is that possible at the moment? */ 1004 * send it our via STDOUT. Is that possible at the moment? */
1005 if ((IOSTATE_READY == output_facility->facility_state || 1005 if ((IOSTATE_READY == output_facility->facility_state ||
1006 IOSTATE_WAITING == output_facility->facility_state) 1006 IOSTATE_WAITING == output_facility->facility_state)
1007 && 0 < input_facility->buffer_size) 1007 && 0 < input_facility->buffer_size)
1008 { /* hand over this buffers content and apply message header for gnunet */ 1008 { /* hand over this buffers content and apply message header for gnunet */
1009 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 1009 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1010 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 1010 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1011 1011
1012 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1012 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1013 input_facility->buffer, 1013 input_facility->buffer,
1014 input_facility->buffer_size); 1014 input_facility->buffer_size);
1015 1015
1016 output_facility->buffer_size = size; 1016 output_facility->buffer_size = size;
1017 hdr->size = htons(size); 1017 hdr->size = htons(size);
1018 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1018 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1019 output_facility->facility_state = IOSTATE_READY; 1019 output_facility->facility_state = IOSTATE_READY;
1020 input_facility->facility_state = IOSTATE_READY; 1020 input_facility->facility_state = IOSTATE_READY;
1021 } 1021 }
1022 else if (0 < input_facility->buffer_size) 1022 else if (0 < input_facility->buffer_size)
1023 { /* If we have have read our buffer, wait for our write-partner*/ 1023 { /* If we have have read our buffer, wait for our write-partner*/
1024 input_facility->facility_state = IOSTATE_WAITING; 1024 input_facility->facility_state = IOSTATE_WAITING;
1025 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? 1025 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
1026 } 1026 }
1027 } 1027 }
1028 else 1028 else
1029 { /* operation still pending/queued or failed? */ 1029 { /* operation still pending/queued or failed? */
1030 int err = GetLastError (); 1030 int err = GetLastError();
1031 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1031 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1032 { /* error occurred, let the rest of the elements finish */ 1032 { /* error occurred, let the rest of the elements finish */
1033 input_facility->path_open = FALSE; 1033 input_facility->path_open = FALSE;
1034 input_facility->facility_state = IOSTATE_FAILED; 1034 input_facility->facility_state = IOSTATE_FAILED;
1035 if (IOSTATE_WAITING == output_facility->facility_state) 1035 if (IOSTATE_WAITING == output_facility->facility_state)
1036 output_facility->path_open = FALSE; 1036 output_facility->path_open = FALSE;
1037 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1037 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1038 } 1038 }
1039 } 1039 }
1040 } 1040 }
1041 return TRUE; 1041 return TRUE;
1042
1042 case IOSTATE_RESUME: 1043 case IOSTATE_RESUME:
1043 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 1044 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1044 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 1045 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1045 1046
1046 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1047 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1047 input_facility->buffer, 1048 input_facility->buffer,
1048 input_facility->buffer_size); 1049 input_facility->buffer_size);
1049 1050
1050 output_facility->buffer_size = size; 1051 output_facility->buffer_size = size;
1051 hdr->size = htons (size); 1052 hdr->size = htons(size);
1052 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1053 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1053 output_facility->facility_state = IOSTATE_READY; 1054 output_facility->facility_state = IOSTATE_READY;
1054 input_facility->facility_state = IOSTATE_READY; 1055 input_facility->facility_state = IOSTATE_READY;
1055 return TRUE; 1056 return TRUE;
1057
1056 default: 1058 default:
1057 return TRUE; 1059 return TRUE;
1058 } 1060 }
@@ -1086,154 +1088,157 @@ attempt_read_tap (struct io_facility * input_facility,
1086 * @return false if an event reset was impossible (OS error), else true 1088 * @return false if an event reset was impossible (OS error), else true
1087 */ 1089 */
1088static BOOL 1090static BOOL
1089attempt_read_stdin (struct io_facility * input_facility, 1091attempt_read_stdin(struct io_facility * input_facility,
1090 struct io_facility * output_facility) 1092 struct io_facility * output_facility)
1091{ 1093{
1092 struct GNUNET_MessageHeader * hdr; 1094 struct GNUNET_MessageHeader * hdr;
1093 1095
1094 switch (input_facility->facility_state) 1096 switch (input_facility->facility_state)
1095 { 1097 {
1096 case IOSTATE_READY: 1098 case IOSTATE_READY:
1097 { 1099 {
1098 input_facility->buffer_size = 0; 1100 input_facility->buffer_size = 0;
1099 1101
1100partial_read_iostate_ready: 1102partial_read_iostate_ready:
1101 if (! ResetEvent (input_facility->overlapped.hEvent)) 1103 if (!ResetEvent(input_facility->overlapped.hEvent))
1102 return FALSE; 1104 return FALSE;
1103 1105
1104 /* Check how the task is handled */ 1106 /* Check how the task is handled */
1105 if (ReadFile (input_facility->handle, 1107 if (ReadFile(input_facility->handle,
1106 input_facility->buffer + input_facility->buffer_size, 1108 input_facility->buffer + input_facility->buffer_size,
1107 sizeof (input_facility->buffer) - input_facility->buffer_size, 1109 sizeof(input_facility->buffer) - input_facility->buffer_size,
1108 &input_facility->buffer_size_processed, 1110 &input_facility->buffer_size_processed,
1109 &input_facility->overlapped)) 1111 &input_facility->overlapped))
1110 {/* async event processed immediately*/ 1112 { /* async event processed immediately*/
1111 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1113 hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1112 1114
1113 /* reset event manually*/ 1115 /* reset event manually*/
1114 if (!SetEvent (input_facility->overlapped.hEvent)) 1116 if (!SetEvent(input_facility->overlapped.hEvent))
1115 return FALSE; 1117 return FALSE;
1116 1118
1117 fprintf (stderr, "DEBUG: stdin read succeeded immediately\n"); 1119 fprintf(stderr, "DEBUG: stdin read succeeded immediately\n");
1118 input_facility->buffer_size += input_facility->buffer_size_processed; 1120 input_facility->buffer_size += input_facility->buffer_size_processed;
1119 1121
1120 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER || 1122 if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER ||
1121 ntohs (hdr->size) > sizeof (input_facility->buffer)) 1123 ntohs(hdr->size) > sizeof(input_facility->buffer))
1122 { 1124 {
1123 fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); 1125 fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1124 input_facility->facility_state = IOSTATE_READY; 1126 input_facility->facility_state = IOSTATE_READY;
1125 return TRUE; 1127 return TRUE;
1126 } 1128 }
1127 /* we got the a part of a packet */ 1129 /* we got the a part of a packet */
1128 if (ntohs (hdr->size) > input_facility->buffer_size) 1130 if (ntohs(hdr->size) > input_facility->buffer_size)
1129 goto partial_read_iostate_ready; 1131 goto partial_read_iostate_ready;
1130 1132
1131 /* have we read more than 0 bytes of payload? (sizeread > header)*/ 1133 /* have we read more than 0 bytes of payload? (sizeread > header)*/
1132 if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader) && 1134 if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader) &&
1133 ((IOSTATE_READY == output_facility->facility_state) || 1135 ((IOSTATE_READY == output_facility->facility_state) ||
1134 (IOSTATE_WAITING == output_facility->facility_state))) 1136 (IOSTATE_WAITING == output_facility->facility_state)))
1135 {/* we successfully read something from the TAP and now need to 1137 { /* we successfully read something from the TAP and now need to
1136 * send it our via STDOUT. Is that possible at the moment? */ 1138 * send it our via STDOUT. Is that possible at the moment? */
1137 1139 /* hand over this buffers content and strip gnunet message header */
1138 /* hand over this buffers content and strip gnunet message header */ 1140 GNUNET_memcpy(output_facility->buffer,
1139 GNUNET_memcpy (output_facility->buffer, 1141 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1140 input_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1142 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1141 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); 1143 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1142 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); 1144 output_facility->facility_state = IOSTATE_READY;
1143 output_facility->facility_state = IOSTATE_READY;
1144 input_facility->facility_state = IOSTATE_READY;
1145 }
1146 else if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader))
1147 /* If we have have read our buffer, wait for our write-partner*/
1148 input_facility->facility_state = IOSTATE_WAITING;
1149 else /* we read nothing */
1150 input_facility->facility_state = IOSTATE_READY; 1145 input_facility->facility_state = IOSTATE_READY;
1151 } 1146 }
1152 else /* operation was either queued or failed*/ 1147 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1153 { 1148 /* If we have have read our buffer, wait for our write-partner*/
1154 int err = GetLastError (); 1149 input_facility->facility_state = IOSTATE_WAITING;
1155 if (ERROR_IO_PENDING == err) /* operation queued */ 1150 else /* we read nothing */
1156 input_facility->facility_state = IOSTATE_QUEUED; 1151 input_facility->facility_state = IOSTATE_READY;
1157 else 1152 }
1158 { /* error occurred, let the rest of the elements finish */ 1153 else /* operation was either queued or failed*/
1159 input_facility->path_open = FALSE; 1154 {
1160 input_facility->facility_state = IOSTATE_FAILED; 1155 int err = GetLastError();
1161 if (IOSTATE_WAITING == output_facility->facility_state) 1156 if (ERROR_IO_PENDING == err) /* operation queued */
1162 output_facility->path_open = FALSE; 1157 input_facility->facility_state = IOSTATE_QUEUED;
1163 1158 else
1164 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1159 { /* error occurred, let the rest of the elements finish */
1165 } 1160 input_facility->path_open = FALSE;
1166 } 1161 input_facility->facility_state = IOSTATE_FAILED;
1167 } 1162 if (IOSTATE_WAITING == output_facility->facility_state)
1163 output_facility->path_open = FALSE;
1164
1165 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1166 }
1167 }
1168 }
1168 return TRUE; 1169 return TRUE;
1169 // We are queued and should check if the read has finished 1170
1171 // We are queued and should check if the read has finished
1170 case IOSTATE_QUEUED: 1172 case IOSTATE_QUEUED:
1171 { 1173 {
1172 // there was an operation going on already, check if that has completed now. 1174 // there was an operation going on already, check if that has completed now.
1173 if (GetOverlappedResult (input_facility->handle, 1175 if (GetOverlappedResult(input_facility->handle,
1174 &input_facility->overlapped, 1176 &input_facility->overlapped,
1175 &input_facility->buffer_size_processed, 1177 &input_facility->buffer_size_processed,
1176 FALSE)) 1178 FALSE))
1177 {/* successful return for a queued operation */ 1179 { /* successful return for a queued operation */
1178 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1180 hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1179 1181
1180 if (! ResetEvent (input_facility->overlapped.hEvent)) 1182 if (!ResetEvent(input_facility->overlapped.hEvent))
1181 return FALSE; 1183 return FALSE;
1182 1184
1183 fprintf (stderr, "DEBUG: stdin read succeeded delayed\n"); 1185 fprintf(stderr, "DEBUG: stdin read succeeded delayed\n");
1184 input_facility->buffer_size += input_facility->buffer_size_processed; 1186 input_facility->buffer_size += input_facility->buffer_size_processed;
1185 1187
1186 if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || 1188 if ((ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
1187 (ntohs (hdr->size) > sizeof (input_facility->buffer))) 1189 (ntohs(hdr->size) > sizeof(input_facility->buffer)))
1188 { 1190 {
1189 fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); 1191 fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1190 input_facility->facility_state = IOSTATE_READY; 1192 input_facility->facility_state = IOSTATE_READY;
1191 return TRUE; 1193 return TRUE;
1192 } 1194 }
1193 /* we got the a part of a packet */ 1195 /* we got the a part of a packet */
1194 if (ntohs (hdr->size) > input_facility->buffer_size ); 1196 if (ntohs(hdr->size) > input_facility->buffer_size)
1195 goto partial_read_iostate_ready; 1197 ;
1196 1198 goto partial_read_iostate_ready;
1197 /* we successfully read something from the TAP and now need to 1199
1198 * send it our via STDOUT. Is that possible at the moment? */ 1200 /* we successfully read something from the TAP and now need to
1199 if ((IOSTATE_READY == output_facility->facility_state || 1201 * send it our via STDOUT. Is that possible at the moment? */
1200 IOSTATE_WAITING == output_facility->facility_state) 1202 if ((IOSTATE_READY == output_facility->facility_state ||
1201 && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader)) 1203 IOSTATE_WAITING == output_facility->facility_state)
1202 { /* hand over this buffers content and strip gnunet message header */ 1204 && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1203 GNUNET_memcpy (output_facility->buffer, 1205 { /* hand over this buffers content and strip gnunet message header */
1204 input_facility->buffer + sizeof(struct GNUNET_MessageHeader), 1206 GNUNET_memcpy(output_facility->buffer,
1205 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader)); 1207 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1206 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader); 1208 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1207 output_facility->facility_state = IOSTATE_READY; 1209 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1208 input_facility->facility_state = IOSTATE_READY; 1210 output_facility->facility_state = IOSTATE_READY;
1209 }
1210 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1211 input_facility->facility_state = IOSTATE_WAITING;
1212 else
1213 input_facility->facility_state = IOSTATE_READY; 1211 input_facility->facility_state = IOSTATE_READY;
1214 } 1212 }
1215 else 1213 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1216 { /* operation still pending/queued or failed? */ 1214 input_facility->facility_state = IOSTATE_WAITING;
1217 int err = GetLastError (); 1215 else
1218 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1216 input_facility->facility_state = IOSTATE_READY;
1219 { /* error occurred, let the rest of the elements finish */ 1217 }
1220 input_facility->path_open = FALSE; 1218 else
1221 input_facility->facility_state = IOSTATE_FAILED; 1219 { /* operation still pending/queued or failed? */
1222 if (IOSTATE_WAITING == output_facility->facility_state) 1220 int err = GetLastError();
1223 output_facility->path_open = FALSE; 1221 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1224 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1222 { /* error occurred, let the rest of the elements finish */
1225 } 1223 input_facility->path_open = FALSE;
1226 } 1224 input_facility->facility_state = IOSTATE_FAILED;
1227 } 1225 if (IOSTATE_WAITING == output_facility->facility_state)
1226 output_facility->path_open = FALSE;
1227 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1228 }
1229 }
1230 }
1228 return TRUE; 1231 return TRUE;
1232
1229 case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */ 1233 case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */
1230 GNUNET_memcpy (output_facility->buffer, 1234 GNUNET_memcpy(output_facility->buffer,
1231 input_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1235 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1232 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); 1236 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1233 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); 1237 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1234 output_facility->facility_state = IOSTATE_READY; 1238 output_facility->facility_state = IOSTATE_READY;
1235 input_facility->facility_state = IOSTATE_READY; 1239 input_facility->facility_state = IOSTATE_READY;
1236 return TRUE; 1240 return TRUE;
1241
1237 default: 1242 default:
1238 return TRUE; 1243 return TRUE;
1239 } 1244 }
@@ -1250,8 +1255,8 @@ partial_read_iostate_ready:
1250 * @return false if an event reset was impossible (OS error), else true 1255 * @return false if an event reset was impossible (OS error), else true
1251 */ 1256 */
1252static BOOL 1257static BOOL
1253attempt_write (struct io_facility * output_facility, 1258attempt_write(struct io_facility * output_facility,
1254 struct io_facility * input_facility) 1259 struct io_facility * input_facility)
1255{ 1260{
1256 switch (output_facility->facility_state) 1261 switch (output_facility->facility_state)
1257 { 1262 {
@@ -1259,22 +1264,21 @@ attempt_write (struct io_facility * output_facility,
1259 output_facility->buffer_size_written = 0; 1264 output_facility->buffer_size_written = 0;
1260 1265
1261continue_partial_write: 1266continue_partial_write:
1262 if (! ResetEvent (output_facility->overlapped.hEvent)) 1267 if (!ResetEvent(output_facility->overlapped.hEvent))
1263 return FALSE; 1268 return FALSE;
1264 1269
1265 /* Check how the task was handled */ 1270 /* Check how the task was handled */
1266 if (WriteFile (output_facility->handle, 1271 if (WriteFile(output_facility->handle,
1267 output_facility->buffer + output_facility->buffer_size_written, 1272 output_facility->buffer + output_facility->buffer_size_written,
1268 output_facility->buffer_size - output_facility->buffer_size_written, 1273 output_facility->buffer_size - output_facility->buffer_size_written,
1269 &output_facility->buffer_size_processed, 1274 &output_facility->buffer_size_processed,
1270 &output_facility->overlapped)) 1275 &output_facility->overlapped))
1271 {/* async event processed immediately*/ 1276 {/* async event processed immediately*/
1272 1277 fprintf(stderr, "DEBUG: write succeeded immediately\n");
1273 fprintf (stderr, "DEBUG: write succeeded immediately\n");
1274 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1278 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1275 1279
1276 /* reset event manually*/ 1280 /* reset event manually*/
1277 if (! SetEvent (output_facility->overlapped.hEvent)) 1281 if (!SetEvent(output_facility->overlapped.hEvent))
1278 return FALSE; 1282 return FALSE;
1279 1283
1280 /* partial write */ 1284 /* partial write */
@@ -1292,7 +1296,7 @@ continue_partial_write:
1292 } 1296 }
1293 else /* operation was either queued or failed*/ 1297 else /* operation was either queued or failed*/
1294 { 1298 {
1295 int err = GetLastError (); 1299 int err = GetLastError();
1296 if (ERROR_IO_PENDING == err) 1300 if (ERROR_IO_PENDING == err)
1297 { /* operation queued */ 1301 { /* operation queued */
1298 output_facility->facility_state = IOSTATE_QUEUED; 1302 output_facility->facility_state = IOSTATE_QUEUED;
@@ -1301,22 +1305,23 @@ continue_partial_write:
1301 { /* error occurred, close this path */ 1305 { /* error occurred, close this path */
1302 output_facility->path_open = FALSE; 1306 output_facility->path_open = FALSE;
1303 output_facility->facility_state = IOSTATE_FAILED; 1307 output_facility->facility_state = IOSTATE_FAILED;
1304 fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); 1308 fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1305 } 1309 }
1306 } 1310 }
1307 return TRUE; 1311 return TRUE;
1312
1308 case IOSTATE_QUEUED: 1313 case IOSTATE_QUEUED:
1309 // there was an operation going on already, check if that has completed now. 1314 // there was an operation going on already, check if that has completed now.
1310 1315
1311 if (GetOverlappedResult (output_facility->handle, 1316 if (GetOverlappedResult(output_facility->handle,
1312 &output_facility->overlapped, 1317 &output_facility->overlapped,
1313 &output_facility->buffer_size_processed, 1318 &output_facility->buffer_size_processed,
1314 FALSE)) 1319 FALSE))
1315 {/* successful return for a queued operation */ 1320 {/* successful return for a queued operation */
1316 if (! ResetEvent (output_facility->overlapped.hEvent)) 1321 if (!ResetEvent(output_facility->overlapped.hEvent))
1317 return FALSE; 1322 return FALSE;
1318 1323
1319 fprintf (stderr, "DEBUG: write succeeded delayed\n"); 1324 fprintf(stderr, "DEBUG: write succeeded delayed\n");
1320 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1325 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1321 1326
1322 /* partial write */ 1327 /* partial write */
@@ -1334,14 +1339,15 @@ continue_partial_write:
1334 } 1339 }
1335 else 1340 else
1336 { /* operation still pending/queued or failed? */ 1341 { /* operation still pending/queued or failed? */
1337 int err = GetLastError (); 1342 int err = GetLastError();
1338 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1343 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1339 { /* error occurred, close this path */ 1344 { /* error occurred, close this path */
1340 output_facility->path_open = FALSE; 1345 output_facility->path_open = FALSE;
1341 output_facility->facility_state = IOSTATE_FAILED; 1346 output_facility->facility_state = IOSTATE_FAILED;
1342 fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); 1347 fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1343 } 1348 }
1344 } 1349 }
1350
1345 default: 1351 default:
1346 return TRUE; 1352 return TRUE;
1347 } 1353 }
@@ -1357,15 +1363,15 @@ continue_partial_write:
1357 * @return true on success, else false 1363 * @return true on success, else false
1358 */ 1364 */
1359static BOOL 1365static BOOL
1360initialize_io_facility (struct io_facility * elem, 1366initialize_io_facility(struct io_facility * elem,
1361 int initial_state, 1367 int initial_state,
1362 BOOL signaled) 1368 BOOL signaled)
1363{ 1369{
1364 elem->path_open = TRUE; 1370 elem->path_open = TRUE;
1365 elem->handle = INVALID_HANDLE_VALUE; 1371 elem->handle = INVALID_HANDLE_VALUE;
1366 elem->facility_state = initial_state; 1372 elem->facility_state = initial_state;
1367 elem->buffer_size = 0; 1373 elem->buffer_size = 0;
1368 elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL); 1374 elem->overlapped.hEvent = CreateEvent(NULL, TRUE, signaled, NULL);
1369 if (NULL == elem->overlapped.hEvent) 1375 if (NULL == elem->overlapped.hEvent)
1370 return FALSE; 1376 return FALSE;
1371 1377
@@ -1379,7 +1385,7 @@ initialize_io_facility (struct io_facility * elem,
1379 * @param tap_handle device handle for interacting with the Virtual interface 1385 * @param tap_handle device handle for interacting with the Virtual interface
1380 */ 1386 */
1381static void 1387static void
1382run (HANDLE tap_handle) 1388run(HANDLE tap_handle)
1383{ 1389{
1384 /* IO-Facility for reading from our virtual interface */ 1390 /* IO-Facility for reading from our virtual interface */
1385 struct io_facility tap_read; 1391 struct io_facility tap_read;
@@ -1390,8 +1396,8 @@ run (HANDLE tap_handle)
1390 /* IO-Facility for writing to stdout */ 1396 /* IO-Facility for writing to stdout */
1391 struct io_facility std_out; 1397 struct io_facility std_out;
1392 1398
1393 HANDLE parent_std_in_handle = GetStdHandle (STD_INPUT_HANDLE); 1399 HANDLE parent_std_in_handle = GetStdHandle(STD_INPUT_HANDLE);
1394 HANDLE parent_std_out_handle = GetStdHandle (STD_OUTPUT_HANDLE); 1400 HANDLE parent_std_out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
1395 1401
1396 /* tun up: */ 1402 /* tun up: */
1397 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn 1403 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn
@@ -1400,14 +1406,14 @@ run (HANDLE tap_handle)
1400 * DHCP and such are all features we will never use in gnunet afaik. 1406 * DHCP and such are all features we will never use in gnunet afaik.
1401 * But for openvpn those are essential. 1407 * But for openvpn those are essential.
1402 */ 1408 */
1403 if ((privilege_testing) || (! tun_up (tap_handle))) 1409 if ((privilege_testing) || (!tun_up(tap_handle)))
1404 goto teardown_final; 1410 goto teardown_final;
1405 1411
1406 /* Initialize our overlapped IO structures*/ 1412 /* Initialize our overlapped IO structures*/
1407 if (! (initialize_io_facility (&tap_read, IOSTATE_READY, FALSE) 1413 if (!(initialize_io_facility(&tap_read, IOSTATE_READY, FALSE)
1408 && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE) 1414 && initialize_io_facility(&tap_write, IOSTATE_WAITING, TRUE)
1409 && initialize_io_facility (&std_in, IOSTATE_READY, FALSE) 1415 && initialize_io_facility(&std_in, IOSTATE_READY, FALSE)
1410 && initialize_io_facility (&std_out, IOSTATE_WAITING, TRUE))) 1416 && initialize_io_facility(&std_out, IOSTATE_WAITING, TRUE)))
1411 goto teardown_final; 1417 goto teardown_final;
1412 1418
1413 /* Handles for STDIN and STDOUT */ 1419 /* Handles for STDIN and STDOUT */
@@ -1418,72 +1424,71 @@ run (HANDLE tap_handle)
1418 /* Debug output to console STDIN/STDOUT*/ 1424 /* Debug output to console STDIN/STDOUT*/
1419 std_in.handle = parent_std_in_handle; 1425 std_in.handle = parent_std_in_handle;
1420 std_out.handle = parent_std_out_handle; 1426 std_out.handle = parent_std_out_handle;
1421
1422#else 1427#else
1423 fprintf (stderr, "DEBUG: reopening stdin/out for overlapped IO\n"); 1428 fprintf(stderr, "DEBUG: reopening stdin/out for overlapped IO\n");
1424 /* 1429 /*
1425 * Find out the types of our handles. 1430 * Find out the types of our handles.
1426 * This part is a problem, because in windows we need to handle files, 1431 * This part is a problem, because in windows we need to handle files,
1427 * pipes and the console differently. 1432 * pipes and the console differently.
1428 */ 1433 */
1429 if ((FILE_TYPE_PIPE != GetFileType (parent_std_in_handle)) || 1434 if ((FILE_TYPE_PIPE != GetFileType(parent_std_in_handle)) ||
1430 (FILE_TYPE_PIPE != GetFileType (parent_std_out_handle))) 1435 (FILE_TYPE_PIPE != GetFileType(parent_std_out_handle)))
1431 { 1436 {
1432 fprintf (stderr, "ERROR: stdin/stdout must be named pipes\n"); 1437 fprintf(stderr, "ERROR: stdin/stdout must be named pipes\n");
1433 goto teardown; 1438 goto teardown;
1434 } 1439 }
1435 1440
1436 std_in.handle = ReOpenFile (parent_std_in_handle, 1441 std_in.handle = ReOpenFile(parent_std_in_handle,
1437 GENERIC_READ, 1442 GENERIC_READ,
1438 FILE_SHARE_WRITE | FILE_SHARE_READ, 1443 FILE_SHARE_WRITE | FILE_SHARE_READ,
1439 FILE_FLAG_OVERLAPPED); 1444 FILE_FLAG_OVERLAPPED);
1440 1445
1441 if (INVALID_HANDLE_VALUE == std_in.handle) 1446 if (INVALID_HANDLE_VALUE == std_in.handle)
1442 { 1447 {
1443 fprintf (stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n"); 1448 fprintf(stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n");
1444 goto teardown; 1449 goto teardown;
1445 } 1450 }
1446 1451
1447 std_out.handle = ReOpenFile (parent_std_out_handle, 1452 std_out.handle = ReOpenFile(parent_std_out_handle,
1448 GENERIC_WRITE, 1453 GENERIC_WRITE,
1449 FILE_SHARE_READ, 1454 FILE_SHARE_READ,
1450 FILE_FLAG_OVERLAPPED); 1455 FILE_FLAG_OVERLAPPED);
1451 1456
1452 if (INVALID_HANDLE_VALUE == std_out.handle) 1457 if (INVALID_HANDLE_VALUE == std_out.handle)
1453 { 1458 {
1454 fprintf (stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n"); 1459 fprintf(stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n");
1455 goto teardown; 1460 goto teardown;
1456 } 1461 }
1457#endif 1462#endif
1458 1463
1459 fprintf (stderr, "DEBUG: mainloop has begun\n"); 1464 fprintf(stderr, "DEBUG: mainloop has begun\n");
1460 1465
1461 while (std_out.path_open || tap_write.path_open) 1466 while (std_out.path_open || tap_write.path_open)
1462 { 1467 {
1463 /* perform READ from stdin if possible */ 1468 /* perform READ from stdin if possible */
1464 if (std_in.path_open && (! attempt_read_stdin (&std_in, &tap_write))) 1469 if (std_in.path_open && (!attempt_read_stdin(&std_in, &tap_write)))
1465 break; 1470 break;
1466 1471
1467 /* perform READ from tap if possible */ 1472 /* perform READ from tap if possible */
1468 if (tap_read.path_open && (! attempt_read_tap (&tap_read, &std_out))) 1473 if (tap_read.path_open && (!attempt_read_tap(&tap_read, &std_out)))
1469 break; 1474 break;
1470 1475
1471 /* perform WRITE to tap if possible */ 1476 /* perform WRITE to tap if possible */
1472 if (tap_write.path_open && (! attempt_write (&tap_write, &std_in))) 1477 if (tap_write.path_open && (!attempt_write(&tap_write, &std_in)))
1473 break; 1478 break;
1474 1479
1475 /* perform WRITE to STDOUT if possible */ 1480 /* perform WRITE to STDOUT if possible */
1476 if (std_out.path_open && (! attempt_write (&std_out, &tap_read))) 1481 if (std_out.path_open && (!attempt_write(&std_out, &tap_read)))
1477 break; 1482 break;
1478 } 1483 }
1479 1484
1480 fprintf (stderr, "DEBUG: teardown initiated\n"); 1485 fprintf(stderr, "DEBUG: teardown initiated\n");
1481teardown: 1486teardown:
1482 CancelIo (tap_handle); 1487 CancelIo(tap_handle);
1483 CancelIo (std_in.handle); 1488 CancelIo(std_in.handle);
1484 CancelIo (std_out.handle); 1489 CancelIo(std_out.handle);
1485teardown_final: 1490teardown_final:
1486 CloseHandle (tap_handle); 1491 CloseHandle(tap_handle);
1487} 1492}
1488 1493
1489 1494
@@ -1500,7 +1505,7 @@ teardown_final:
1500 * 6: IPv4 netmask (255.255.0.0), ignored if #4 is "-" 1505 * 6: IPv4 netmask (255.255.0.0), ignored if #4 is "-"
1501 */ 1506 */
1502int 1507int
1503main (int argc, char **argv) 1508main(int argc, char **argv)
1504{ 1509{
1505 char hwid[LINE_LEN]; 1510 char hwid[LINE_LEN];
1506 HANDLE handle; 1511 HANDLE handle;
@@ -1508,97 +1513,98 @@ main (int argc, char **argv)
1508 BOOL have_ip4 = FALSE; 1513 BOOL have_ip4 = FALSE;
1509 BOOL have_ip6 = FALSE; 1514 BOOL have_ip6 = FALSE;
1510 1515
1511 if (argc > 1 && 0 == strcmp (argv[1], "-d")){ 1516 if (argc > 1 && 0 == strcmp(argv[1], "-d"))
1517 {
1512 privilege_testing = TRUE; 1518 privilege_testing = TRUE;
1513 fprintf (stderr, 1519 fprintf(stderr,
1514 "%s", 1520 "%s",
1515 "DEBUG: Running binary in privilege testing mode."); 1521 "DEBUG: Running binary in privilege testing mode.");
1516 argv++; 1522 argv++;
1517 argc--; 1523 argc--;
1518 } 1524 }
1519 1525
1520 if (6 != argc) 1526 if (6 != argc)
1521 { 1527 {
1522 fprintf (stderr, 1528 fprintf(stderr,
1523 "%s", 1529 "%s",
1524 "FATAL: must supply 5 arguments\nUsage:\ngnunet-helper-vpn [-d] <if name prefix> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n"); 1530 "FATAL: must supply 5 arguments\nUsage:\ngnunet-helper-vpn [-d] <if name prefix> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n");
1525 return 1; 1531 return 1;
1526 } 1532 }
1527 1533
1528 GNUNET_strlcpy (hwid, argv[1], sizeof (hwid)); 1534 GNUNET_strlcpy(hwid, argv[1], sizeof(hwid));
1529 1535
1530 /* 1536 /*
1531 * We use our PID for finding/resolving the control-panel name of our virtual 1537 * We use our PID for finding/resolving the control-panel name of our virtual
1532 * device. PIDs are (of course) unique at runtime, thus we can safely use it 1538 * device. PIDs are (of course) unique at runtime, thus we can safely use it
1533 * as additional hardware-id for our device. 1539 * as additional hardware-id for our device.
1534 */ 1540 */
1535 snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", 1541 snprintf(secondary_hwid, LINE_LEN / 2, "%s-%d",
1536 hwid, 1542 hwid,
1537 _getpid ()); 1543 _getpid());
1538 1544
1539 if (INVALID_HANDLE_VALUE == (handle = init_tun ())) 1545 if (INVALID_HANDLE_VALUE == (handle = init_tun()))
1540 { 1546 {
1541 fprintf (stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n", 1547 fprintf(stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n",
1542 hwid, 1548 hwid,
1543 argv[2], 1549 argv[2],
1544 argv[3], 1550 argv[3],
1545 argv[4], 1551 argv[4],
1546 argv[5]); 1552 argv[5]);
1547 global_ret = -1; 1553 global_ret = -1;
1548 goto cleanup; 1554 goto cleanup;
1549 } 1555 }
1550 1556
1551 fprintf (stderr, "DEBUG: Setting IPs, if needed\n"); 1557 fprintf(stderr, "DEBUG: Setting IPs, if needed\n");
1552 if (0 != strcmp (argv[2], "-")) 1558 if (0 != strcmp(argv[2], "-"))
1553 { 1559 {
1554 const char *address = argv[2]; 1560 const char *address = argv[2];
1555 long prefix_len = atol (argv[3]); 1561 long prefix_len = atol(argv[3]);
1556 1562
1557 if ((prefix_len < 1) || (prefix_len > 127)) 1563 if ((prefix_len < 1) || (prefix_len > 127))
1558 { 1564 {
1559 fprintf (stderr, "FATAL: ipv6 prefix_len out of range\n"); 1565 fprintf(stderr, "FATAL: ipv6 prefix_len out of range\n");
1560 global_ret = -1; 1566 global_ret = -1;
1561 goto cleanup; 1567 goto cleanup;
1562 } 1568 }
1563 1569
1564 fprintf (stderr, "DEBUG: Setting IP6 address: %s/%d\n",address,prefix_len); 1570 fprintf(stderr, "DEBUG: Setting IP6 address: %s/%d\n", address, prefix_len);
1565 if (0 != (global_ret = set_address6 (address, prefix_len))) 1571 if (0 != (global_ret = set_address6(address, prefix_len)))
1566 goto cleanup; 1572 goto cleanup;
1567 1573
1568 have_ip6 = TRUE; 1574 have_ip6 = TRUE;
1569 } 1575 }
1570 1576
1571 if (0 != strcmp (argv[4], "-")) 1577 if (0 != strcmp(argv[4], "-"))
1572 { 1578 {
1573 const char *address = argv[4]; 1579 const char *address = argv[4];
1574 const char *mask = argv[5]; 1580 const char *mask = argv[5];
1575 1581
1576 fprintf (stderr, "DEBUG: Setting IP4 address: %s/%s\n",address,mask); 1582 fprintf(stderr, "DEBUG: Setting IP4 address: %s/%s\n", address, mask);
1577 if (0 != (global_ret = set_address4 (address, mask))) 1583 if (0 != (global_ret = set_address4(address, mask)))
1578 goto cleanup; 1584 goto cleanup;
1579 1585
1580 have_ip4 = TRUE; 1586 have_ip4 = TRUE;
1581 } 1587 }
1582 1588
1583 run (handle); 1589 run(handle);
1584cleanup: 1590cleanup:
1585 1591
1586 if (have_ip4) 1592 if (have_ip4)
1587 { 1593 {
1588 const char *address = argv[4]; 1594 const char *address = argv[4];
1589 fprintf (stderr, "DEBUG: Removing IP4 address\n"); 1595 fprintf(stderr, "DEBUG: Removing IP4 address\n");
1590 remove_address4 (address); 1596 remove_address4(address);
1591 } 1597 }
1592 if (have_ip6) 1598 if (have_ip6)
1593 { 1599 {
1594 const char *address = argv[2]; 1600 const char *address = argv[2];
1595 fprintf (stderr, "DEBUG: Removing IP6 address\n"); 1601 fprintf(stderr, "DEBUG: Removing IP6 address\n");
1596 remove_address6 (address); 1602 remove_address6(address);
1597 } 1603 }
1598 1604
1599 fprintf (stderr, "DEBUG: removing interface\n"); 1605 fprintf(stderr, "DEBUG: removing interface\n");
1600 remove_interface (); 1606 remove_interface();
1601 fprintf (stderr, "DEBUG: graceful exit completed\n"); 1607 fprintf(stderr, "DEBUG: graceful exit completed\n");
1602 1608
1603 return global_ret; 1609 return global_ret;
1604} 1610}
diff --git a/src/vpn/gnunet-helper-vpn.c b/src/vpn/gnunet-helper-vpn.c
index e621b8716..4b4073418 100644
--- a/src/vpn/gnunet-helper-vpn.c
+++ b/src/vpn/gnunet-helper-vpn.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file vpn/gnunet-helper-vpn.c 22 * @file vpn/gnunet-helper-vpn.c
@@ -61,8 +61,7 @@
61/** 61/**
62 * This is in linux/include/net/ipv6.h, but not always exported... 62 * This is in linux/include/net/ipv6.h, but not always exported...
63 */ 63 */
64struct in6_ifreq 64struct in6_ifreq {
65{
66 struct in6_addr ifr6_addr; 65 struct in6_addr ifr6_addr;
67 uint32_t ifr6_prefixlen; 66 uint32_t ifr6_prefixlen;
68 unsigned int ifr6_ifindex; 67 unsigned int ifr6_ifindex;
@@ -78,55 +77,55 @@ struct in6_ifreq
78 * @return the fd to the tun or -1 on error 77 * @return the fd to the tun or -1 on error
79 */ 78 */
80static int 79static int
81init_tun (char *dev) 80init_tun(char *dev)
82{ 81{
83 struct ifreq ifr; 82 struct ifreq ifr;
84 int fd; 83 int fd;
85 84
86 if (NULL == dev) 85 if (NULL == dev)
87 { 86 {
88 errno = EINVAL; 87 errno = EINVAL;
89 return -1; 88 return -1;
90 } 89 }
91 90
92 if (-1 == (fd = open ("/dev/net/tun", O_RDWR))) 91 if (-1 == (fd = open("/dev/net/tun", O_RDWR)))
93 { 92 {
94 fprintf (stderr, 93 fprintf(stderr,
95 "Error opening `%s': %s\n", 94 "Error opening `%s': %s\n",
96 "/dev/net/tun", 95 "/dev/net/tun",
97 strerror (errno)); 96 strerror(errno));
98 return -1; 97 return -1;
99 } 98 }
100 99
101 if (fd >= FD_SETSIZE) 100 if (fd >= FD_SETSIZE)
102 { 101 {
103 fprintf (stderr, 102 fprintf(stderr,
104 "File descriptor to large: %d", 103 "File descriptor to large: %d",
105 fd); 104 fd);
106 (void) close (fd); 105 (void)close(fd);
107 return -1; 106 return -1;
108 } 107 }
109 108
110 memset (&ifr, 0, sizeof (ifr)); 109 memset(&ifr, 0, sizeof(ifr));
111 ifr.ifr_flags = IFF_TUN; 110 ifr.ifr_flags = IFF_TUN;
112 111
113 if ('\0' != *dev) 112 if ('\0' != *dev)
114 strncpy (ifr.ifr_name, 113 strncpy(ifr.ifr_name,
115 dev, 114 dev,
116 IFNAMSIZ); 115 IFNAMSIZ);
117 116
118 if (-1 == ioctl (fd, 117 if (-1 == ioctl(fd,
119 TUNSETIFF, 118 TUNSETIFF,
120 (void *) &ifr)) 119 (void *)&ifr))
121 { 120 {
122 fprintf (stderr, 121 fprintf(stderr,
123 "Error with ioctl on `%s': %s\n", 122 "Error with ioctl on `%s': %s\n",
124 "/dev/net/tun", 123 "/dev/net/tun",
125 strerror (errno)); 124 strerror(errno));
126 (void) close (fd); 125 (void)close(fd);
127 return -1; 126 return -1;
128 } 127 }
129 strcpy (dev, ifr.ifr_name); 128 strcpy(dev, ifr.ifr_name);
130 return fd; 129 return fd;
131} 130}
132 131
@@ -139,9 +138,9 @@ init_tun (char *dev)
139 * @param prefix_len the length of the network-prefix 138 * @param prefix_len the length of the network-prefix
140 */ 139 */
141static void 140static void
142set_address6 (const char *dev, 141set_address6(const char *dev,
143 const char *address, 142 const char *address,
144 unsigned long prefix_len) 143 unsigned long prefix_len)
145{ 144{
146 struct ifreq ifr; 145 struct ifreq ifr;
147 struct in6_ifreq ifr6; 146 struct in6_ifreq ifr6;
@@ -151,44 +150,44 @@ set_address6 (const char *dev,
151 /* 150 /*
152 * parse the new address 151 * parse the new address
153 */ 152 */
154 memset (&sa6, 0, sizeof (struct sockaddr_in6)); 153 memset(&sa6, 0, sizeof(struct sockaddr_in6));
155 sa6.sin6_family = AF_INET6; 154 sa6.sin6_family = AF_INET6;
156 if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) 155 if (1 != inet_pton(AF_INET6, address, sa6.sin6_addr.s6_addr))
157 { 156 {
158 fprintf (stderr, 157 fprintf(stderr,
159 "Failed to parse IPv6 address `%s'\n", 158 "Failed to parse IPv6 address `%s'\n",
160 address); 159 address);
161 exit (1); 160 exit(1);
162 } 161 }
163 162
164 if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) 163 if (-1 == (fd = socket(PF_INET6, SOCK_DGRAM, 0)))
165 { 164 {
166 fprintf (stderr, 165 fprintf(stderr,
167 "Error creating socket: %s\n", 166 "Error creating socket: %s\n",
168 strerror (errno)); 167 strerror(errno));
169 exit (1); 168 exit(1);
170 } 169 }
171 170
172 memset (&ifr, 0, sizeof (struct ifreq)); 171 memset(&ifr, 0, sizeof(struct ifreq));
173 /* 172 /*
174 * Get the index of the if 173 * Get the index of the if
175 */ 174 */
176 strncpy (ifr.ifr_name, 175 strncpy(ifr.ifr_name,
177 dev, 176 dev,
178 IFNAMSIZ); 177 IFNAMSIZ);
179 if (-1 == ioctl (fd, 178 if (-1 == ioctl(fd,
180 SIOGIFINDEX, 179 SIOGIFINDEX,
181 &ifr)) 180 &ifr))
182 { 181 {
183 fprintf (stderr, 182 fprintf(stderr,
184 "ioctl failed at %d: %s\n", 183 "ioctl failed at %d: %s\n",
185 __LINE__, 184 __LINE__,
186 strerror (errno)); 185 strerror(errno));
187 (void) close (fd); 186 (void)close(fd);
188 exit (1); 187 exit(1);
189 } 188 }
190 189
191 memset (&ifr6, 0, sizeof (struct in6_ifreq)); 190 memset(&ifr6, 0, sizeof(struct in6_ifreq));
192 ifr6.ifr6_addr = sa6.sin6_addr; 191 ifr6.ifr6_addr = sa6.sin6_addr;
193 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 192 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
194 ifr6.ifr6_prefixlen = prefix_len; 193 ifr6.ifr6_prefixlen = prefix_len;
@@ -196,56 +195,56 @@ set_address6 (const char *dev,
196 /* 195 /*
197 * Set the address 196 * Set the address
198 */ 197 */
199 if (-1 == ioctl (fd, 198 if (-1 == ioctl(fd,
200 SIOCSIFADDR, 199 SIOCSIFADDR,
201 &ifr6)) 200 &ifr6))
202 { 201 {
203 fprintf (stderr, 202 fprintf(stderr,
204 "ioctl failed at line %d: %s\n", 203 "ioctl failed at line %d: %s\n",
205 __LINE__, 204 __LINE__,
206 strerror (errno)); 205 strerror(errno));
207 (void) close (fd); 206 (void)close(fd);
208 exit (1); 207 exit(1);
209 } 208 }
210 209
211 /* 210 /*
212 * Get the flags 211 * Get the flags
213 */ 212 */
214 if (-1 == ioctl (fd, 213 if (-1 == ioctl(fd,
215 SIOCGIFFLAGS, 214 SIOCGIFFLAGS,
216 &ifr)) 215 &ifr))
217 { 216 {
218 fprintf (stderr, 217 fprintf(stderr,
219 "ioctl failed at line %d: %s\n", 218 "ioctl failed at line %d: %s\n",
220 __LINE__, 219 __LINE__,
221 strerror (errno)); 220 strerror(errno));
222 (void) close (fd); 221 (void)close(fd);
223 exit (1); 222 exit(1);
224 } 223 }
225 224
226 /* 225 /*
227 * Add the UP and RUNNING flags 226 * Add the UP and RUNNING flags
228 */ 227 */
229 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 228 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
230 if (-1 == ioctl (fd, 229 if (-1 == ioctl(fd,
231 SIOCSIFFLAGS, 230 SIOCSIFFLAGS,
232 &ifr)) 231 &ifr))
233 { 232 {
234 fprintf (stderr, 233 fprintf(stderr,
235 "ioctl failed at line %d: %s\n", 234 "ioctl failed at line %d: %s\n",
236 __LINE__, 235 __LINE__,
237 strerror (errno)); 236 strerror(errno));
238 (void) close (fd); 237 (void)close(fd);
239 exit (1); 238 exit(1);
240 } 239 }
241 240
242 if (0 != close (fd)) 241 if (0 != close(fd))
243 { 242 {
244 fprintf (stderr, 243 fprintf(stderr,
245 "close failed: %s\n", 244 "close failed: %s\n",
246 strerror (errno)); 245 strerror(errno));
247 exit (1); 246 exit(1);
248 } 247 }
249} 248}
250 249
251 250
@@ -257,117 +256,117 @@ set_address6 (const char *dev,
257 * @param mask the netmask 256 * @param mask the netmask
258 */ 257 */
259static void 258static void
260set_address4 (const char *dev, 259set_address4(const char *dev,
261 const char *address, 260 const char *address,
262 const char *mask) 261 const char *mask)
263{ 262{
264 int fd; 263 int fd;
265 struct sockaddr_in *addr; 264 struct sockaddr_in *addr;
266 struct ifreq ifr; 265 struct ifreq ifr;
267 266
268 memset (&ifr, 0, sizeof (struct ifreq)); 267 memset(&ifr, 0, sizeof(struct ifreq));
269 addr = (struct sockaddr_in *) &(ifr.ifr_addr); 268 addr = (struct sockaddr_in *)&(ifr.ifr_addr);
270 addr->sin_family = AF_INET; 269 addr->sin_family = AF_INET;
271 270
272 /* 271 /*
273 * Parse the address 272 * Parse the address
274 */ 273 */
275 if (1 != inet_pton (AF_INET, 274 if (1 != inet_pton(AF_INET,
276 address, 275 address,
277 &addr->sin_addr.s_addr)) 276 &addr->sin_addr.s_addr))
278 { 277 {
279 fprintf (stderr, 278 fprintf(stderr,
280 "Failed to parse IPv4 address `%s'\n", 279 "Failed to parse IPv4 address `%s'\n",
281 address); 280 address);
282 exit (1); 281 exit(1);
283 } 282 }
284 283
285 if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) 284 if (-1 == (fd = socket(PF_INET, SOCK_DGRAM, 0)))
286 { 285 {
287 fprintf (stderr, 286 fprintf(stderr,
288 "Error creating socket: %s\n", 287 "Error creating socket: %s\n",
289 strerror (errno)); 288 strerror(errno));
290 exit (1); 289 exit(1);
291 } 290 }
292 291
293 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 292 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
294 293
295 /* 294 /*
296 * Set the address 295 * Set the address
297 */ 296 */
298 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr)) 297 if (-1 == ioctl(fd, SIOCSIFADDR, &ifr))
299 { 298 {
300 fprintf (stderr, 299 fprintf(stderr,
301 "ioctl failed at %d: %s\n", 300 "ioctl failed at %d: %s\n",
302 __LINE__, 301 __LINE__,
303 strerror (errno)); 302 strerror(errno));
304 (void) close (fd); 303 (void)close(fd);
305 exit (1); 304 exit(1);
306 } 305 }
307 306
308 /* 307 /*
309 * Parse the netmask 308 * Parse the netmask
310 */ 309 */
311 addr = (struct sockaddr_in *) &(ifr.ifr_netmask); 310 addr = (struct sockaddr_in *)&(ifr.ifr_netmask);
312 if (1 != inet_pton (AF_INET, 311 if (1 != inet_pton(AF_INET,
313 mask, 312 mask,
314 &addr->sin_addr.s_addr)) 313 &addr->sin_addr.s_addr))
315 { 314 {
316 fprintf (stderr, 315 fprintf(stderr,
317 "Failed to parse IPv4 address mask `%s'\n", 316 "Failed to parse IPv4 address mask `%s'\n",
318 mask); 317 mask);
319 (void) close (fd); 318 (void)close(fd);
320 exit (1); 319 exit(1);
321 } 320 }
322 321
323 /* 322 /*
324 * Set the netmask 323 * Set the netmask
325 */ 324 */
326 if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr)) 325 if (-1 == ioctl(fd, SIOCSIFNETMASK, &ifr))
327 { 326 {
328 fprintf (stderr, 327 fprintf(stderr,
329 "ioctl failed at line %d: %s\n", 328 "ioctl failed at line %d: %s\n",
330 __LINE__, 329 __LINE__,
331 strerror (errno)); 330 strerror(errno));
332 (void) close (fd); 331 (void)close(fd);
333 exit (1); 332 exit(1);
334 } 333 }
335 334
336 /* 335 /*
337 * Get the flags 336 * Get the flags
338 */ 337 */
339 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) 338 if (-1 == ioctl(fd, SIOCGIFFLAGS, &ifr))
340 { 339 {
341 fprintf (stderr, 340 fprintf(stderr,
342 "ioctl failed at line %d: %s\n", 341 "ioctl failed at line %d: %s\n",
343 __LINE__, 342 __LINE__,
344 strerror (errno)); 343 strerror(errno));
345 (void) close (fd); 344 (void)close(fd);
346 exit (1); 345 exit(1);
347 } 346 }
348 347
349 /* 348 /*
350 * Add the UP and RUNNING flags 349 * Add the UP and RUNNING flags
351 */ 350 */
352 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 351 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
353 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) 352 if (-1 == ioctl(fd, SIOCSIFFLAGS, &ifr))
354 { 353 {
355 fprintf (stderr, 354 fprintf(stderr,
356 "ioctl failed at line %d: %s\n", 355 "ioctl failed at line %d: %s\n",
357 __LINE__, 356 __LINE__,
358 strerror (errno)); 357 strerror(errno));
359 (void) close (fd); 358 (void)close(fd);
360 exit (1); 359 exit(1);
361 } 360 }
362 361
363 if (0 != close (fd)) 362 if (0 != close(fd))
364 { 363 {
365 fprintf (stderr, 364 fprintf(stderr,
366 "close failed: %s\n", 365 "close failed: %s\n",
367 strerror (errno)); 366 strerror(errno));
368 (void) close (fd); 367 (void)close(fd);
369 exit (1); 368 exit(1);
370 } 369 }
371} 370}
372 371
373 372
@@ -377,7 +376,7 @@ set_address4 (const char *dev,
377 * @param fd_tun tunnel FD 376 * @param fd_tun tunnel FD
378 */ 377 */
379static void 378static void
380run (int fd_tun) 379run(int fd_tun)
381{ 380{
382 /* 381 /*
383 * The buffer filled by reading from fd_tun 382 * The buffer filled by reading from fd_tun
@@ -404,198 +403,198 @@ run (int fd_tun)
404 int write_open = 1; 403 int write_open = 1;
405 404
406 while ((1 == read_open) && (1 == write_open)) 405 while ((1 == read_open) && (1 == write_open))
407 {
408 FD_ZERO (&fds_w);
409 FD_ZERO (&fds_r);
410
411 /*
412 * We are supposed to read and the buffer is empty
413 * -> select on read from tun
414 */
415 if (read_open && (0 == buftun_size))
416 FD_SET (fd_tun, &fds_r);
417
418 /*
419 * We are supposed to read and the buffer is not empty
420 * -> select on write to stdout
421 */
422 if (read_open && (0 != buftun_size))
423 FD_SET (1, &fds_w);
424
425 /*
426 * We are supposed to write and the buffer is empty
427 * -> select on read from stdin
428 */
429 if (write_open && (NULL == bufin_read))
430 FD_SET (0, &fds_r);
431
432 /*
433 * We are supposed to write and the buffer is not empty
434 * -> select on write to tun
435 */
436 if (write_open && (NULL != bufin_read))
437 FD_SET (fd_tun, &fds_w);
438
439 int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
440
441 if (-1 == r)
442 {
443 if (EINTR == errno)
444 continue;
445 fprintf (stderr,
446 "select failed: %s\n",
447 strerror (errno));
448 exit (1);
449 }
450
451 if (r > 0)
452 { 406 {
453 if (FD_ISSET (fd_tun, &fds_r)) 407 FD_ZERO(&fds_w);
454 { 408 FD_ZERO(&fds_r);
455 buftun_size = 409
456 read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), 410 /*
457 MAX_SIZE - sizeof (struct GNUNET_MessageHeader)); 411 * We are supposed to read and the buffer is empty
458 if (-1 == buftun_size) 412 * -> select on read from tun
459 { 413 */
460 fprintf (stderr, 414 if (read_open && (0 == buftun_size))
461 "read-error: %s\n", 415 FD_SET(fd_tun, &fds_r);
462 strerror (errno)); 416
463 shutdown (fd_tun, SHUT_RD); 417 /*
464 shutdown (1, SHUT_WR); 418 * We are supposed to read and the buffer is not empty
465 read_open = 0; 419 * -> select on write to stdout
466 buftun_size = 0; 420 */
467 } 421 if (read_open && (0 != buftun_size))
468 else if (0 == buftun_size) 422 FD_SET(1, &fds_w);
469 { 423
470 fprintf (stderr, "EOF on tun\n"); 424 /*
471 shutdown (fd_tun, SHUT_RD); 425 * We are supposed to write and the buffer is empty
472 shutdown (1, SHUT_WR); 426 * -> select on read from stdin
473 read_open = 0; 427 */
474 buftun_size = 0; 428 if (write_open && (NULL == bufin_read))
475 } 429 FD_SET(0, &fds_r);
476 else 430
431 /*
432 * We are supposed to write and the buffer is not empty
433 * -> select on write to tun
434 */
435 if (write_open && (NULL != bufin_read))
436 FD_SET(fd_tun, &fds_w);
437
438 int r = select(fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
439
440 if (-1 == r)
477 { 441 {
478 buftun_read = buftun; 442 if (EINTR == errno)
479 struct GNUNET_MessageHeader *hdr = 443 continue;
480 (struct GNUNET_MessageHeader *) buftun; 444 fprintf(stderr,
481 buftun_size += sizeof (struct GNUNET_MessageHeader); 445 "select failed: %s\n",
482 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 446 strerror(errno));
483 hdr->size = htons (buftun_size); 447 exit(1);
484 } 448 }
485 } 449
486 else if (FD_ISSET (1, &fds_w)) 450 if (r > 0)
487 {
488 ssize_t written = write (1,
489 buftun_read,
490 buftun_size);
491
492 if (-1 == written)
493 { 451 {
452 if (FD_ISSET(fd_tun, &fds_r))
453 {
454 buftun_size =
455 read(fd_tun, buftun + sizeof(struct GNUNET_MessageHeader),
456 MAX_SIZE - sizeof(struct GNUNET_MessageHeader));
457 if (-1 == buftun_size)
458 {
459 fprintf(stderr,
460 "read-error: %s\n",
461 strerror(errno));
462 shutdown(fd_tun, SHUT_RD);
463 shutdown(1, SHUT_WR);
464 read_open = 0;
465 buftun_size = 0;
466 }
467 else if (0 == buftun_size)
468 {
469 fprintf(stderr, "EOF on tun\n");
470 shutdown(fd_tun, SHUT_RD);
471 shutdown(1, SHUT_WR);
472 read_open = 0;
473 buftun_size = 0;
474 }
475 else
476 {
477 buftun_read = buftun;
478 struct GNUNET_MessageHeader *hdr =
479 (struct GNUNET_MessageHeader *)buftun;
480 buftun_size += sizeof(struct GNUNET_MessageHeader);
481 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
482 hdr->size = htons(buftun_size);
483 }
484 }
485 else if (FD_ISSET(1, &fds_w))
486 {
487 ssize_t written = write(1,
488 buftun_read,
489 buftun_size);
490
491 if (-1 == written)
492 {
494#if !DEBUG 493#if !DEBUG
495 if (errno != EPIPE) 494 if (errno != EPIPE)
496#endif 495#endif
497 fprintf (stderr, 496 fprintf(stderr,
498 "write-error to stdout: %s\n", 497 "write-error to stdout: %s\n",
499 strerror (errno)); 498 strerror(errno));
500 shutdown (fd_tun, SHUT_RD); 499 shutdown(fd_tun, SHUT_RD);
501 shutdown (1, SHUT_WR); 500 shutdown(1, SHUT_WR);
502 read_open = 0; 501 read_open = 0;
503 buftun_size = 0; 502 buftun_size = 0;
504 } 503 }
505 else if (0 == written) 504 else if (0 == written)
506 { 505 {
507 fprintf (stderr, 506 fprintf(stderr,
508 "write returned 0!?\n"); 507 "write returned 0!?\n");
509 exit (1); 508 exit(1);
510 } 509 }
511 else 510 else
512 { 511 {
513 buftun_size -= written; 512 buftun_size -= written;
514 buftun_read += written; 513 buftun_read += written;
515 } 514 }
516 } 515 }
517 516
518 if (FD_ISSET (0, &fds_r)) 517 if (FD_ISSET(0, &fds_r))
519 { 518 {
520 bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos); 519 bufin_size = read(0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos);
521 if (-1 == bufin_size) 520 if (-1 == bufin_size)
522 { 521 {
523 fprintf (stderr, 522 fprintf(stderr,
524 "read-error: %s\n", 523 "read-error: %s\n",
525 strerror (errno)); 524 strerror(errno));
526 shutdown (0, SHUT_RD); 525 shutdown(0, SHUT_RD);
527 shutdown (fd_tun, SHUT_WR); 526 shutdown(fd_tun, SHUT_WR);
528 write_open = 0; 527 write_open = 0;
529 bufin_size = 0; 528 bufin_size = 0;
530 } 529 }
531 else if (0 == bufin_size) 530 else if (0 == bufin_size)
532 { 531 {
533#if DEBUG 532#if DEBUG
534 fprintf (stderr, "EOF on stdin\n"); 533 fprintf(stderr, "EOF on stdin\n");
535#endif 534#endif
536 shutdown (0, SHUT_RD); 535 shutdown(0, SHUT_RD);
537 shutdown (fd_tun, SHUT_WR); 536 shutdown(fd_tun, SHUT_WR);
538 write_open = 0; 537 write_open = 0;
539 bufin_size = 0; 538 bufin_size = 0;
540 } 539 }
541 else 540 else
542 { 541 {
543 struct GNUNET_MessageHeader *hdr; 542 struct GNUNET_MessageHeader *hdr;
544 543
545PROCESS_BUFFER: 544PROCESS_BUFFER:
546 bufin_rpos += bufin_size; 545 bufin_rpos += bufin_size;
547 if (bufin_rpos < sizeof (struct GNUNET_MessageHeader)) 546 if (bufin_rpos < sizeof(struct GNUNET_MessageHeader))
548 continue; 547 continue;
549 hdr = (struct GNUNET_MessageHeader *) bufin; 548 hdr = (struct GNUNET_MessageHeader *)bufin;
550 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) 549 if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
551 { 550 {
552 fprintf (stderr, 551 fprintf(stderr,
553 "protocol violation!\n"); 552 "protocol violation!\n");
554 exit (1); 553 exit(1);
555 } 554 }
556 if (ntohs (hdr->size) > bufin_rpos) 555 if (ntohs(hdr->size) > bufin_rpos)
557 continue; 556 continue;
558 bufin_read = bufin + sizeof (struct GNUNET_MessageHeader); 557 bufin_read = bufin + sizeof(struct GNUNET_MessageHeader);
559 bufin_size = ntohs (hdr->size) - sizeof (struct GNUNET_MessageHeader); 558 bufin_size = ntohs(hdr->size) - sizeof(struct GNUNET_MessageHeader);
560 bufin_rpos -= bufin_size + sizeof (struct GNUNET_MessageHeader); 559 bufin_rpos -= bufin_size + sizeof(struct GNUNET_MessageHeader);
560 }
561 }
562 else if (FD_ISSET(fd_tun, &fds_w))
563 {
564 ssize_t written = write(fd_tun,
565 bufin_read,
566 bufin_size);
567
568 if (-1 == written)
569 {
570 fprintf(stderr,
571 "write-error to tun: %s\n",
572 strerror(errno));
573 shutdown(0, SHUT_RD);
574 shutdown(fd_tun, SHUT_WR);
575 write_open = 0;
576 bufin_size = 0;
577 }
578 else if (0 == written)
579 {
580 fprintf(stderr, "write returned 0!?\n");
581 exit(1);
582 }
583 else
584 {
585 bufin_size -= written;
586 bufin_read += written;
587 if (0 == bufin_size)
588 {
589 memmove(bufin, bufin_read, bufin_rpos);
590 bufin_read = NULL; /* start reading again */
591 bufin_size = 0;
592 goto PROCESS_BUFFER;
593 }
594 }
595 }
561 } 596 }
562 }
563 else if (FD_ISSET (fd_tun, &fds_w))
564 {
565 ssize_t written = write (fd_tun,
566 bufin_read,
567 bufin_size);
568
569 if (-1 == written)
570 {
571 fprintf (stderr,
572 "write-error to tun: %s\n",
573 strerror (errno));
574 shutdown (0, SHUT_RD);
575 shutdown (fd_tun, SHUT_WR);
576 write_open = 0;
577 bufin_size = 0;
578 }
579 else if (0 == written)
580 {
581 fprintf (stderr, "write returned 0!?\n");
582 exit (1);
583 }
584 else
585 {
586 bufin_size -= written;
587 bufin_read += written;
588 if (0 == bufin_size)
589 {
590 memmove (bufin, bufin_read, bufin_rpos);
591 bufin_read = NULL; /* start reading again */
592 bufin_size = 0;
593 goto PROCESS_BUFFER;
594 }
595 }
596 }
597 } 597 }
598 }
599} 598}
600 599
601 600
@@ -611,92 +610,92 @@ PROCESS_BUFFER:
611 * 5: IPv4 netmask (255.255.0.0), ignored if #4 is "-" 610 * 5: IPv4 netmask (255.255.0.0), ignored if #4 is "-"
612 */ 611 */
613int 612int
614main (int argc, char **argv) 613main(int argc, char **argv)
615{ 614{
616 char dev[IFNAMSIZ]; 615 char dev[IFNAMSIZ];
617 int fd_tun; 616 int fd_tun;
618 int global_ret; 617 int global_ret;
619 618
620 if (6 != argc) 619 if (6 != argc)
621 { 620 {
622 fprintf (stderr, "Fatal: must supply 5 arguments!\n"); 621 fprintf(stderr, "Fatal: must supply 5 arguments!\n");
623 return 1; 622 return 1;
624 } 623 }
625 624
626 strncpy (dev, 625 strncpy(dev,
627 argv[1], 626 argv[1],
628 IFNAMSIZ); 627 IFNAMSIZ);
629 dev[IFNAMSIZ - 1] = '\0'; 628 dev[IFNAMSIZ - 1] = '\0';
630 629
631 if (-1 == (fd_tun = init_tun (dev))) 630 if (-1 == (fd_tun = init_tun(dev)))
632 {
633 fprintf (stderr,
634 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
635 dev,
636 argv[2],
637 argv[3],
638 argv[4],
639 argv[5]);
640 return 1;
641 }
642
643 if (0 != strcmp (argv[2], "-"))
644 {
645 const char *address = argv[2];
646 long prefix_len = atol (argv[3]);
647
648 if ((prefix_len < 1) || (prefix_len > 127))
649 { 631 {
650 fprintf (stderr, 632 fprintf(stderr,
651 "Fatal: prefix_len out of range\n"); 633 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
652 close (fd_tun); 634 dev,
635 argv[2],
636 argv[3],
637 argv[4],
638 argv[5]);
653 return 1; 639 return 1;
654 } 640 }
655 641
656 set_address6 (dev, 642 if (0 != strcmp(argv[2], "-"))
657 address, 643 {
658 prefix_len); 644 const char *address = argv[2];
659 } 645 long prefix_len = atol(argv[3]);
646
647 if ((prefix_len < 1) || (prefix_len > 127))
648 {
649 fprintf(stderr,
650 "Fatal: prefix_len out of range\n");
651 close(fd_tun);
652 return 1;
653 }
654
655 set_address6(dev,
656 address,
657 prefix_len);
658 }
660 659
661 if (0 != strcmp (argv[4], "-")) 660 if (0 != strcmp(argv[4], "-"))
662 { 661 {
663 const char *address = argv[4]; 662 const char *address = argv[4];
664 const char *mask = argv[5]; 663 const char *mask = argv[5];
665 664
666 set_address4 (dev, address, mask); 665 set_address4(dev, address, mask);
667 } 666 }
668 667
669 uid_t uid = getuid (); 668 uid_t uid = getuid();
670#ifdef HAVE_SETRESUID 669#ifdef HAVE_SETRESUID
671 if (0 != setresuid (uid, uid, uid)) 670 if (0 != setresuid(uid, uid, uid))
672 { 671 {
673 fprintf (stderr, 672 fprintf(stderr,
674 "Failed to setresuid: %s\n", 673 "Failed to setresuid: %s\n",
675 strerror (errno)); 674 strerror(errno));
676 global_ret = 2; 675 global_ret = 2;
677 goto cleanup; 676 goto cleanup;
678 } 677 }
679#else 678#else
680 if (0 != (setuid (uid) | seteuid (uid))) 679 if (0 != (setuid(uid) | seteuid(uid)))
681 { 680 {
682 fprintf (stderr, 681 fprintf(stderr,
683 "Failed to setuid: %s\n", 682 "Failed to setuid: %s\n",
684 strerror (errno)); 683 strerror(errno));
685 global_ret = 2; 684 global_ret = 2;
686 goto cleanup; 685 goto cleanup;
687 } 686 }
688#endif 687#endif
689 688
690 if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) 689 if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
691 { 690 {
692 fprintf (stderr, 691 fprintf(stderr,
693 "Failed to protect against SIGPIPE: %s\n", 692 "Failed to protect against SIGPIPE: %s\n",
694 strerror (errno)); 693 strerror(errno));
695 /* no exit, we might as well die with SIGPIPE should it ever happen */ 694 /* no exit, we might as well die with SIGPIPE should it ever happen */
696 } 695 }
697 run (fd_tun); 696 run(fd_tun);
698 global_ret = 0; 697 global_ret = 0;
699 cleanup: 698cleanup:
700 close (fd_tun); 699 close(fd_tun);
701 return global_ret; 700 return global_ret;
702} 701}
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index e2d8a8e50..4c042ea80 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file vpn/gnunet-service-vpn.c 22 * @file vpn/gnunet-service-vpn.c
@@ -65,9 +65,7 @@ struct DestinationEntry;
65 * List of channels we keep for each destination port for a given 65 * List of channels we keep for each destination port for a given
66 * destination entry. 66 * destination entry.
67 */ 67 */
68struct DestinationChannel 68struct DestinationChannel {
69{
70
71 /** 69 /**
72 * Kept in a DLL. 70 * Kept in a DLL.
73 */ 71 */
@@ -94,9 +92,7 @@ struct DestinationChannel
94 * Information we track for each IP address to determine which channel 92 * Information we track for each IP address to determine which channel
95 * to send the traffic over to the destination. 93 * to send the traffic over to the destination.
96 */ 94 */
97struct DestinationEntry 95struct DestinationEntry {
98{
99
100 /** 96 /**
101 * Key under which this entry is in the 'destination_map' (only valid 97 * Key under which this entry is in the 'destination_map' (only valid
102 * if 'heap_node != NULL'). 98 * if 'heap_node != NULL').
@@ -127,11 +123,8 @@ struct DestinationEntry
127 /** 123 /**
128 * Details about the connection (depending on is_service). 124 * Details about the connection (depending on is_service).
129 */ 125 */
130 union 126 union {
131 { 127 struct {
132
133 struct
134 {
135 /** 128 /**
136 * The description of the service (only used for service channels). 129 * The description of the service (only used for service channels).
137 */ 130 */
@@ -141,12 +134,9 @@ struct DestinationEntry
141 * Peer offering the service. 134 * Peer offering the service.
142 */ 135 */
143 struct GNUNET_PeerIdentity target; 136 struct GNUNET_PeerIdentity target;
144
145 } service_destination; 137 } service_destination;
146 138
147 struct 139 struct {
148 {
149
150 /** 140 /**
151 * Address family used (AF_INET or AF_INET6). 141 * Address family used (AF_INET or AF_INET6).
152 */ 142 */
@@ -155,21 +145,18 @@ struct DestinationEntry
155 /** 145 /**
156 * IP address of the ultimate destination (only used for exit channels). 146 * IP address of the ultimate destination (only used for exit channels).
157 */ 147 */
158 union 148 union {
159 {
160 /** 149 /**
161 * Address if af is AF_INET. 150 * Address if af is AF_INET.
162 */ 151 */
163 struct in_addr v4; 152 struct in_addr v4;
164 153
165 /** 154 /**
166 * Address if af is AF_INET6. 155 * Address if af is AF_INET6.
167 */ 156 */
168 struct in6_addr v6; 157 struct in6_addr v6;
169 } ip; 158 } ip;
170
171 } exit_destination; 159 } exit_destination;
172
173 } details; 160 } details;
174}; 161};
175 162
@@ -177,8 +164,7 @@ struct DestinationEntry
177/** 164/**
178 * A messages we have in queue for a particular channel. 165 * A messages we have in queue for a particular channel.
179 */ 166 */
180struct ChannelMessageQueueEntry 167struct ChannelMessageQueueEntry {
181{
182 /** 168 /**
183 * This is a doubly-linked list. 169 * This is a doubly-linked list.
184 */ 170 */
@@ -204,9 +190,7 @@ struct ChannelMessageQueueEntry
204/** 190/**
205 * State we keep for each of our channels. 191 * State we keep for each of our channels.
206 */ 192 */
207struct ChannelState 193struct ChannelState {
208{
209
210 /** 194 /**
211 * Information about the channel to use, NULL if no channel 195 * Information about the channel to use, NULL if no channel
212 * is available right now. 196 * is available right now.
@@ -266,8 +250,7 @@ struct ChannelState
266 /** 250 /**
267 * IP address of the source on our end, initially uninitialized. 251 * IP address of the source on our end, initially uninitialized.
268 */ 252 */
269 union 253 union {
270 {
271 /** 254 /**
272 * Address if af is AF_INET. 255 * Address if af is AF_INET.
273 */ 256 */
@@ -277,15 +260,13 @@ struct ChannelState
277 * Address if af is AF_INET6. 260 * Address if af is AF_INET6.
278 */ 261 */
279 struct in6_addr v6; 262 struct in6_addr v6;
280
281 } source_ip; 263 } source_ip;
282 264
283 /** 265 /**
284 * Destination IP address used by the source on our end (this is the IP 266 * Destination IP address used by the source on our end (this is the IP
285 * that we pick freely within the VPN's channel IP range). 267 * that we pick freely within the VPN's channel IP range).
286 */ 268 */
287 union 269 union {
288 {
289 /** 270 /**
290 * Address if af is AF_INET. 271 * Address if af is AF_INET.
291 */ 272 */
@@ -295,7 +276,6 @@ struct ChannelState
295 * Address if af is AF_INET6. 276 * Address if af is AF_INET6.
296 */ 277 */
297 struct in6_addr v6; 278 struct in6_addr v6;
298
299 } destination_ip; 279 } destination_ip;
300 280
301 /** 281 /**
@@ -390,22 +370,24 @@ static unsigned long long max_channel_mappings;
390 * @param key where to store the key 370 * @param key where to store the key
391 */ 371 */
392static void 372static void
393get_destination_key_from_ip (int af, 373get_destination_key_from_ip(int af,
394 const void *address, 374 const void *address,
395 struct GNUNET_HashCode *key) 375 struct GNUNET_HashCode *key)
396{ 376{
397 switch (af) 377 switch (af)
398 { 378 {
399 case AF_INET: 379 case AF_INET:
400 GNUNET_CRYPTO_hash (address, sizeof (struct in_addr), key); 380 GNUNET_CRYPTO_hash(address, sizeof(struct in_addr), key);
401 break; 381 break;
402 case AF_INET6: 382
403 GNUNET_CRYPTO_hash (address, sizeof (struct in6_addr), key); 383 case AF_INET6:
404 break; 384 GNUNET_CRYPTO_hash(address, sizeof(struct in6_addr), key);
405 default: 385 break;
406 GNUNET_assert (0); 386
407 break; 387 default:
408 } 388 GNUNET_assert(0);
389 break;
390 }
409} 391}
410 392
411 393
@@ -422,43 +404,45 @@ get_destination_key_from_ip (int af,
422 * @param key where to store the key 404 * @param key where to store the key
423 */ 405 */
424static void 406static void
425get_channel_key_from_ips (int af, 407get_channel_key_from_ips(int af,
426 uint8_t protocol, 408 uint8_t protocol,
427 const void *source_ip, 409 const void *source_ip,
428 uint16_t source_port, 410 uint16_t source_port,
429 const void *destination_ip, 411 const void *destination_ip,
430 uint16_t destination_port, 412 uint16_t destination_port,
431 struct GNUNET_HashCode *key) 413 struct GNUNET_HashCode *key)
432{ 414{
433 char *off; 415 char *off;
434 416
435 memset (key, 0, sizeof (struct GNUNET_HashCode)); 417 memset(key, 0, sizeof(struct GNUNET_HashCode));
436 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash, 418 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
437 so we put the ports in there (and hope for few collisions) */ 419 so we put the ports in there (and hope for few collisions) */
438 off = (char *) key; 420 off = (char *)key;
439 GNUNET_memcpy (off, &source_port, sizeof (uint16_t)); 421 GNUNET_memcpy(off, &source_port, sizeof(uint16_t));
440 off += sizeof (uint16_t); 422 off += sizeof(uint16_t);
441 GNUNET_memcpy (off, &destination_port, sizeof (uint16_t)); 423 GNUNET_memcpy(off, &destination_port, sizeof(uint16_t));
442 off += sizeof (uint16_t); 424 off += sizeof(uint16_t);
443 switch (af) 425 switch (af)
444 { 426 {
445 case AF_INET: 427 case AF_INET:
446 GNUNET_memcpy (off, source_ip, sizeof (struct in_addr)); 428 GNUNET_memcpy(off, source_ip, sizeof(struct in_addr));
447 off += sizeof (struct in_addr); 429 off += sizeof(struct in_addr);
448 GNUNET_memcpy (off, destination_ip, sizeof (struct in_addr)); 430 GNUNET_memcpy(off, destination_ip, sizeof(struct in_addr));
449 off += sizeof (struct in_addr); 431 off += sizeof(struct in_addr);
450 break; 432 break;
451 case AF_INET6: 433
452 GNUNET_memcpy (off, source_ip, sizeof (struct in6_addr)); 434 case AF_INET6:
453 off += sizeof (struct in6_addr); 435 GNUNET_memcpy(off, source_ip, sizeof(struct in6_addr));
454 GNUNET_memcpy (off, destination_ip, sizeof (struct in6_addr)); 436 off += sizeof(struct in6_addr);
455 off += sizeof (struct in6_addr); 437 GNUNET_memcpy(off, destination_ip, sizeof(struct in6_addr));
456 break; 438 off += sizeof(struct in6_addr);
457 default: 439 break;
458 GNUNET_assert (0); 440
459 break; 441 default:
460 } 442 GNUNET_assert(0);
461 GNUNET_memcpy (off, &protocol, sizeof (uint8_t)); 443 break;
444 }
445 GNUNET_memcpy(off, &protocol, sizeof(uint8_t));
462 /* off += sizeof (uint8_t); */ 446 /* off += sizeof (uint8_t); */
463} 447}
464 448
@@ -472,35 +456,38 @@ get_channel_key_from_ips (int af,
472 * @param addr resulting IP address 456 * @param addr resulting IP address
473 */ 457 */
474static void 458static void
475send_client_reply (struct GNUNET_SERVICE_Client *client, 459send_client_reply(struct GNUNET_SERVICE_Client *client,
476 uint64_t request_id, 460 uint64_t request_id,
477 int result_af, 461 int result_af,
478 const void *addr) 462 const void *addr)
479{ 463{
480 struct GNUNET_MQ_Envelope *env; 464 struct GNUNET_MQ_Envelope *env;
481 struct RedirectToIpResponseMessage *res; 465 struct RedirectToIpResponseMessage *res;
482 size_t rlen; 466 size_t rlen;
483 467
484 switch (result_af) 468 switch (result_af)
485 { 469 {
486 case AF_INET: 470 case AF_INET:
487 rlen = sizeof (struct in_addr); 471 rlen = sizeof(struct in_addr);
488 break; 472 break;
489 case AF_INET6: 473
490 rlen = sizeof (struct in6_addr); 474 case AF_INET6:
491 break; 475 rlen = sizeof(struct in6_addr);
492 case AF_UNSPEC: 476 break;
493 rlen = 0; 477
494 break; 478 case AF_UNSPEC:
495 default: 479 rlen = 0;
496 GNUNET_assert (0); 480 break;
497 return; 481
498 } 482 default:
499 env = GNUNET_MQ_msg_extra (res, rlen, GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP); 483 GNUNET_assert(0);
500 res->result_af = htonl (result_af); 484 return;
485 }
486 env = GNUNET_MQ_msg_extra(res, rlen, GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
487 res->result_af = htonl(result_af);
501 res->request_id = request_id; 488 res->request_id = request_id;
502 GNUNET_memcpy (&res[1], addr, rlen); 489 GNUNET_memcpy(&res[1], addr, rlen);
503 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); 490 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env);
504} 491}
505 492
506 493
@@ -510,52 +497,52 @@ send_client_reply (struct GNUNET_SERVICE_Client *client,
510 * @param ts state to free 497 * @param ts state to free
511 */ 498 */
512static void 499static void
513free_channel_state (struct ChannelState *ts) 500free_channel_state(struct ChannelState *ts)
514{ 501{
515 struct GNUNET_HashCode key; 502 struct GNUNET_HashCode key;
516 struct ChannelMessageQueueEntry *tnq; 503 struct ChannelMessageQueueEntry *tnq;
517 struct GNUNET_CADET_Channel *channel; 504 struct GNUNET_CADET_Channel *channel;
518 505
519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n"); 506 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n");
520 if (NULL != (channel = ts->channel)) 507 if (NULL != (channel = ts->channel))
521 { 508 {
522 ts->channel = NULL; 509 ts->channel = NULL;
523 GNUNET_CADET_channel_destroy (channel); 510 GNUNET_CADET_channel_destroy(channel);
524 return; 511 return;
525 } 512 }
526 GNUNET_STATISTICS_update (stats, 513 GNUNET_STATISTICS_update(stats,
527 gettext_noop ("# Active channels"), 514 gettext_noop("# Active channels"),
528 -1, 515 -1,
529 GNUNET_NO); 516 GNUNET_NO);
530 while (NULL != (tnq = ts->tmq_head)) 517 while (NULL != (tnq = ts->tmq_head))
531 { 518 {
532 GNUNET_CONTAINER_DLL_remove (ts->tmq_head, ts->tmq_tail, tnq); 519 GNUNET_CONTAINER_DLL_remove(ts->tmq_head, ts->tmq_tail, tnq);
533 ts->tmq_length--; 520 ts->tmq_length--;
534 GNUNET_free (tnq); 521 GNUNET_free(tnq);
535 } 522 }
536 GNUNET_assert (0 == ts->tmq_length); 523 GNUNET_assert(0 == ts->tmq_length);
537 GNUNET_assert (NULL == ts->destination.heap_node); 524 GNUNET_assert(NULL == ts->destination.heap_node);
538 if (NULL != ts->search) 525 if (NULL != ts->search)
539 { 526 {
540 GNUNET_REGEX_search_cancel (ts->search); 527 GNUNET_REGEX_search_cancel(ts->search);
541 ts->search = NULL; 528 ts->search = NULL;
542 } 529 }
543 if (NULL != ts->heap_node) 530 if (NULL != ts->heap_node)
544 { 531 {
545 GNUNET_CONTAINER_heap_remove_node (ts->heap_node); 532 GNUNET_CONTAINER_heap_remove_node(ts->heap_node);
546 ts->heap_node = NULL; 533 ts->heap_node = NULL;
547 get_channel_key_from_ips (ts->af, 534 get_channel_key_from_ips(ts->af,
548 ts->protocol, 535 ts->protocol,
549 &ts->source_ip, 536 &ts->source_ip,
550 ts->source_port, 537 ts->source_port,
551 &ts->destination_ip, 538 &ts->destination_ip,
552 ts->destination_port, 539 ts->destination_port,
553 &key); 540 &key);
554 GNUNET_assert ( 541 GNUNET_assert(
555 GNUNET_YES == 542 GNUNET_YES ==
556 GNUNET_CONTAINER_multihashmap_remove (channel_map, &key, ts)); 543 GNUNET_CONTAINER_multihashmap_remove(channel_map, &key, ts));
557 } 544 }
558 GNUNET_free (ts); 545 GNUNET_free(ts);
559} 546}
560 547
561 548
@@ -567,27 +554,27 @@ free_channel_state (struct ChannelState *ts)
567 * @param env message to queue 554 * @param env message to queue
568 */ 555 */
569static void 556static void
570send_to_channel (struct ChannelState *ts, struct GNUNET_MQ_Envelope *env) 557send_to_channel(struct ChannelState *ts, struct GNUNET_MQ_Envelope *env)
571{ 558{
572 struct GNUNET_MQ_Handle *mq; 559 struct GNUNET_MQ_Handle *mq;
573 560
574 GNUNET_assert (NULL != ts->channel); 561 GNUNET_assert(NULL != ts->channel);
575 mq = GNUNET_CADET_get_mq (ts->channel); 562 mq = GNUNET_CADET_get_mq(ts->channel);
576 GNUNET_MQ_env_set_options (env, 563 GNUNET_MQ_env_set_options(env,
577 GNUNET_MQ_PRIO_BEST_EFFORT | 564 GNUNET_MQ_PRIO_BEST_EFFORT |
578 GNUNET_MQ_PREF_OUT_OF_ORDER); 565 GNUNET_MQ_PREF_OUT_OF_ORDER);
579 GNUNET_MQ_send (mq, env); 566 GNUNET_MQ_send(mq, env);
580 if (GNUNET_MQ_get_length (mq) > MAX_MESSAGE_QUEUE_SIZE) 567 if (GNUNET_MQ_get_length(mq) > MAX_MESSAGE_QUEUE_SIZE)
581 { 568 {
582 env = GNUNET_MQ_unsent_head (mq); 569 env = GNUNET_MQ_unsent_head(mq);
583 GNUNET_assert (NULL != env); 570 GNUNET_assert(NULL != env);
584 GNUNET_STATISTICS_update (stats, 571 GNUNET_STATISTICS_update(stats,
585 gettext_noop ( 572 gettext_noop(
586 "# Messages dropped in cadet queue (overflow)"), 573 "# Messages dropped in cadet queue (overflow)"),
587 1, 574 1,
588 GNUNET_NO); 575 GNUNET_NO);
589 GNUNET_MQ_discard (env); 576 GNUNET_MQ_discard(env);
590 } 577 }
591} 578}
592 579
593 580
@@ -598,26 +585,26 @@ send_to_channel (struct ChannelState *ts, struct GNUNET_MQ_Envelope *env)
598 * @return diagnostic string describing destination 585 * @return diagnostic string describing destination
599 */ 586 */
600static const char * 587static const char *
601print_channel_destination (const struct DestinationEntry *de) 588print_channel_destination(const struct DestinationEntry *de)
602{ 589{
603 static char dest[256]; 590 static char dest[256];
604 591
605 if (de->is_service) 592 if (de->is_service)
606 { 593 {
607 GNUNET_snprintf (dest, 594 GNUNET_snprintf(dest,
608 sizeof (dest), 595 sizeof(dest),
609 "HS: %s-%s", 596 "HS: %s-%s",
610 GNUNET_i2s (&de->details.service_destination.target), 597 GNUNET_i2s(&de->details.service_destination.target),
611 GNUNET_h2s ( 598 GNUNET_h2s(
612 &de->details.service_destination.service_descriptor)); 599 &de->details.service_destination.service_descriptor));
613 } 600 }
614 else 601 else
615 { 602 {
616 inet_ntop (de->details.exit_destination.af, 603 inet_ntop(de->details.exit_destination.af,
617 &de->details.exit_destination.ip, 604 &de->details.exit_destination.ip,
618 dest, 605 dest,
619 sizeof (dest)); 606 sizeof(dest));
620 } 607 }
621 return dest; 608 return dest;
622} 609}
623 610
@@ -630,16 +617,16 @@ print_channel_destination (const struct DestinationEntry *de)
630 * @param channel connection to the other end (henceforth invalid) 617 * @param channel connection to the other end (henceforth invalid)
631 */ 618 */
632static void 619static void
633channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel) 620channel_cleaner(void *cls, const struct GNUNET_CADET_Channel *channel)
634{ 621{
635 struct ChannelState *ts = cls; 622 struct ChannelState *ts = cls;
636 623
637 ts->channel = 624 ts->channel =
638 NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */ 625 NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 626 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
640 "CADET notified us about death of channel to `%s'\n", 627 "CADET notified us about death of channel to `%s'\n",
641 print_channel_destination (&ts->destination)); 628 print_channel_destination(&ts->destination));
642 free_channel_state (ts); 629 free_channel_state(ts);
643} 630}
644 631
645 632
@@ -653,19 +640,19 @@ channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel)
653 * also be the first 8 bytes of the TCP header 640 * also be the first 8 bytes of the TCP header
654 */ 641 */
655static void 642static void
656make_up_icmpv4_payload (struct ChannelState *ts, 643make_up_icmpv4_payload(struct ChannelState *ts,
657 struct GNUNET_TUN_IPv4Header *ipp, 644 struct GNUNET_TUN_IPv4Header *ipp,
658 struct GNUNET_TUN_UdpHeader *udp) 645 struct GNUNET_TUN_UdpHeader *udp)
659{ 646{
660 GNUNET_TUN_initialize_ipv4_header (ipp, 647 GNUNET_TUN_initialize_ipv4_header(ipp,
661 ts->protocol, 648 ts->protocol,
662 sizeof (struct GNUNET_TUN_TcpHeader), 649 sizeof(struct GNUNET_TUN_TcpHeader),
663 &ts->source_ip.v4, 650 &ts->source_ip.v4,
664 &ts->destination_ip.v4); 651 &ts->destination_ip.v4);
665 udp->source_port = htons (ts->source_port); 652 udp->source_port = htons(ts->source_port);
666 udp->destination_port = htons (ts->destination_port); 653 udp->destination_port = htons(ts->destination_port);
667 udp->len = htons (0); 654 udp->len = htons(0);
668 udp->crc = htons (0); 655 udp->crc = htons(0);
669} 656}
670 657
671 658
@@ -679,19 +666,19 @@ make_up_icmpv4_payload (struct ChannelState *ts,
679 * also be the first 8 bytes of the TCP header 666 * also be the first 8 bytes of the TCP header
680 */ 667 */
681static void 668static void
682make_up_icmpv6_payload (struct ChannelState *ts, 669make_up_icmpv6_payload(struct ChannelState *ts,
683 struct GNUNET_TUN_IPv6Header *ipp, 670 struct GNUNET_TUN_IPv6Header *ipp,
684 struct GNUNET_TUN_UdpHeader *udp) 671 struct GNUNET_TUN_UdpHeader *udp)
685{ 672{
686 GNUNET_TUN_initialize_ipv6_header (ipp, 673 GNUNET_TUN_initialize_ipv6_header(ipp,
687 ts->protocol, 674 ts->protocol,
688 sizeof (struct GNUNET_TUN_TcpHeader), 675 sizeof(struct GNUNET_TUN_TcpHeader),
689 &ts->source_ip.v6, 676 &ts->source_ip.v6,
690 &ts->destination_ip.v6); 677 &ts->destination_ip.v6);
691 udp->source_port = htons (ts->source_port); 678 udp->source_port = htons(ts->source_port);
692 udp->destination_port = htons (ts->destination_port); 679 udp->destination_port = htons(ts->destination_port);
693 udp->len = htons (0); 680 udp->len = htons(0);
694 udp->crc = htons (0); 681 udp->crc = htons(0);
695} 682}
696 683
697 684
@@ -704,20 +691,20 @@ make_up_icmpv6_payload (struct ChannelState *ts,
704 * #GNUNET_SYSERR to close it (signal serious error) 691 * #GNUNET_SYSERR to close it (signal serious error)
705 */ 692 */
706static int 693static int
707check_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) 694check_icmp_back(void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
708{ 695{
709 struct ChannelState *ts = cls; 696 struct ChannelState *ts = cls;
710 697
711 if (NULL == ts->heap_node) 698 if (NULL == ts->heap_node)
712 { 699 {
713 GNUNET_break_op (0); 700 GNUNET_break_op(0);
714 return GNUNET_SYSERR; 701 return GNUNET_SYSERR;
715 } 702 }
716 if (AF_UNSPEC == ts->af) 703 if (AF_UNSPEC == ts->af)
717 { 704 {
718 GNUNET_break_op (0); 705 GNUNET_break_op(0);
719 return GNUNET_SYSERR; 706 return GNUNET_SYSERR;
720 } 707 }
721 return GNUNET_OK; 708 return GNUNET_OK;
722} 709}
723 710
@@ -730,324 +717,344 @@ check_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
730 * @param message the actual message 717 * @param message the actual message
731 */ 718 */
732static void 719static void
733handle_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) 720handle_icmp_back(void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
734{ 721{
735 struct ChannelState *ts = cls; 722 struct ChannelState *ts = cls;
736 size_t mlen; 723 size_t mlen;
737 724
738 GNUNET_STATISTICS_update (stats, 725 GNUNET_STATISTICS_update(stats,
739 gettext_noop ("# ICMP packets received from cadet"), 726 gettext_noop("# ICMP packets received from cadet"),
740 1, 727 1,
741 GNUNET_NO); 728 GNUNET_NO);
742 mlen = 729 mlen =
743 ntohs (i2v->header.size) - sizeof (struct GNUNET_EXIT_IcmpToVPNMessage); 730 ntohs(i2v->header.size) - sizeof(struct GNUNET_EXIT_IcmpToVPNMessage);
744 { 731 {
745 char sbuf[INET6_ADDRSTRLEN]; 732 char sbuf[INET6_ADDRSTRLEN];
746 char dbuf[INET6_ADDRSTRLEN]; 733 char dbuf[INET6_ADDRSTRLEN];
747 734
748 GNUNET_log ( 735 GNUNET_log(
749 GNUNET_ERROR_TYPE_DEBUG, 736 GNUNET_ERROR_TYPE_DEBUG,
750 "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n", 737 "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
751 (unsigned int) mlen, 738 (unsigned int)mlen,
752 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), 739 inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
753 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf))); 740 inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)));
754 } 741 }
755 switch (ts->af) 742 switch (ts->af)
756 {
757 case AF_INET: {
758 size_t size = sizeof (struct GNUNET_TUN_IPv4Header) +
759 sizeof (struct GNUNET_TUN_IcmpHeader) +
760 sizeof (struct GNUNET_MessageHeader) +
761 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
762 { 743 {
763 /* reserve some extra space in case we have an ICMP type here where 744 case AF_INET: {
764 we will need to make up the payload ourselves */ 745 size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
765 char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN; 746 sizeof(struct GNUNET_TUN_IcmpHeader) +
766 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 747 sizeof(struct GNUNET_MessageHeader) +
767 struct GNUNET_TUN_Layer2PacketHeader *tun = 748 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
768 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
769 struct GNUNET_TUN_IPv4Header *ipv4 =
770 (struct GNUNET_TUN_IPv4Header *) &tun[1];
771 struct GNUNET_TUN_IcmpHeader *icmp =
772 (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
773 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
774 tun->flags = htons (0);
775 tun->proto = htons (ETH_P_IPV4);
776 GNUNET_TUN_initialize_ipv4_header (ipv4,
777 IPPROTO_ICMP,
778 sizeof (struct GNUNET_TUN_IcmpHeader) +
779 mlen,
780 &ts->destination_ip.v4,
781 &ts->source_ip.v4);
782 *icmp = i2v->icmp_header;
783 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
784 /* For some ICMP types, we need to adjust (make up) the payload here.
785 Also, depending on the AF used on the other side, we have to
786 do ICMP PT (translate ICMP types) */
787 switch (ntohl (i2v->af))
788 { 749 {
789 case AF_INET: 750 /* reserve some extra space in case we have an ICMP type here where
790 switch (icmp->type) 751 we will need to make up the payload ourselves */
791 { 752 char buf[size + sizeof(struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
792 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: 753 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
793 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: 754 struct GNUNET_TUN_Layer2PacketHeader *tun =
794 break; 755 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
795 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: 756 struct GNUNET_TUN_IPv4Header *ipv4 =
796 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 757 (struct GNUNET_TUN_IPv4Header *)&tun[1];
797 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: { 758 struct GNUNET_TUN_IcmpHeader *icmp =
798 struct GNUNET_TUN_IPv4Header *ipp = 759 (struct GNUNET_TUN_IcmpHeader *)&ipv4[1];
799 (struct GNUNET_TUN_IPv4Header *) &icmp[1]; 760 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
800 struct GNUNET_TUN_UdpHeader *udp = 761 tun->flags = htons(0);
801 (struct GNUNET_TUN_UdpHeader *) &ipp[1]; 762 tun->proto = htons(ETH_P_IPV4);
802 763 GNUNET_TUN_initialize_ipv4_header(ipv4,
803 if (mlen != 0) 764 IPPROTO_ICMP,
765 sizeof(struct GNUNET_TUN_IcmpHeader) +
766 mlen,
767 &ts->destination_ip.v4,
768 &ts->source_ip.v4);
769 *icmp = i2v->icmp_header;
770 GNUNET_memcpy(&icmp[1], &i2v[1], mlen);
771 /* For some ICMP types, we need to adjust (make up) the payload here.
772 Also, depending on the AF used on the other side, we have to
773 do ICMP PT (translate ICMP types) */
774 switch (ntohl(i2v->af))
804 { 775 {
805 /* sender did not strip ICMP payload? */ 776 case AF_INET:
806 GNUNET_break_op (0); 777 switch (icmp->type)
778 {
779 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
780 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
781 break;
782
783 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
784 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
785 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: {
786 struct GNUNET_TUN_IPv4Header *ipp =
787 (struct GNUNET_TUN_IPv4Header *)&icmp[1];
788 struct GNUNET_TUN_UdpHeader *udp =
789 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
790
791 if (mlen != 0)
792 {
793 /* sender did not strip ICMP payload? */
794 GNUNET_break_op(0);
795 return;
796 }
797 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
798 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
799 make_up_icmpv4_payload(ts, ipp, udp);
800 }
801 break;
802
803 default:
804 GNUNET_break_op(0);
805 GNUNET_STATISTICS_update(
806 stats,
807 gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
808 1,
809 GNUNET_NO);
810 return;
811 }
812 /* end AF_INET */
813 break;
814
815 case AF_INET6:
816 /* ICMP PT 6-to-4 and possibly making up payloads */
817 switch (icmp->type)
818 {
819 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
820 icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
821 {
822 struct GNUNET_TUN_IPv4Header *ipp =
823 (struct GNUNET_TUN_IPv4Header *)&icmp[1];
824 struct GNUNET_TUN_UdpHeader *udp =
825 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
826
827 if (mlen != 0)
828 {
829 /* sender did not strip ICMP payload? */
830 GNUNET_break_op(0);
831 return;
832 }
833 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
834 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
835 make_up_icmpv4_payload(ts, ipp, udp);
836 }
837 break;
838
839 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
840 icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
841 {
842 struct GNUNET_TUN_IPv4Header *ipp =
843 (struct GNUNET_TUN_IPv4Header *)&icmp[1];
844 struct GNUNET_TUN_UdpHeader *udp =
845 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
846
847 if (mlen != 0)
848 {
849 /* sender did not strip ICMP payload? */
850 GNUNET_break_op(0);
851 return;
852 }
853 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
854 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
855 make_up_icmpv4_payload(ts, ipp, udp);
856 }
857 break;
858
859 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
860 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
861 GNUNET_STATISTICS_update(
862 stats,
863 gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
864 1,
865 GNUNET_NO);
866 return;
867
868 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
869 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
870 break;
871
872 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
873 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
874 break;
875
876 default:
877 GNUNET_break_op(0);
878 GNUNET_STATISTICS_update(
879 stats,
880 gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
881 1,
882 GNUNET_NO);
883 return;
884 }
885 /* end AF_INET6 */
886 break;
887
888 default:
889 GNUNET_break_op(0);
807 return; 890 return;
808 } 891 }
809 size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; 892 msg->size = htons(size);
810 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 893 GNUNET_TUN_calculate_icmp_checksum(icmp, &i2v[1], mlen);
811 make_up_icmpv4_payload (ts, ipp, udp); 894 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
812 }
813 break;
814 default:
815 GNUNET_break_op (0);
816 GNUNET_STATISTICS_update (
817 stats,
818 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
819 1,
820 GNUNET_NO);
821 return;
822 }
823 /* end AF_INET */
824 break;
825 case AF_INET6:
826 /* ICMP PT 6-to-4 and possibly making up payloads */
827 switch (icmp->type)
828 {
829 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
830 icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
831 {
832 struct GNUNET_TUN_IPv4Header *ipp =
833 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
834 struct GNUNET_TUN_UdpHeader *udp =
835 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
836
837 if (mlen != 0)
838 {
839 /* sender did not strip ICMP payload? */
840 GNUNET_break_op (0);
841 return;
842 }
843 size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
844 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
845 make_up_icmpv4_payload (ts, ipp, udp);
846 }
847 break;
848 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
849 icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
850 {
851 struct GNUNET_TUN_IPv4Header *ipp =
852 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
853 struct GNUNET_TUN_UdpHeader *udp =
854 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
855
856 if (mlen != 0)
857 {
858 /* sender did not strip ICMP payload? */
859 GNUNET_break_op (0);
860 return;
861 }
862 size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
863 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
864 make_up_icmpv4_payload (ts, ipp, udp);
865 }
866 break;
867 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
868 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
869 GNUNET_STATISTICS_update (
870 stats,
871 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
872 1,
873 GNUNET_NO);
874 return;
875 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
876 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
877 break;
878 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
879 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
880 break;
881 default:
882 GNUNET_break_op (0);
883 GNUNET_STATISTICS_update (
884 stats,
885 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
886 1,
887 GNUNET_NO);
888 return;
889 }
890 /* end AF_INET6 */
891 break;
892 default:
893 GNUNET_break_op (0);
894 return;
895 } 895 }
896 msg->size = htons (size);
897 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
898 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
899 } 896 }
900 } 897 break;
901 break;
902 case AF_INET6: {
903 size_t size = sizeof (struct GNUNET_TUN_IPv6Header) +
904 sizeof (struct GNUNET_TUN_IcmpHeader) +
905 sizeof (struct GNUNET_MessageHeader) +
906 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
907 {
908 char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
909 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
910 struct GNUNET_TUN_Layer2PacketHeader *tun =
911 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
912 struct GNUNET_TUN_IPv6Header *ipv6 =
913 (struct GNUNET_TUN_IPv6Header *) &tun[1];
914 struct GNUNET_TUN_IcmpHeader *icmp =
915 (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
916 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
917 tun->flags = htons (0);
918 tun->proto = htons (ETH_P_IPV6);
919 GNUNET_TUN_initialize_ipv6_header (ipv6,
920 IPPROTO_ICMPV6,
921 sizeof (struct GNUNET_TUN_IcmpHeader) +
922 mlen,
923 &ts->destination_ip.v6,
924 &ts->source_ip.v6);
925 *icmp = i2v->icmp_header;
926 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
927
928 /* For some ICMP types, we need to adjust (make up) the payload here.
929 Also, depending on the AF used on the other side, we have to
930 do ICMP PT (translate ICMP types) */
931 switch (ntohl (i2v->af))
932 {
933 case AF_INET:
934 /* ICMP PT 4-to-6 and possibly making up payloads */
935 switch (icmp->type)
936 {
937 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
938 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
939 break;
940 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
941 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
942 break;
943 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
944 icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
945 {
946 struct GNUNET_TUN_IPv6Header *ipp =
947 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
948 struct GNUNET_TUN_UdpHeader *udp =
949 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
950
951 if (mlen != 0)
952 {
953 /* sender did not strip ICMP payload? */
954 GNUNET_break_op (0);
955 return;
956 }
957 size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
958 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
959 make_up_icmpv6_payload (ts, ipp, udp);
960 }
961 break;
962 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
963 icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
964 {
965 struct GNUNET_TUN_IPv6Header *ipp =
966 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
967 struct GNUNET_TUN_UdpHeader *udp =
968 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
969 898
970 if (mlen != 0) 899 case AF_INET6: {
971 { 900 size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
972 /* sender did not strip ICMP payload? */ 901 sizeof(struct GNUNET_TUN_IcmpHeader) +
973 GNUNET_break_op (0); 902 sizeof(struct GNUNET_MessageHeader) +
974 return; 903 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
975 } 904 {
976 size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; 905 char buf[size + sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
977 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 906 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
978 make_up_icmpv6_payload (ts, ipp, udp); 907 struct GNUNET_TUN_Layer2PacketHeader *tun =
979 } 908 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
980 break; 909 struct GNUNET_TUN_IPv6Header *ipv6 =
981 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 910 (struct GNUNET_TUN_IPv6Header *)&tun[1];
982 GNUNET_STATISTICS_update ( 911 struct GNUNET_TUN_IcmpHeader *icmp =
983 stats, 912 (struct GNUNET_TUN_IcmpHeader *)&ipv6[1];
984 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), 913 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
985 1, 914 tun->flags = htons(0);
986 GNUNET_NO); 915 tun->proto = htons(ETH_P_IPV6);
987 return; 916 GNUNET_TUN_initialize_ipv6_header(ipv6,
988 default: 917 IPPROTO_ICMPV6,
989 GNUNET_break_op (0); 918 sizeof(struct GNUNET_TUN_IcmpHeader) +
990 GNUNET_STATISTICS_update ( 919 mlen,
991 stats, 920 &ts->destination_ip.v6,
992 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), 921 &ts->source_ip.v6);
993 1, 922 *icmp = i2v->icmp_header;
994 GNUNET_NO); 923 GNUNET_memcpy(&icmp[1], &i2v[1], mlen);
995 return; 924
996 } 925 /* For some ICMP types, we need to adjust (make up) the payload here.
997 /* end AF_INET */ 926 Also, depending on the AF used on the other side, we have to
998 break; 927 do ICMP PT (translate ICMP types) */
999 case AF_INET6: 928 switch (ntohl(i2v->af))
1000 switch (icmp->type)
1001 {
1002 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
1003 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
1004 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
1005 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: {
1006 struct GNUNET_TUN_IPv6Header *ipp =
1007 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1008 struct GNUNET_TUN_UdpHeader *udp =
1009 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1010
1011 if (mlen != 0)
1012 { 929 {
1013 /* sender did not strip ICMP payload? */ 930 case AF_INET:
1014 GNUNET_break_op (0); 931 /* ICMP PT 4-to-6 and possibly making up payloads */
932 switch (icmp->type)
933 {
934 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
935 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
936 break;
937
938 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
939 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
940 break;
941
942 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
943 icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
944 {
945 struct GNUNET_TUN_IPv6Header *ipp =
946 (struct GNUNET_TUN_IPv6Header *)&icmp[1];
947 struct GNUNET_TUN_UdpHeader *udp =
948 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
949
950 if (mlen != 0)
951 {
952 /* sender did not strip ICMP payload? */
953 GNUNET_break_op(0);
954 return;
955 }
956 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
957 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
958 make_up_icmpv6_payload(ts, ipp, udp);
959 }
960 break;
961
962 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
963 icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
964 {
965 struct GNUNET_TUN_IPv6Header *ipp =
966 (struct GNUNET_TUN_IPv6Header *)&icmp[1];
967 struct GNUNET_TUN_UdpHeader *udp =
968 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
969
970 if (mlen != 0)
971 {
972 /* sender did not strip ICMP payload? */
973 GNUNET_break_op(0);
974 return;
975 }
976 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
977 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
978 make_up_icmpv6_payload(ts, ipp, udp);
979 }
980 break;
981
982 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
983 GNUNET_STATISTICS_update(
984 stats,
985 gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
986 1,
987 GNUNET_NO);
988 return;
989
990 default:
991 GNUNET_break_op(0);
992 GNUNET_STATISTICS_update(
993 stats,
994 gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
995 1,
996 GNUNET_NO);
997 return;
998 }
999 /* end AF_INET */
1000 break;
1001
1002 case AF_INET6:
1003 switch (icmp->type)
1004 {
1005 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
1006 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
1007 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
1008 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: {
1009 struct GNUNET_TUN_IPv6Header *ipp =
1010 (struct GNUNET_TUN_IPv6Header *)&icmp[1];
1011 struct GNUNET_TUN_UdpHeader *udp =
1012 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
1013
1014 if (mlen != 0)
1015 {
1016 /* sender did not strip ICMP payload? */
1017 GNUNET_break_op(0);
1018 return;
1019 }
1020 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
1021 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
1022 make_up_icmpv6_payload(ts, ipp, udp);
1023 }
1024 break;
1025
1026 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1027 break;
1028
1029 default:
1030 GNUNET_break_op(0);
1031 GNUNET_STATISTICS_update(
1032 stats,
1033 gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
1034 1,
1035 GNUNET_NO);
1036 return;
1037 }
1038 /* end AF_INET6 */
1039 break;
1040
1041 default:
1042 GNUNET_break_op(0);
1015 return; 1043 return;
1016 } 1044 }
1017 size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; 1045 msg->size = htons(size);
1018 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 1046 GNUNET_TUN_calculate_icmp_checksum(icmp, &i2v[1], mlen);
1019 make_up_icmpv6_payload (ts, ipp, udp); 1047 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1020 }
1021 break;
1022 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1023 break;
1024 default:
1025 GNUNET_break_op (0);
1026 GNUNET_STATISTICS_update (
1027 stats,
1028 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1029 1,
1030 GNUNET_NO);
1031 return;
1032 }
1033 /* end AF_INET6 */
1034 break;
1035 default:
1036 GNUNET_break_op (0);
1037 return;
1038 } 1048 }
1039 msg->size = htons (size);
1040 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
1041 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1042 } 1049 }
1043 } 1050 break;
1044 break; 1051
1045 default: 1052 default:
1046 GNUNET_assert (0); 1053 GNUNET_assert(0);
1047 } 1054 }
1048 GNUNET_CONTAINER_heap_update_cost (ts->heap_node, 1055 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1049 GNUNET_TIME_absolute_get ().abs_value_us); 1056 GNUNET_TIME_absolute_get().abs_value_us);
1050 GNUNET_CADET_receive_done (ts->channel); 1057 GNUNET_CADET_receive_done(ts->channel);
1051} 1058}
1052 1059
1053 1060
@@ -1060,20 +1067,20 @@ handle_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
1060 * #GNUNET_SYSERR to close it (signal serious error) 1067 * #GNUNET_SYSERR to close it (signal serious error)
1061 */ 1068 */
1062static int 1069static int
1063check_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply) 1070check_udp_back(void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1064{ 1071{
1065 struct ChannelState *ts = cls; 1072 struct ChannelState *ts = cls;
1066 1073
1067 if (NULL == ts->heap_node) 1074 if (NULL == ts->heap_node)
1068 { 1075 {
1069 GNUNET_break_op (0); 1076 GNUNET_break_op(0);
1070 return GNUNET_SYSERR; 1077 return GNUNET_SYSERR;
1071 } 1078 }
1072 if (AF_UNSPEC == ts->af) 1079 if (AF_UNSPEC == ts->af)
1073 { 1080 {
1074 GNUNET_break_op (0); 1081 GNUNET_break_op(0);
1075 return GNUNET_SYSERR; 1082 return GNUNET_SYSERR;
1076 } 1083 }
1077 return GNUNET_OK; 1084 return GNUNET_OK;
1078} 1085}
1079 1086
@@ -1086,116 +1093,118 @@ check_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1086 * @param reply the actual message 1093 * @param reply the actual message
1087 */ 1094 */
1088static void 1095static void
1089handle_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply) 1096handle_udp_back(void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1090{ 1097{
1091 struct ChannelState *ts = cls; 1098 struct ChannelState *ts = cls;
1092 size_t mlen; 1099 size_t mlen;
1093 1100
1094 GNUNET_STATISTICS_update (stats, 1101 GNUNET_STATISTICS_update(stats,
1095 gettext_noop ("# UDP packets received from cadet"), 1102 gettext_noop("# UDP packets received from cadet"),
1096 1, 1103 1,
1097 GNUNET_NO); 1104 GNUNET_NO);
1098 mlen = 1105 mlen =
1099 ntohs (reply->header.size) - sizeof (struct GNUNET_EXIT_UdpReplyMessage); 1106 ntohs(reply->header.size) - sizeof(struct GNUNET_EXIT_UdpReplyMessage);
1100 { 1107 {
1101 char sbuf[INET6_ADDRSTRLEN]; 1108 char sbuf[INET6_ADDRSTRLEN];
1102 char dbuf[INET6_ADDRSTRLEN]; 1109 char dbuf[INET6_ADDRSTRLEN];
1103 1110
1104 GNUNET_log ( 1111 GNUNET_log(
1105 GNUNET_ERROR_TYPE_DEBUG, 1112 GNUNET_ERROR_TYPE_DEBUG,
1106 "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", 1113 "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1107 (unsigned int) mlen, 1114 (unsigned int)mlen,
1108 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), 1115 inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1109 ts->destination_port, 1116 ts->destination_port,
1110 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), 1117 inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1111 ts->source_port); 1118 ts->source_port);
1112 } 1119 }
1113 switch (ts->af) 1120 switch (ts->af)
1114 {
1115 case AF_INET: {
1116 size_t size = sizeof (struct GNUNET_TUN_IPv4Header) +
1117 sizeof (struct GNUNET_TUN_UdpHeader) +
1118 sizeof (struct GNUNET_MessageHeader) +
1119 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1120 { 1121 {
1121 char buf[size] GNUNET_ALIGN; 1122 case AF_INET: {
1122 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1123 size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
1123 struct GNUNET_TUN_Layer2PacketHeader *tun = 1124 sizeof(struct GNUNET_TUN_UdpHeader) +
1124 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1125 sizeof(struct GNUNET_MessageHeader) +
1125 struct GNUNET_TUN_IPv4Header *ipv4 = 1126 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1126 (struct GNUNET_TUN_IPv4Header *) &tun[1]; 1127 {
1127 struct GNUNET_TUN_UdpHeader *udp = 1128 char buf[size] GNUNET_ALIGN;
1128 (struct GNUNET_TUN_UdpHeader *) &ipv4[1]; 1129 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1129 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1130 struct GNUNET_TUN_Layer2PacketHeader *tun =
1130 msg->size = htons (size); 1131 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1131 tun->flags = htons (0); 1132 struct GNUNET_TUN_IPv4Header *ipv4 =
1132 tun->proto = htons (ETH_P_IPV4); 1133 (struct GNUNET_TUN_IPv4Header *)&tun[1];
1133 GNUNET_TUN_initialize_ipv4_header (ipv4, 1134 struct GNUNET_TUN_UdpHeader *udp =
1134 IPPROTO_UDP, 1135 (struct GNUNET_TUN_UdpHeader *)&ipv4[1];
1135 sizeof (struct GNUNET_TUN_UdpHeader) + 1136 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1136 mlen, 1137 msg->size = htons(size);
1137 &ts->destination_ip.v4, 1138 tun->flags = htons(0);
1138 &ts->source_ip.v4); 1139 tun->proto = htons(ETH_P_IPV4);
1139 if (0 == ntohs (reply->source_port)) 1140 GNUNET_TUN_initialize_ipv4_header(ipv4,
1140 udp->source_port = htons (ts->destination_port); 1141 IPPROTO_UDP,
1141 else 1142 sizeof(struct GNUNET_TUN_UdpHeader) +
1142 udp->source_port = reply->source_port; 1143 mlen,
1143 if (0 == ntohs (reply->destination_port)) 1144 &ts->destination_ip.v4,
1144 udp->destination_port = htons (ts->source_port); 1145 &ts->source_ip.v4);
1145 else 1146 if (0 == ntohs(reply->source_port))
1146 udp->destination_port = reply->destination_port; 1147 udp->source_port = htons(ts->destination_port);
1147 udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); 1148 else
1148 GNUNET_TUN_calculate_udp4_checksum (ipv4, udp, &reply[1], mlen); 1149 udp->source_port = reply->source_port;
1149 GNUNET_memcpy (&udp[1], &reply[1], mlen); 1150 if (0 == ntohs(reply->destination_port))
1150 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1151 udp->destination_port = htons(ts->source_port);
1152 else
1153 udp->destination_port = reply->destination_port;
1154 udp->len = htons(mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1155 GNUNET_TUN_calculate_udp4_checksum(ipv4, udp, &reply[1], mlen);
1156 GNUNET_memcpy(&udp[1], &reply[1], mlen);
1157 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1158 }
1151 } 1159 }
1152 } 1160 break;
1153 break; 1161
1154 case AF_INET6: { 1162 case AF_INET6: {
1155 size_t size = sizeof (struct GNUNET_TUN_IPv6Header) + 1163 size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
1156 sizeof (struct GNUNET_TUN_UdpHeader) + 1164 sizeof(struct GNUNET_TUN_UdpHeader) +
1157 sizeof (struct GNUNET_MessageHeader) + 1165 sizeof(struct GNUNET_MessageHeader) +
1158 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; 1166 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1159 { 1167 {
1160 char buf[size] GNUNET_ALIGN; 1168 char buf[size] GNUNET_ALIGN;
1161 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1169 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1162 struct GNUNET_TUN_Layer2PacketHeader *tun = 1170 struct GNUNET_TUN_Layer2PacketHeader *tun =
1163 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1171 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1164 struct GNUNET_TUN_IPv6Header *ipv6 = 1172 struct GNUNET_TUN_IPv6Header *ipv6 =
1165 (struct GNUNET_TUN_IPv6Header *) &tun[1]; 1173 (struct GNUNET_TUN_IPv6Header *)&tun[1];
1166 struct GNUNET_TUN_UdpHeader *udp = 1174 struct GNUNET_TUN_UdpHeader *udp =
1167 (struct GNUNET_TUN_UdpHeader *) &ipv6[1]; 1175 (struct GNUNET_TUN_UdpHeader *)&ipv6[1];
1168 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1176 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1169 msg->size = htons (size); 1177 msg->size = htons(size);
1170 tun->flags = htons (0); 1178 tun->flags = htons(0);
1171 tun->proto = htons (ETH_P_IPV6); 1179 tun->proto = htons(ETH_P_IPV6);
1172 GNUNET_TUN_initialize_ipv6_header (ipv6, 1180 GNUNET_TUN_initialize_ipv6_header(ipv6,
1173 IPPROTO_UDP, 1181 IPPROTO_UDP,
1174 sizeof (struct GNUNET_TUN_UdpHeader) + 1182 sizeof(struct GNUNET_TUN_UdpHeader) +
1175 mlen, 1183 mlen,
1176 &ts->destination_ip.v6, 1184 &ts->destination_ip.v6,
1177 &ts->source_ip.v6); 1185 &ts->source_ip.v6);
1178 if (0 == ntohs (reply->source_port)) 1186 if (0 == ntohs(reply->source_port))
1179 udp->source_port = htons (ts->destination_port); 1187 udp->source_port = htons(ts->destination_port);
1180 else 1188 else
1181 udp->source_port = reply->source_port; 1189 udp->source_port = reply->source_port;
1182 if (0 == ntohs (reply->destination_port)) 1190 if (0 == ntohs(reply->destination_port))
1183 udp->destination_port = htons (ts->source_port); 1191 udp->destination_port = htons(ts->source_port);
1184 else 1192 else
1185 udp->destination_port = reply->destination_port; 1193 udp->destination_port = reply->destination_port;
1186 udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); 1194 udp->len = htons(mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1187 GNUNET_TUN_calculate_udp6_checksum (ipv6, udp, &reply[1], mlen); 1195 GNUNET_TUN_calculate_udp6_checksum(ipv6, udp, &reply[1], mlen);
1188 GNUNET_memcpy (&udp[1], &reply[1], mlen); 1196 GNUNET_memcpy(&udp[1], &reply[1], mlen);
1189 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1197 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1198 }
1190 } 1199 }
1191 } 1200 break;
1192 break; 1201
1193 default: 1202 default:
1194 GNUNET_assert (0); 1203 GNUNET_assert(0);
1195 } 1204 }
1196 GNUNET_CONTAINER_heap_update_cost (ts->heap_node, 1205 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1197 GNUNET_TIME_absolute_get ().abs_value_us); 1206 GNUNET_TIME_absolute_get().abs_value_us);
1198 GNUNET_CADET_receive_done (ts->channel); 1207 GNUNET_CADET_receive_done(ts->channel);
1199} 1208}
1200 1209
1201 1210
@@ -1208,20 +1217,20 @@ handle_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1208 * #GNUNET_SYSERR to close it (signal serious error) 1217 * #GNUNET_SYSERR to close it (signal serious error)
1209 */ 1218 */
1210static int 1219static int
1211check_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data) 1220check_tcp_back(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1212{ 1221{
1213 struct ChannelState *ts = cls; 1222 struct ChannelState *ts = cls;
1214 1223
1215 if (NULL == ts->heap_node) 1224 if (NULL == ts->heap_node)
1216 { 1225 {
1217 GNUNET_break_op (0); 1226 GNUNET_break_op(0);
1218 return GNUNET_SYSERR; 1227 return GNUNET_SYSERR;
1219 } 1228 }
1220 if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) 1229 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1221 { 1230 {
1222 GNUNET_break_op (0); 1231 GNUNET_break_op(0);
1223 return GNUNET_SYSERR; 1232 return GNUNET_SYSERR;
1224 } 1233 }
1225 return GNUNET_OK; 1234 return GNUNET_OK;
1226} 1235}
1227 1236
@@ -1234,101 +1243,102 @@ check_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1234 * @param data the actual message 1243 * @param data the actual message
1235 */ 1244 */
1236static void 1245static void
1237handle_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data) 1246handle_tcp_back(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1238{ 1247{
1239 struct ChannelState *ts = cls; 1248 struct ChannelState *ts = cls;
1240 size_t mlen; 1249 size_t mlen;
1241 1250
1242 GNUNET_STATISTICS_update (stats, 1251 GNUNET_STATISTICS_update(stats,
1243 gettext_noop ("# TCP packets received from cadet"), 1252 gettext_noop("# TCP packets received from cadet"),
1244 1, 1253 1,
1245 GNUNET_NO); 1254 GNUNET_NO);
1246 mlen = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage); 1255 mlen = ntohs(data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1247 { 1256 {
1248 char sbuf[INET6_ADDRSTRLEN]; 1257 char sbuf[INET6_ADDRSTRLEN];
1249 char dbuf[INET6_ADDRSTRLEN]; 1258 char dbuf[INET6_ADDRSTRLEN];
1250 1259
1251 GNUNET_log ( 1260 GNUNET_log(
1252 GNUNET_ERROR_TYPE_DEBUG, 1261 GNUNET_ERROR_TYPE_DEBUG,
1253 "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", 1262 "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1254 (unsigned int) mlen, 1263 (unsigned int)mlen,
1255 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), 1264 inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1256 ts->destination_port, 1265 ts->destination_port,
1257 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), 1266 inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1258 ts->source_port); 1267 ts->source_port);
1259 } 1268 }
1260 switch (ts->af) 1269 switch (ts->af)
1261 {
1262 case AF_INET: {
1263 size_t size = sizeof (struct GNUNET_TUN_IPv4Header) +
1264 sizeof (struct GNUNET_TUN_TcpHeader) +
1265 sizeof (struct GNUNET_MessageHeader) +
1266 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1267 { 1270 {
1268 char buf[size] GNUNET_ALIGN; 1271 case AF_INET: {
1269 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1272 size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
1270 struct GNUNET_TUN_Layer2PacketHeader *tun = 1273 sizeof(struct GNUNET_TUN_TcpHeader) +
1271 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1274 sizeof(struct GNUNET_MessageHeader) +
1272 struct GNUNET_TUN_IPv4Header *ipv4 = 1275 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1273 (struct GNUNET_TUN_IPv4Header *) &tun[1]; 1276 {
1274 struct GNUNET_TUN_TcpHeader *tcp = 1277 char buf[size] GNUNET_ALIGN;
1275 (struct GNUNET_TUN_TcpHeader *) &ipv4[1]; 1278 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1276 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1279 struct GNUNET_TUN_Layer2PacketHeader *tun =
1277 msg->size = htons (size); 1280 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1278 tun->flags = htons (0); 1281 struct GNUNET_TUN_IPv4Header *ipv4 =
1279 tun->proto = htons (ETH_P_IPV4); 1282 (struct GNUNET_TUN_IPv4Header *)&tun[1];
1280 GNUNET_TUN_initialize_ipv4_header (ipv4, 1283 struct GNUNET_TUN_TcpHeader *tcp =
1281 IPPROTO_TCP, 1284 (struct GNUNET_TUN_TcpHeader *)&ipv4[1];
1282 sizeof (struct GNUNET_TUN_TcpHeader) + 1285 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1283 mlen, 1286 msg->size = htons(size);
1284 &ts->destination_ip.v4, 1287 tun->flags = htons(0);
1285 &ts->source_ip.v4); 1288 tun->proto = htons(ETH_P_IPV4);
1286 *tcp = data->tcp_header; 1289 GNUNET_TUN_initialize_ipv4_header(ipv4,
1287 tcp->source_port = htons (ts->destination_port); 1290 IPPROTO_TCP,
1288 tcp->destination_port = htons (ts->source_port); 1291 sizeof(struct GNUNET_TUN_TcpHeader) +
1289 GNUNET_TUN_calculate_tcp4_checksum (ipv4, tcp, &data[1], mlen); 1292 mlen,
1290 GNUNET_memcpy (&tcp[1], &data[1], mlen); 1293 &ts->destination_ip.v4,
1291 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1294 &ts->source_ip.v4);
1295 *tcp = data->tcp_header;
1296 tcp->source_port = htons(ts->destination_port);
1297 tcp->destination_port = htons(ts->source_port);
1298 GNUNET_TUN_calculate_tcp4_checksum(ipv4, tcp, &data[1], mlen);
1299 GNUNET_memcpy(&tcp[1], &data[1], mlen);
1300 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1301 }
1292 } 1302 }
1293 } 1303 break;
1294 break; 1304
1295 case AF_INET6: { 1305 case AF_INET6: {
1296 size_t size = sizeof (struct GNUNET_TUN_IPv6Header) + 1306 size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
1297 sizeof (struct GNUNET_TUN_TcpHeader) + 1307 sizeof(struct GNUNET_TUN_TcpHeader) +
1298 sizeof (struct GNUNET_MessageHeader) + 1308 sizeof(struct GNUNET_MessageHeader) +
1299 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; 1309 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1300 { 1310 {
1301 char buf[size] GNUNET_ALIGN; 1311 char buf[size] GNUNET_ALIGN;
1302 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1312 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1303 struct GNUNET_TUN_Layer2PacketHeader *tun = 1313 struct GNUNET_TUN_Layer2PacketHeader *tun =
1304 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1314 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1305 struct GNUNET_TUN_IPv6Header *ipv6 = 1315 struct GNUNET_TUN_IPv6Header *ipv6 =
1306 (struct GNUNET_TUN_IPv6Header *) &tun[1]; 1316 (struct GNUNET_TUN_IPv6Header *)&tun[1];
1307 struct GNUNET_TUN_TcpHeader *tcp = 1317 struct GNUNET_TUN_TcpHeader *tcp =
1308 (struct GNUNET_TUN_TcpHeader *) &ipv6[1]; 1318 (struct GNUNET_TUN_TcpHeader *)&ipv6[1];
1309 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1319 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1310 msg->size = htons (size); 1320 msg->size = htons(size);
1311 tun->flags = htons (0); 1321 tun->flags = htons(0);
1312 tun->proto = htons (ETH_P_IPV6); 1322 tun->proto = htons(ETH_P_IPV6);
1313 GNUNET_TUN_initialize_ipv6_header (ipv6, 1323 GNUNET_TUN_initialize_ipv6_header(ipv6,
1314 IPPROTO_TCP, 1324 IPPROTO_TCP,
1315 sizeof (struct GNUNET_TUN_TcpHeader) + 1325 sizeof(struct GNUNET_TUN_TcpHeader) +
1316 mlen, 1326 mlen,
1317 &ts->destination_ip.v6, 1327 &ts->destination_ip.v6,
1318 &ts->source_ip.v6); 1328 &ts->source_ip.v6);
1319 *tcp = data->tcp_header; 1329 *tcp = data->tcp_header;
1320 tcp->source_port = htons (ts->destination_port); 1330 tcp->source_port = htons(ts->destination_port);
1321 tcp->destination_port = htons (ts->source_port); 1331 tcp->destination_port = htons(ts->source_port);
1322 GNUNET_TUN_calculate_tcp6_checksum (ipv6, tcp, &data[1], mlen); 1332 GNUNET_TUN_calculate_tcp6_checksum(ipv6, tcp, &data[1], mlen);
1323 GNUNET_memcpy (&tcp[1], &data[1], mlen); 1333 GNUNET_memcpy(&tcp[1], &data[1], mlen);
1324 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1334 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1335 }
1325 } 1336 }
1326 } 1337 break;
1327 break; 1338 }
1328 } 1339 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1329 GNUNET_CONTAINER_heap_update_cost (ts->heap_node, 1340 GNUNET_TIME_absolute_get().abs_value_us);
1330 GNUNET_TIME_absolute_get ().abs_value_us); 1341 GNUNET_CADET_receive_done(ts->channel);
1331 GNUNET_CADET_receive_done (ts->channel);
1332} 1342}
1333 1343
1334 1344
@@ -1341,32 +1351,32 @@ handle_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1341 * @return the channel handle 1351 * @return the channel handle
1342 */ 1352 */
1343static struct GNUNET_CADET_Channel * 1353static struct GNUNET_CADET_Channel *
1344create_channel (struct ChannelState *ts, 1354create_channel(struct ChannelState *ts,
1345 const struct GNUNET_PeerIdentity *target, 1355 const struct GNUNET_PeerIdentity *target,
1346 const struct GNUNET_HashCode *port) 1356 const struct GNUNET_HashCode *port)
1347{ 1357{
1348 struct GNUNET_MQ_MessageHandler cadet_handlers[] = 1358 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1349 {GNUNET_MQ_hd_var_size (udp_back, 1359 { GNUNET_MQ_hd_var_size(udp_back,
1350 GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 1360 GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY,
1351 struct GNUNET_EXIT_UdpReplyMessage, 1361 struct GNUNET_EXIT_UdpReplyMessage,
1352 ts), 1362 ts),
1353 GNUNET_MQ_hd_var_size (tcp_back, 1363 GNUNET_MQ_hd_var_size(tcp_back,
1354 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 1364 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN,
1355 struct GNUNET_EXIT_TcpDataMessage, 1365 struct GNUNET_EXIT_TcpDataMessage,
1356 ts), 1366 ts),
1357 GNUNET_MQ_hd_var_size (icmp_back, 1367 GNUNET_MQ_hd_var_size(icmp_back,
1358 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 1368 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN,
1359 struct GNUNET_EXIT_IcmpToVPNMessage, 1369 struct GNUNET_EXIT_IcmpToVPNMessage,
1360 ts), 1370 ts),
1361 GNUNET_MQ_handler_end ()}; 1371 GNUNET_MQ_handler_end() };
1362 1372
1363 return GNUNET_CADET_channel_create (cadet_handle, 1373 return GNUNET_CADET_channel_create(cadet_handle,
1364 ts, 1374 ts,
1365 target, 1375 target,
1366 port, 1376 port,
1367 NULL, 1377 NULL,
1368 &channel_cleaner, 1378 &channel_cleaner,
1369 cadet_handlers); 1379 cadet_handlers);
1370} 1380}
1371 1381
1372 1382
@@ -1381,45 +1391,47 @@ create_channel (struct ChannelState *ts,
1381 * @param put_path_length Length of the @a put_path. 1391 * @param put_path_length Length of the @a put_path.
1382 */ 1392 */
1383static void 1393static void
1384handle_regex_result (void *cls, 1394handle_regex_result(void *cls,
1385 const struct GNUNET_PeerIdentity *id, 1395 const struct GNUNET_PeerIdentity *id,
1386 const struct GNUNET_PeerIdentity *get_path, 1396 const struct GNUNET_PeerIdentity *get_path,
1387 unsigned int get_path_length, 1397 unsigned int get_path_length,
1388 const struct GNUNET_PeerIdentity *put_path, 1398 const struct GNUNET_PeerIdentity *put_path,
1389 unsigned int put_path_length) 1399 unsigned int put_path_length)
1390{ 1400{
1391 struct ChannelState *ts = cls; 1401 struct ChannelState *ts = cls;
1392 struct GNUNET_HashCode port; 1402 struct GNUNET_HashCode port;
1393 1403
1394 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1404 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1395 "Exit %s found for destination %s!\n", 1405 "Exit %s found for destination %s!\n",
1396 GNUNET_i2s (id), 1406 GNUNET_i2s(id),
1397 print_channel_destination (&ts->destination)); 1407 print_channel_destination(&ts->destination));
1398 GNUNET_REGEX_search_cancel (ts->search); 1408 GNUNET_REGEX_search_cancel(ts->search);
1399 ts->search = NULL; 1409 ts->search = NULL;
1400 switch (ts->af) 1410 switch (ts->af)
1401 { 1411 {
1402 case AF_INET: 1412 case AF_INET:
1403 /* these must match the strings used in gnunet-daemon-exit */ 1413 /* these must match the strings used in gnunet-daemon-exit */
1404 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_IPV4_GATEWAY, 1414 GNUNET_CRYPTO_hash(GNUNET_APPLICATION_PORT_IPV4_GATEWAY,
1405 strlen (GNUNET_APPLICATION_PORT_IPV4_GATEWAY), 1415 strlen(GNUNET_APPLICATION_PORT_IPV4_GATEWAY),
1406 &port); 1416 &port);
1407 break; 1417 break;
1408 case AF_INET6: 1418
1409 /* these must match the strings used in gnunet-daemon-exit */ 1419 case AF_INET6:
1410 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_IPV6_GATEWAY, 1420 /* these must match the strings used in gnunet-daemon-exit */
1411 strlen (GNUNET_APPLICATION_PORT_IPV6_GATEWAY), 1421 GNUNET_CRYPTO_hash(GNUNET_APPLICATION_PORT_IPV6_GATEWAY,
1412 &port); 1422 strlen(GNUNET_APPLICATION_PORT_IPV6_GATEWAY),
1413 break; 1423 &port);
1414 default: 1424 break;
1415 GNUNET_break (0); 1425
1416 return; 1426 default:
1417 } 1427 GNUNET_break(0);
1418 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1428 return;
1419 "Creating tunnel to %s for destination %s!\n", 1429 }
1420 GNUNET_i2s (id), 1430 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1421 print_channel_destination (&ts->destination)); 1431 "Creating tunnel to %s for destination %s!\n",
1422 ts->channel = create_channel (ts, id, &port); 1432 GNUNET_i2s(id),
1433 print_channel_destination(&ts->destination));
1434 ts->channel = create_channel(ts, id, &port);
1423} 1435}
1424 1436
1425 1437
@@ -1431,90 +1443,92 @@ handle_regex_result (void *cls,
1431 * @return channel state of the channel that was created 1443 * @return channel state of the channel that was created
1432 */ 1444 */
1433static struct ChannelState * 1445static struct ChannelState *
1434create_channel_to_destination (struct DestinationChannel *dt, int client_af) 1446create_channel_to_destination(struct DestinationChannel *dt, int client_af)
1435{ 1447{
1436 struct ChannelState *ts; 1448 struct ChannelState *ts;
1437 1449
1438 GNUNET_STATISTICS_update (stats, 1450 GNUNET_STATISTICS_update(stats,
1439 gettext_noop ("# Cadet channels created"), 1451 gettext_noop("# Cadet channels created"),
1440 1, 1452 1,
1441 GNUNET_NO); 1453 GNUNET_NO);
1442 ts = GNUNET_new (struct ChannelState); 1454 ts = GNUNET_new(struct ChannelState);
1443 ts->af = client_af; 1455 ts->af = client_af;
1444 ts->destination = *dt->destination; 1456 ts->destination = *dt->destination;
1445 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */ 1457 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1446 ts->destination_port = dt->destination_port; 1458 ts->destination_port = dt->destination_port;
1447 if (dt->destination->is_service) 1459 if (dt->destination->is_service)
1448 {
1449 struct GNUNET_HashCode cadet_port;
1450
1451 GNUNET_TUN_compute_service_cadet_port (&ts->destination.details
1452 .service_destination
1453 .service_descriptor,
1454 ts->destination_port,
1455 &cadet_port);
1456 ts->channel =
1457 create_channel (ts,
1458 &dt->destination->details.service_destination.target,
1459 &cadet_port);
1460
1461 if (NULL == ts->channel)
1462 { 1460 {
1463 GNUNET_break (0); 1461 struct GNUNET_HashCode cadet_port;
1464 GNUNET_free (ts); 1462
1465 return NULL; 1463 GNUNET_TUN_compute_service_cadet_port(&ts->destination.details
1466 } 1464 .service_destination
1467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1465 .service_descriptor,
1468 "Creating channel to peer %s offering service %s on port %u\n", 1466 ts->destination_port,
1469 GNUNET_i2s ( 1467 &cadet_port);
1470 &dt->destination->details.service_destination.target), 1468 ts->channel =
1471 GNUNET_h2s (&ts->destination.details.service_destination 1469 create_channel(ts,
1472 .service_descriptor), 1470 &dt->destination->details.service_destination.target,
1473 (unsigned int) ts->destination_port); 1471 &cadet_port);
1474 } 1472
1473 if (NULL == ts->channel)
1474 {
1475 GNUNET_break(0);
1476 GNUNET_free(ts);
1477 return NULL;
1478 }
1479 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1480 "Creating channel to peer %s offering service %s on port %u\n",
1481 GNUNET_i2s(
1482 &dt->destination->details.service_destination.target),
1483 GNUNET_h2s(&ts->destination.details.service_destination
1484 .service_descriptor),
1485 (unsigned int)ts->destination_port);
1486 }
1475 else 1487 else
1476 {
1477 char *policy;
1478
1479 switch (dt->destination->details.exit_destination.af)
1480 { 1488 {
1481 case AF_INET: { 1489 char *policy;
1482 char address[GNUNET_TUN_IPV4_REGEXLEN];
1483 1490
1484 GNUNET_TUN_ipv4toregexsearch (&dt->destination->details.exit_destination 1491 switch (dt->destination->details.exit_destination.af)
1492 {
1493 case AF_INET: {
1494 char address[GNUNET_TUN_IPV4_REGEXLEN];
1495
1496 GNUNET_TUN_ipv4toregexsearch(&dt->destination->details.exit_destination
1485 .ip.v4, 1497 .ip.v4,
1486 dt->destination_port, 1498 dt->destination_port,
1487 address); 1499 address);
1488 GNUNET_asprintf (&policy, 1500 GNUNET_asprintf(&policy,
1489 "%s%s", 1501 "%s%s",
1490 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, 1502 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
1491 address); 1503 address);
1492 break; 1504 break;
1493 } 1505 }
1494 case AF_INET6: { 1506
1495 char address[GNUNET_TUN_IPV6_REGEXLEN]; 1507 case AF_INET6: {
1508 char address[GNUNET_TUN_IPV6_REGEXLEN];
1496 1509
1497 GNUNET_TUN_ipv6toregexsearch (&dt->destination->details.exit_destination 1510 GNUNET_TUN_ipv6toregexsearch(&dt->destination->details.exit_destination
1498 .ip.v6, 1511 .ip.v6,
1499 dt->destination_port, 1512 dt->destination_port,
1500 address); 1513 address);
1501 GNUNET_asprintf (&policy, 1514 GNUNET_asprintf(&policy,
1502 "%s%s", 1515 "%s%s",
1503 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, 1516 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
1504 address); 1517 address);
1505 break; 1518 break;
1506 } 1519 }
1507 default:
1508 GNUNET_assert (0);
1509 break;
1510 }
1511 1520
1512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1521 default:
1513 "Requesting connect by string: %s\n", 1522 GNUNET_assert(0);
1514 policy); 1523 break;
1515 ts->search = GNUNET_REGEX_search (cfg, policy, &handle_regex_result, ts); 1524 }
1516 GNUNET_free (policy); 1525
1517 } 1526 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1527 "Requesting connect by string: %s\n",
1528 policy);
1529 ts->search = GNUNET_REGEX_search(cfg, policy, &handle_regex_result, ts);
1530 GNUNET_free(policy);
1531 }
1518 return ts; 1532 return ts;
1519} 1533}
1520 1534
@@ -1525,18 +1539,18 @@ create_channel_to_destination (struct DestinationChannel *dt, int client_af)
1525 * @param except channel that must NOT be cleaned up, even if it is the oldest 1539 * @param except channel that must NOT be cleaned up, even if it is the oldest
1526 */ 1540 */
1527static void 1541static void
1528expire_channel (struct ChannelState *except) 1542expire_channel(struct ChannelState *except)
1529{ 1543{
1530 struct ChannelState *ts; 1544 struct ChannelState *ts;
1531 1545
1532 ts = GNUNET_CONTAINER_heap_peek (channel_heap); 1546 ts = GNUNET_CONTAINER_heap_peek(channel_heap);
1533 GNUNET_assert (NULL != ts); 1547 GNUNET_assert(NULL != ts);
1534 if (except == ts) 1548 if (except == ts)
1535 return; /* can't do this */ 1549 return; /* can't do this */
1536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1550 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1537 "Tearing down expired channel to %s\n", 1551 "Tearing down expired channel to %s\n",
1538 print_channel_destination (&except->destination)); 1552 print_channel_destination(&except->destination));
1539 free_channel_state (ts); 1553 free_channel_state(ts);
1540} 1554}
1541 1555
1542 1556
@@ -1552,13 +1566,13 @@ expire_channel (struct ChannelState *except)
1552 * @param payload_length number of bytes in @a payload 1566 * @param payload_length number of bytes in @a payload
1553 */ 1567 */
1554static void 1568static void
1555route_packet (struct DestinationEntry *destination, 1569route_packet(struct DestinationEntry *destination,
1556 int af, 1570 int af,
1557 uint8_t protocol, 1571 uint8_t protocol,
1558 const void *source_ip, 1572 const void *source_ip,
1559 const void *destination_ip, 1573 const void *destination_ip,
1560 const void *payload, 1574 const void *payload,
1561 size_t payload_length) 1575 size_t payload_length)
1562{ 1576{
1563 struct GNUNET_HashCode key; 1577 struct GNUNET_HashCode key;
1564 struct ChannelState *ts; 1578 struct ChannelState *ts;
@@ -1573,630 +1587,663 @@ route_packet (struct DestinationEntry *destination,
1573 uint16_t destination_port; 1587 uint16_t destination_port;
1574 1588
1575 switch (protocol) 1589 switch (protocol)
1576 {
1577 case IPPROTO_UDP: {
1578 if (payload_length < sizeof (struct GNUNET_TUN_UdpHeader))
1579 {
1580 /* blame kernel? */
1581 GNUNET_break (0);
1582 return;
1583 }
1584 tcp = NULL; /* make compiler happy */
1585 icmp = NULL; /* make compiler happy */
1586 udp = payload;
1587 if (udp->len < sizeof (struct GNUNET_TUN_UdpHeader))
1588 { 1590 {
1589 GNUNET_break_op (0); 1591 case IPPROTO_UDP: {
1590 return; 1592 if (payload_length < sizeof(struct GNUNET_TUN_UdpHeader))
1591 } 1593 {
1592 source_port = ntohs (udp->source_port); 1594 /* blame kernel? */
1593 destination_port = ntohs (udp->destination_port); 1595 GNUNET_break(0);
1594 get_channel_key_from_ips (af, 1596 return;
1595 IPPROTO_UDP, 1597 }
1596 source_ip, 1598 tcp = NULL; /* make compiler happy */
1597 source_port, 1599 icmp = NULL; /* make compiler happy */
1598 destination_ip, 1600 udp = payload;
1599 destination_port, 1601 if (udp->len < sizeof(struct GNUNET_TUN_UdpHeader))
1600 &key); 1602 {
1601 } 1603 GNUNET_break_op(0);
1602 break; 1604 return;
1603 case IPPROTO_TCP: { 1605 }
1604 if (payload_length < sizeof (struct GNUNET_TUN_TcpHeader)) 1606 source_port = ntohs(udp->source_port);
1605 { 1607 destination_port = ntohs(udp->destination_port);
1606 /* blame kernel? */ 1608 get_channel_key_from_ips(af,
1607 GNUNET_break (0); 1609 IPPROTO_UDP,
1608 return; 1610 source_ip,
1611 source_port,
1612 destination_ip,
1613 destination_port,
1614 &key);
1609 } 1615 }
1610 udp = NULL; /* make compiler happy */ 1616 break;
1611 icmp = NULL; /* make compiler happy */ 1617
1612 tcp = payload; 1618 case IPPROTO_TCP: {
1613 if (tcp->off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) 1619 if (payload_length < sizeof(struct GNUNET_TUN_TcpHeader))
1614 { 1620 {
1615 GNUNET_break_op (0); 1621 /* blame kernel? */
1616 return; 1622 GNUNET_break(0);
1623 return;
1624 }
1625 udp = NULL; /* make compiler happy */
1626 icmp = NULL; /* make compiler happy */
1627 tcp = payload;
1628 if (tcp->off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1629 {
1630 GNUNET_break_op(0);
1631 return;
1632 }
1633 source_port = ntohs(tcp->source_port);
1634 destination_port = ntohs(tcp->destination_port);
1635 get_channel_key_from_ips(af,
1636 IPPROTO_TCP,
1637 source_ip,
1638 source_port,
1639 destination_ip,
1640 destination_port,
1641 &key);
1617 } 1642 }
1618 source_port = ntohs (tcp->source_port); 1643 break;
1619 destination_port = ntohs (tcp->destination_port); 1644
1620 get_channel_key_from_ips (af, 1645 case IPPROTO_ICMP:
1621 IPPROTO_TCP, 1646 case IPPROTO_ICMPV6: {
1622 source_ip, 1647 if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP))
1623 source_port, 1648 {
1624 destination_ip, 1649 GNUNET_break(0);
1625 destination_port, 1650 return;
1626 &key); 1651 }
1627 } 1652 if (payload_length < sizeof(struct GNUNET_TUN_IcmpHeader))
1628 break; 1653 {
1629 case IPPROTO_ICMP: 1654 /* blame kernel? */
1630 case IPPROTO_ICMPV6: { 1655 GNUNET_break(0);
1631 if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP)) 1656 return;
1632 { 1657 }
1633 GNUNET_break (0); 1658 tcp = NULL; /* make compiler happy */
1634 return; 1659 udp = NULL; /* make compiler happy */
1660 icmp = payload;
1661 source_port = 0;
1662 destination_port = 0;
1663 get_channel_key_from_ips(af,
1664 protocol,
1665 source_ip,
1666 0,
1667 destination_ip,
1668 0,
1669 &key);
1635 } 1670 }
1636 if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader)) 1671 break;
1637 { 1672
1638 /* blame kernel? */ 1673 default:
1639 GNUNET_break (0); 1674 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1675 _("Protocol %u not supported, dropping\n"),
1676 (unsigned int)protocol);
1640 return; 1677 return;
1641 } 1678 }
1642 tcp = NULL; /* make compiler happy */
1643 udp = NULL; /* make compiler happy */
1644 icmp = payload;
1645 source_port = 0;
1646 destination_port = 0;
1647 get_channel_key_from_ips (af,
1648 protocol,
1649 source_ip,
1650 0,
1651 destination_ip,
1652 0,
1653 &key);
1654 }
1655 break;
1656 default:
1657 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1658 _ ("Protocol %u not supported, dropping\n"),
1659 (unsigned int) protocol);
1660 return;
1661 }
1662 alen = 0; 1679 alen = 0;
1663 if (! destination->is_service) 1680 if (!destination->is_service)
1664 {
1665 switch (destination->details.exit_destination.af)
1666 { 1681 {
1667 case AF_INET: 1682 switch (destination->details.exit_destination.af)
1668 alen = sizeof (struct in_addr); 1683 {
1669 break; 1684 case AF_INET:
1670 case AF_INET6: 1685 alen = sizeof(struct in_addr);
1671 alen = sizeof (struct in6_addr); 1686 break;
1672 break;
1673 default:
1674 GNUNET_assert (0);
1675 }
1676
1677 {
1678 char sbuf[INET6_ADDRSTRLEN];
1679 char dbuf[INET6_ADDRSTRLEN];
1680 char xbuf[INET6_ADDRSTRLEN];
1681
1682 GNUNET_log (
1683 GNUNET_ERROR_TYPE_DEBUG,
1684 "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1685 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1686 inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
1687 source_port,
1688 inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
1689 destination_port,
1690 inet_ntop (destination->details.exit_destination.af,
1691 &destination->details.exit_destination.ip,
1692 xbuf,
1693 sizeof (xbuf)),
1694 destination_port);
1695 }
1696 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1697 if (dt->destination_port == destination_port)
1698 break;
1699 }
1700 else
1701 {
1702 {
1703 char sbuf[INET6_ADDRSTRLEN];
1704 char dbuf[INET6_ADDRSTRLEN];
1705
1706 GNUNET_log (
1707 GNUNET_ERROR_TYPE_DEBUG,
1708 "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1709 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1710 inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
1711 source_port,
1712 inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
1713 destination_port,
1714 GNUNET_h2s (
1715 &destination->details.service_destination.service_descriptor),
1716 GNUNET_i2s (&destination->details.service_destination.target));
1717 }
1718 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1719 if (dt->destination_port == destination_port)
1720 break;
1721 }
1722 if (NULL == dt)
1723 {
1724 dt = GNUNET_new (struct DestinationChannel);
1725 dt->destination = destination;
1726 GNUNET_CONTAINER_DLL_insert (destination->dt_head,
1727 destination->dt_tail,
1728 dt);
1729 dt->destination_port = destination_port;
1730 }
1731 1687
1732 /* see if we have an existing channel for this destination */ 1688 case AF_INET6:
1733 ts = GNUNET_CONTAINER_multihashmap_get (channel_map, &key); 1689 alen = sizeof(struct in6_addr);
1734 if (NULL == ts) 1690 break;
1735 {
1736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1737 "Creating new channel for key %s\n",
1738 GNUNET_h2s (&key));
1739 /* need to either use the existing channel from the destination (if still
1740 available) or create a fresh one */
1741 ts = create_channel_to_destination (dt, af);
1742 if (NULL == ts)
1743 return;
1744 /* now bind existing "unbound" channel to our IP/port tuple */
1745 ts->protocol = protocol;
1746 ts->af = af;
1747 if (AF_INET == af)
1748 {
1749 ts->source_ip.v4 = *(const struct in_addr *) source_ip;
1750 ts->destination_ip.v4 = *(const struct in_addr *) destination_ip;
1751 }
1752 else
1753 {
1754 ts->source_ip.v6 = *(const struct in6_addr *) source_ip;
1755 ts->destination_ip.v6 = *(const struct in6_addr *) destination_ip;
1756 }
1757 ts->source_port = source_port;
1758 ts->destination_port = destination_port;
1759 ts->heap_node =
1760 GNUNET_CONTAINER_heap_insert (channel_heap,
1761 ts,
1762 GNUNET_TIME_absolute_get ().abs_value_us);
1763 GNUNET_assert (GNUNET_YES ==
1764 GNUNET_CONTAINER_multihashmap_put (
1765 channel_map,
1766 &key,
1767 ts,
1768 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1769 GNUNET_STATISTICS_update (stats,
1770 gettext_noop ("# Active channels"),
1771 1,
1772 GNUNET_NO);
1773 while (GNUNET_CONTAINER_multihashmap_size (channel_map) >
1774 max_channel_mappings)
1775 expire_channel (ts);
1776 }
1777 else
1778 {
1779 GNUNET_CONTAINER_heap_update_cost (ts->heap_node,
1780 GNUNET_TIME_absolute_get ()
1781 .abs_value_us);
1782 }
1783 if (NULL == ts->channel)
1784 {
1785 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1786 "Packet dropped, channel to %s not yet ready (%s)\n",
1787 print_channel_destination (&ts->destination),
1788 (NULL == ts->search) ? "EXIT search failed"
1789 : "EXIT search active");
1790 GNUNET_STATISTICS_update (stats,
1791 gettext_noop (
1792 "# Packets dropped (channel not yet online)"),
1793 1,
1794 GNUNET_NO);
1795 return;
1796 }
1797 1691
1798 /* send via channel */ 1692 default:
1799 switch (protocol) 1693 GNUNET_assert(0);
1800 { 1694 }
1801 case IPPROTO_UDP:
1802 if (destination->is_service)
1803 {
1804 struct GNUNET_EXIT_UdpServiceMessage *usm;
1805 1695
1806 mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) + payload_length -
1807 sizeof (struct GNUNET_TUN_UdpHeader);
1808 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1809 { 1696 {
1810 GNUNET_break (0); 1697 char sbuf[INET6_ADDRSTRLEN];
1811 return; 1698 char dbuf[INET6_ADDRSTRLEN];
1699 char xbuf[INET6_ADDRSTRLEN];
1700
1701 GNUNET_log(
1702 GNUNET_ERROR_TYPE_DEBUG,
1703 "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1704 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1705 inet_ntop(af, source_ip, sbuf, sizeof(sbuf)),
1706 source_port,
1707 inet_ntop(af, destination_ip, dbuf, sizeof(dbuf)),
1708 destination_port,
1709 inet_ntop(destination->details.exit_destination.af,
1710 &destination->details.exit_destination.ip,
1711 xbuf,
1712 sizeof(xbuf)),
1713 destination_port);
1812 } 1714 }
1813 env = GNUNET_MQ_msg_extra (usm, 1715 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1814 payload_length - 1716 if (dt->destination_port == destination_port)
1815 sizeof (struct GNUNET_TUN_UdpHeader), 1717 break;
1816 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE); 1718 }
1817 /* if the source port is below 32000, we assume it has a special 1719 else
1818 meaning; if not, we pick a random port (this is a heuristic) */
1819 usm->source_port =
1820 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1821 usm->destination_port = udp->destination_port;
1822 GNUNET_memcpy (&usm[1],
1823 &udp[1],
1824 payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1825 }
1826 else
1827 { 1720 {
1828 struct GNUNET_EXIT_UdpInternetMessage *uim;
1829 struct in_addr *ip4dst;
1830 struct in6_addr *ip6dst;
1831 void *payload;
1832
1833 mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) + alen +
1834 payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1835 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1836 { 1721 {
1837 GNUNET_break (0); 1722 char sbuf[INET6_ADDRSTRLEN];
1838 return; 1723 char dbuf[INET6_ADDRSTRLEN];
1724
1725 GNUNET_log(
1726 GNUNET_ERROR_TYPE_DEBUG,
1727 "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1728 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1729 inet_ntop(af, source_ip, sbuf, sizeof(sbuf)),
1730 source_port,
1731 inet_ntop(af, destination_ip, dbuf, sizeof(dbuf)),
1732 destination_port,
1733 GNUNET_h2s(
1734 &destination->details.service_destination.service_descriptor),
1735 GNUNET_i2s(&destination->details.service_destination.target));
1839 } 1736 }
1840 env = GNUNET_MQ_msg_extra (uim, 1737 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1841 payload_length + alen - 1738 if (dt->destination_port == destination_port)
1842 sizeof (struct GNUNET_TUN_UdpHeader), 1739 break;
1843 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET);
1844 uim->af = htonl (destination->details.exit_destination.af);
1845 uim->source_port =
1846 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1847 uim->destination_port = udp->destination_port;
1848 switch (destination->details.exit_destination.af)
1849 {
1850 case AF_INET:
1851 ip4dst = (struct in_addr *) &uim[1];
1852 *ip4dst = destination->details.exit_destination.ip.v4;
1853 payload = &ip4dst[1];
1854 break;
1855 case AF_INET6:
1856 ip6dst = (struct in6_addr *) &uim[1];
1857 *ip6dst = destination->details.exit_destination.ip.v6;
1858 payload = &ip6dst[1];
1859 break;
1860 default:
1861 GNUNET_assert (0);
1862 }
1863 GNUNET_memcpy (payload,
1864 &udp[1],
1865 payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1866 } 1740 }
1867 break; 1741 if (NULL == dt)
1868 case IPPROTO_TCP:
1869 if (GNUNET_NO == ts->is_established)
1870 { 1742 {
1871 if (destination->is_service) 1743 dt = GNUNET_new(struct DestinationChannel);
1872 { 1744 dt->destination = destination;
1873 struct GNUNET_EXIT_TcpServiceStartMessage *tsm; 1745 GNUNET_CONTAINER_DLL_insert(destination->dt_head,
1746 destination->dt_tail,
1747 dt);
1748 dt->destination_port = destination_port;
1749 }
1874 1750
1875 mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) + 1751 /* see if we have an existing channel for this destination */
1876 payload_length - sizeof (struct GNUNET_TUN_TcpHeader); 1752 ts = GNUNET_CONTAINER_multihashmap_get(channel_map, &key);
1877 if (mlen >= GNUNET_MAX_MESSAGE_SIZE) 1753 if (NULL == ts)
1754 {
1755 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1756 "Creating new channel for key %s\n",
1757 GNUNET_h2s(&key));
1758 /* need to either use the existing channel from the destination (if still
1759 available) or create a fresh one */
1760 ts = create_channel_to_destination(dt, af);
1761 if (NULL == ts)
1762 return;
1763 /* now bind existing "unbound" channel to our IP/port tuple */
1764 ts->protocol = protocol;
1765 ts->af = af;
1766 if (AF_INET == af)
1878 { 1767 {
1879 GNUNET_break (0); 1768 ts->source_ip.v4 = *(const struct in_addr *)source_ip;
1880 return; 1769 ts->destination_ip.v4 = *(const struct in_addr *)destination_ip;
1881 } 1770 }
1882 env =
1883 GNUNET_MQ_msg_extra (tsm,
1884 payload_length -
1885 sizeof (struct GNUNET_TUN_TcpHeader),
1886 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
1887 tsm->reserved = htonl (0);
1888 tsm->tcp_header = *tcp;
1889 GNUNET_memcpy (&tsm[1],
1890 &tcp[1],
1891 payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1892 }
1893 else 1771 else
1894 {
1895 struct GNUNET_EXIT_TcpInternetStartMessage *tim;
1896 struct in_addr *ip4dst;
1897 struct in6_addr *ip6dst;
1898 void *payload;
1899
1900 mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) + alen +
1901 payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1902 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1903 { 1772 {
1904 GNUNET_break (0); 1773 ts->source_ip.v6 = *(const struct in6_addr *)source_ip;
1905 return; 1774 ts->destination_ip.v6 = *(const struct in6_addr *)destination_ip;
1906 }
1907 env =
1908 GNUNET_MQ_msg_extra (tim,
1909 payload_length + alen -
1910 sizeof (struct GNUNET_TUN_TcpHeader),
1911 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
1912 tim->af = htonl (destination->details.exit_destination.af);
1913 tim->tcp_header = *tcp;
1914 switch (destination->details.exit_destination.af)
1915 {
1916 case AF_INET:
1917 ip4dst = (struct in_addr *) &tim[1];
1918 *ip4dst = destination->details.exit_destination.ip.v4;
1919 payload = &ip4dst[1];
1920 break;
1921 case AF_INET6:
1922 ip6dst = (struct in6_addr *) &tim[1];
1923 *ip6dst = destination->details.exit_destination.ip.v6;
1924 payload = &ip6dst[1];
1925 break;
1926 default:
1927 GNUNET_assert (0);
1928 } 1775 }
1929 GNUNET_memcpy (payload, 1776 ts->source_port = source_port;
1930 &tcp[1], 1777 ts->destination_port = destination_port;
1931 payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); 1778 ts->heap_node =
1932 } 1779 GNUNET_CONTAINER_heap_insert(channel_heap,
1780 ts,
1781 GNUNET_TIME_absolute_get().abs_value_us);
1782 GNUNET_assert(GNUNET_YES ==
1783 GNUNET_CONTAINER_multihashmap_put(
1784 channel_map,
1785 &key,
1786 ts,
1787 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1788 GNUNET_STATISTICS_update(stats,
1789 gettext_noop("# Active channels"),
1790 1,
1791 GNUNET_NO);
1792 while (GNUNET_CONTAINER_multihashmap_size(channel_map) >
1793 max_channel_mappings)
1794 expire_channel(ts);
1933 } 1795 }
1934 else 1796 else
1935 { 1797 {
1936 struct GNUNET_EXIT_TcpDataMessage *tdm; 1798 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1937 1799 GNUNET_TIME_absolute_get()
1938 mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + payload_length - 1800 .abs_value_us);
1939 sizeof (struct GNUNET_TUN_TcpHeader);
1940 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1941 {
1942 GNUNET_break (0);
1943 return;
1944 }
1945 env = GNUNET_MQ_msg_extra (tdm,
1946 payload_length -
1947 sizeof (struct GNUNET_TUN_TcpHeader),
1948 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT);
1949 tdm->reserved = htonl (0);
1950 tdm->tcp_header = *tcp;
1951 GNUNET_memcpy (&tdm[1],
1952 &tcp[1],
1953 payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1954 } 1801 }
1955 break; 1802 if (NULL == ts->channel)
1956 case IPPROTO_ICMP:
1957 case IPPROTO_ICMPV6:
1958 if (destination->is_service)
1959 { 1803 {
1960 struct GNUNET_EXIT_IcmpServiceMessage *ism; 1804 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1805 "Packet dropped, channel to %s not yet ready (%s)\n",
1806 print_channel_destination(&ts->destination),
1807 (NULL == ts->search) ? "EXIT search failed"
1808 : "EXIT search active");
1809 GNUNET_STATISTICS_update(stats,
1810 gettext_noop(
1811 "# Packets dropped (channel not yet online)"),
1812 1,
1813 GNUNET_NO);
1814 return;
1815 }
1961 1816
1962 /* ICMP protocol translation will be done by the receiver (as we don't know 1817 /* send via channel */
1963 the target AF); however, we still need to possibly discard the payload 1818 switch (protocol)
1964 depending on the ICMP type */ 1819 {
1965 switch (af) 1820 case IPPROTO_UDP:
1966 { 1821 if (destination->is_service)
1967 case AF_INET:
1968 switch (icmp->type)
1969 { 1822 {
1970 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: 1823 struct GNUNET_EXIT_UdpServiceMessage *usm;
1971 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: 1824
1972 break; 1825 mlen = sizeof(struct GNUNET_EXIT_UdpServiceMessage) + payload_length -
1973 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: 1826 sizeof(struct GNUNET_TUN_UdpHeader);
1974 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 1827 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1975 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: 1828 {
1976 /* throw away ICMP payload, won't be useful for the other side anyway */ 1829 GNUNET_break(0);
1977 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 1830 return;
1978 break; 1831 }
1979 default: 1832 env = GNUNET_MQ_msg_extra(usm,
1980 GNUNET_STATISTICS_update (stats, 1833 payload_length -
1981 gettext_noop ( 1834 sizeof(struct GNUNET_TUN_UdpHeader),
1982 "# ICMPv4 packets dropped (not allowed)"), 1835 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE);
1983 1, 1836 /* if the source port is below 32000, we assume it has a special
1984 GNUNET_NO); 1837 meaning; if not, we pick a random port (this is a heuristic) */
1985 return; 1838 usm->source_port =
1839 (ntohs(udp->source_port) < 32000) ? udp->source_port : 0;
1840 usm->destination_port = udp->destination_port;
1841 GNUNET_memcpy(&usm[1],
1842 &udp[1],
1843 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1986 } 1844 }
1987 /* end of AF_INET */ 1845 else
1988 break;
1989 case AF_INET6:
1990 switch (icmp->type)
1991 { 1846 {
1992 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: 1847 struct GNUNET_EXIT_UdpInternetMessage *uim;
1993 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: 1848 struct in_addr *ip4dst;
1994 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: 1849 struct in6_addr *ip6dst;
1995 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: 1850 void *payload;
1996 /* throw away ICMP payload, won't be useful for the other side anyway */ 1851
1997 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 1852 mlen = sizeof(struct GNUNET_EXIT_UdpInternetMessage) + alen +
1998 break; 1853 payload_length - sizeof(struct GNUNET_TUN_UdpHeader);
1999 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: 1854 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2000 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: 1855 {
2001 break; 1856 GNUNET_break(0);
2002 default: 1857 return;
2003 GNUNET_STATISTICS_update (stats, 1858 }
2004 gettext_noop ( 1859 env = GNUNET_MQ_msg_extra(uim,
2005 "# ICMPv6 packets dropped (not allowed)"), 1860 payload_length + alen -
2006 1, 1861 sizeof(struct GNUNET_TUN_UdpHeader),
2007 GNUNET_NO); 1862 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET);
2008 return; 1863 uim->af = htonl(destination->details.exit_destination.af);
1864 uim->source_port =
1865 (ntohs(udp->source_port) < 32000) ? udp->source_port : 0;
1866 uim->destination_port = udp->destination_port;
1867 switch (destination->details.exit_destination.af)
1868 {
1869 case AF_INET:
1870 ip4dst = (struct in_addr *)&uim[1];
1871 *ip4dst = destination->details.exit_destination.ip.v4;
1872 payload = &ip4dst[1];
1873 break;
1874
1875 case AF_INET6:
1876 ip6dst = (struct in6_addr *)&uim[1];
1877 *ip6dst = destination->details.exit_destination.ip.v6;
1878 payload = &ip6dst[1];
1879 break;
1880
1881 default:
1882 GNUNET_assert(0);
1883 }
1884 GNUNET_memcpy(payload,
1885 &udp[1],
1886 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
2009 } 1887 }
2010 /* end of AF_INET6 */ 1888 break;
2011 break;
2012 default:
2013 GNUNET_assert (0);
2014 break;
2015 }
2016 1889
2017 /* update length calculations, as payload_length may have changed */ 1890 case IPPROTO_TCP:
2018 mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + alen + 1891 if (GNUNET_NO == ts->is_established)
2019 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); 1892 {
2020 if (mlen >= GNUNET_MAX_MESSAGE_SIZE) 1893 if (destination->is_service)
2021 { 1894 {
2022 GNUNET_break (0); 1895 struct GNUNET_EXIT_TcpServiceStartMessage *tsm;
2023 return; 1896
2024 } 1897 mlen = sizeof(struct GNUNET_EXIT_TcpServiceStartMessage) +
1898 payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1899 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1900 {
1901 GNUNET_break(0);
1902 return;
1903 }
1904 env =
1905 GNUNET_MQ_msg_extra(tsm,
1906 payload_length -
1907 sizeof(struct GNUNET_TUN_TcpHeader),
1908 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
1909 tsm->reserved = htonl(0);
1910 tsm->tcp_header = *tcp;
1911 GNUNET_memcpy(&tsm[1],
1912 &tcp[1],
1913 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1914 }
1915 else
1916 {
1917 struct GNUNET_EXIT_TcpInternetStartMessage *tim;
1918 struct in_addr *ip4dst;
1919 struct in6_addr *ip6dst;
1920 void *payload;
1921
1922 mlen = sizeof(struct GNUNET_EXIT_TcpInternetStartMessage) + alen +
1923 payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1924 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1925 {
1926 GNUNET_break(0);
1927 return;
1928 }
1929 env =
1930 GNUNET_MQ_msg_extra(tim,
1931 payload_length + alen -
1932 sizeof(struct GNUNET_TUN_TcpHeader),
1933 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
1934 tim->af = htonl(destination->details.exit_destination.af);
1935 tim->tcp_header = *tcp;
1936 switch (destination->details.exit_destination.af)
1937 {
1938 case AF_INET:
1939 ip4dst = (struct in_addr *)&tim[1];
1940 *ip4dst = destination->details.exit_destination.ip.v4;
1941 payload = &ip4dst[1];
1942 break;
1943
1944 case AF_INET6:
1945 ip6dst = (struct in6_addr *)&tim[1];
1946 *ip6dst = destination->details.exit_destination.ip.v6;
1947 payload = &ip6dst[1];
1948 break;
1949
1950 default:
1951 GNUNET_assert(0);
1952 }
1953 GNUNET_memcpy(payload,
1954 &tcp[1],
1955 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1956 }
1957 }
1958 else
1959 {
1960 struct GNUNET_EXIT_TcpDataMessage *tdm;
2025 1961
2026 env = GNUNET_MQ_msg_extra (ism, 1962 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + payload_length -
2027 payload_length - 1963 sizeof(struct GNUNET_TUN_TcpHeader);
2028 sizeof (struct GNUNET_TUN_IcmpHeader), 1964 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2029 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE); 1965 {
2030 ism->af = htonl (af); /* need to tell destination ICMP protocol family! */ 1966 GNUNET_break(0);
2031 ism->icmp_header = *icmp; 1967 return;
2032 GNUNET_memcpy (&ism[1], 1968 }
2033 &icmp[1], 1969 env = GNUNET_MQ_msg_extra(tdm,
2034 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); 1970 payload_length -
2035 } 1971 sizeof(struct GNUNET_TUN_TcpHeader),
2036 else 1972 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT);
2037 { 1973 tdm->reserved = htonl(0);
2038 struct GNUNET_EXIT_IcmpInternetMessage *iim; 1974 tdm->tcp_header = *tcp;
2039 struct in_addr *ip4dst; 1975 GNUNET_memcpy(&tdm[1],
2040 struct in6_addr *ip6dst; 1976 &tcp[1],
2041 void *payload; 1977 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
2042 uint8_t new_type; 1978 }
2043 1979 break;
2044 new_type = icmp->type; 1980
2045 /* Perform ICMP protocol-translation (depending on destination AF and source AF) 1981 case IPPROTO_ICMP:
2046 and throw away ICMP payload depending on ICMP message type */ 1982 case IPPROTO_ICMPV6:
2047 switch (af) 1983 if (destination->is_service)
2048 {
2049 case AF_INET:
2050 switch (icmp->type)
2051 { 1984 {
2052 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: 1985 struct GNUNET_EXIT_IcmpServiceMessage *ism;
2053 if (destination->details.exit_destination.af == AF_INET6) 1986
2054 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; 1987 /* ICMP protocol translation will be done by the receiver (as we don't know
2055 break; 1988 the target AF); however, we still need to possibly discard the payload
2056 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: 1989 depending on the ICMP type */
2057 if (destination->details.exit_destination.af == AF_INET6) 1990 switch (af)
2058 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; 1991 {
2059 break; 1992 case AF_INET:
2060 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: 1993 switch (icmp->type)
2061 if (destination->details.exit_destination.af == AF_INET6) 1994 {
2062 new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; 1995 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2063 /* throw away IP-payload, exit will have to make it up anyway */ 1996 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2064 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 1997 break;
2065 break; 1998
2066 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: 1999 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2067 if (destination->details.exit_destination.af == AF_INET6) 2000 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2068 new_type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; 2001 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2069 /* throw away IP-payload, exit will have to make it up anyway */ 2002 /* throw away ICMP payload, won't be useful for the other side anyway */
2070 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2003 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2071 break; 2004 break;
2072 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 2005
2073 if (destination->details.exit_destination.af == AF_INET6) 2006 default:
2074 { 2007 GNUNET_STATISTICS_update(stats,
2075 GNUNET_STATISTICS_update ( 2008 gettext_noop(
2076 stats, 2009 "# ICMPv4 packets dropped (not allowed)"),
2077 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), 2010 1,
2078 1, 2011 GNUNET_NO);
2079 GNUNET_NO); 2012 return;
2080 return; 2013 }
2081 } 2014 /* end of AF_INET */
2082 /* throw away IP-payload, exit will have to make it up anyway */ 2015 break;
2083 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2016
2084 break; 2017 case AF_INET6:
2085 default: 2018 switch (icmp->type)
2086 GNUNET_STATISTICS_update ( 2019 {
2087 stats, 2020 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2088 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), 2021 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2089 1, 2022 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2090 GNUNET_NO); 2023 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2091 return; 2024 /* throw away ICMP payload, won't be useful for the other side anyway */
2025 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2026 break;
2027
2028 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2029 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2030 break;
2031
2032 default:
2033 GNUNET_STATISTICS_update(stats,
2034 gettext_noop(
2035 "# ICMPv6 packets dropped (not allowed)"),
2036 1,
2037 GNUNET_NO);
2038 return;
2039 }
2040 /* end of AF_INET6 */
2041 break;
2042
2043 default:
2044 GNUNET_assert(0);
2045 break;
2046 }
2047
2048 /* update length calculations, as payload_length may have changed */
2049 mlen = sizeof(struct GNUNET_EXIT_IcmpServiceMessage) + alen +
2050 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2051 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2052 {
2053 GNUNET_break(0);
2054 return;
2055 }
2056
2057 env = GNUNET_MQ_msg_extra(ism,
2058 payload_length -
2059 sizeof(struct GNUNET_TUN_IcmpHeader),
2060 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE);
2061 ism->af = htonl(af); /* need to tell destination ICMP protocol family! */
2062 ism->icmp_header = *icmp;
2063 GNUNET_memcpy(&ism[1],
2064 &icmp[1],
2065 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2092 } 2066 }
2093 /* end of AF_INET */ 2067 else
2094 break;
2095 case AF_INET6:
2096 switch (icmp->type)
2097 { 2068 {
2098 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: 2069 struct GNUNET_EXIT_IcmpInternetMessage *iim;
2099 if (destination->details.exit_destination.af == AF_INET) 2070 struct in_addr *ip4dst;
2100 new_type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; 2071 struct in6_addr *ip6dst;
2101 /* throw away IP-payload, exit will have to make it up anyway */ 2072 void *payload;
2102 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2073 uint8_t new_type;
2103 break; 2074
2104 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: 2075 new_type = icmp->type;
2105 if (destination->details.exit_destination.af == AF_INET) 2076 /* Perform ICMP protocol-translation (depending on destination AF and source AF)
2106 new_type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; 2077 and throw away ICMP payload depending on ICMP message type */
2107 /* throw away IP-payload, exit will have to make it up anyway */ 2078 switch (af)
2108 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2079 {
2109 break; 2080 case AF_INET:
2110 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: 2081 switch (icmp->type)
2111 if (destination->details.exit_destination.af == AF_INET) 2082 {
2112 { 2083 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2113 GNUNET_STATISTICS_update ( 2084 if (destination->details.exit_destination.af == AF_INET6)
2114 stats, 2085 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2115 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), 2086 break;
2116 1, 2087
2117 GNUNET_NO); 2088 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2118 return; 2089 if (destination->details.exit_destination.af == AF_INET6)
2119 } 2090 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
2120 /* throw away IP-payload, exit will have to make it up anyway */ 2091 break;
2121 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2092
2122 break; 2093 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2123 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: 2094 if (destination->details.exit_destination.af == AF_INET6)
2124 if (destination->details.exit_destination.af == AF_INET) 2095 new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
2125 { 2096 /* throw away IP-payload, exit will have to make it up anyway */
2126 GNUNET_STATISTICS_update ( 2097 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2127 stats, 2098 break;
2128 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), 2099
2129 1, 2100 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2130 GNUNET_NO); 2101 if (destination->details.exit_destination.af == AF_INET6)
2131 return; 2102 new_type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
2132 } 2103 /* throw away IP-payload, exit will have to make it up anyway */
2133 /* throw away IP-payload, exit will have to make it up anyway */ 2104 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2134 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2105 break;
2135 break; 2106
2136 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: 2107 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2137 if (destination->details.exit_destination.af == AF_INET) 2108 if (destination->details.exit_destination.af == AF_INET6)
2138 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; 2109 {
2139 break; 2110 GNUNET_STATISTICS_update(
2140 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: 2111 stats,
2141 if (destination->details.exit_destination.af == AF_INET) 2112 gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
2142 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; 2113 1,
2143 break; 2114 GNUNET_NO);
2144 default: 2115 return;
2145 GNUNET_STATISTICS_update ( 2116 }
2146 stats, 2117 /* throw away IP-payload, exit will have to make it up anyway */
2147 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), 2118 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2148 1, 2119 break;
2149 GNUNET_NO); 2120
2150 return; 2121 default:
2122 GNUNET_STATISTICS_update(
2123 stats,
2124 gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2125 1,
2126 GNUNET_NO);
2127 return;
2128 }
2129 /* end of AF_INET */
2130 break;
2131
2132 case AF_INET6:
2133 switch (icmp->type)
2134 {
2135 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2136 if (destination->details.exit_destination.af == AF_INET)
2137 new_type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
2138 /* throw away IP-payload, exit will have to make it up anyway */
2139 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2140 break;
2141
2142 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2143 if (destination->details.exit_destination.af == AF_INET)
2144 new_type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
2145 /* throw away IP-payload, exit will have to make it up anyway */
2146 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2147 break;
2148
2149 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2150 if (destination->details.exit_destination.af == AF_INET)
2151 {
2152 GNUNET_STATISTICS_update(
2153 stats,
2154 gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2155 1,
2156 GNUNET_NO);
2157 return;
2158 }
2159 /* throw away IP-payload, exit will have to make it up anyway */
2160 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2161 break;
2162
2163 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2164 if (destination->details.exit_destination.af == AF_INET)
2165 {
2166 GNUNET_STATISTICS_update(
2167 stats,
2168 gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2169 1,
2170 GNUNET_NO);
2171 return;
2172 }
2173 /* throw away IP-payload, exit will have to make it up anyway */
2174 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2175 break;
2176
2177 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2178 if (destination->details.exit_destination.af == AF_INET)
2179 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
2180 break;
2181
2182 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2183 if (destination->details.exit_destination.af == AF_INET)
2184 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2185 break;
2186
2187 default:
2188 GNUNET_STATISTICS_update(
2189 stats,
2190 gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2191 1,
2192 GNUNET_NO);
2193 return;
2194 }
2195 /* end of AF_INET6 */
2196 break;
2197
2198 default:
2199 GNUNET_assert(0);
2200 }
2201
2202 /* update length calculations, as payload_length may have changed */
2203 mlen = sizeof(struct GNUNET_EXIT_IcmpInternetMessage) + alen +
2204 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2205 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2206 {
2207 GNUNET_break(0);
2208 return;
2209 }
2210 env = GNUNET_MQ_msg_extra(iim,
2211 alen + payload_length -
2212 sizeof(struct GNUNET_TUN_IcmpHeader),
2213 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET);
2214 iim->icmp_header = *icmp;
2215 iim->icmp_header.type = new_type;
2216 iim->af = htonl(destination->details.exit_destination.af);
2217 switch (destination->details.exit_destination.af)
2218 {
2219 case AF_INET:
2220 ip4dst = (struct in_addr *)&iim[1];
2221 *ip4dst = destination->details.exit_destination.ip.v4;
2222 payload = &ip4dst[1];
2223 break;
2224
2225 case AF_INET6:
2226 ip6dst = (struct in6_addr *)&iim[1];
2227 *ip6dst = destination->details.exit_destination.ip.v6;
2228 payload = &ip6dst[1];
2229 break;
2230
2231 default:
2232 GNUNET_assert(0);
2233 }
2234 GNUNET_memcpy(payload,
2235 &icmp[1],
2236 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2151 } 2237 }
2152 /* end of AF_INET6 */ 2238 break;
2153 break;
2154 default:
2155 GNUNET_assert (0);
2156 }
2157 2239
2158 /* update length calculations, as payload_length may have changed */ 2240 default:
2159 mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + alen + 2241 /* not supported above, how can we get here !? */
2160 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); 2242 GNUNET_assert(0);
2161 if (mlen >= GNUNET_MAX_MESSAGE_SIZE) 2243 break;
2162 {
2163 GNUNET_break (0);
2164 return;
2165 }
2166 env = GNUNET_MQ_msg_extra (iim,
2167 alen + payload_length -
2168 sizeof (struct GNUNET_TUN_IcmpHeader),
2169 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET);
2170 iim->icmp_header = *icmp;
2171 iim->icmp_header.type = new_type;
2172 iim->af = htonl (destination->details.exit_destination.af);
2173 switch (destination->details.exit_destination.af)
2174 {
2175 case AF_INET:
2176 ip4dst = (struct in_addr *) &iim[1];
2177 *ip4dst = destination->details.exit_destination.ip.v4;
2178 payload = &ip4dst[1];
2179 break;
2180 case AF_INET6:
2181 ip6dst = (struct in6_addr *) &iim[1];
2182 *ip6dst = destination->details.exit_destination.ip.v6;
2183 payload = &ip6dst[1];
2184 break;
2185 default:
2186 GNUNET_assert (0);
2187 }
2188 GNUNET_memcpy (payload,
2189 &icmp[1],
2190 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
2191 } 2244 }
2192 break;
2193 default:
2194 /* not supported above, how can we get here !? */
2195 GNUNET_assert (0);
2196 break;
2197 }
2198 ts->is_established = GNUNET_YES; 2245 ts->is_established = GNUNET_YES;
2199 send_to_channel (ts, env); 2246 send_to_channel(ts, env);
2200} 2247}
2201 2248
2202 2249
@@ -2213,106 +2260,108 @@ route_packet (struct DestinationEntry *destination,
2213 * #GNUNET_SYSERR to stop further processing with error 2260 * #GNUNET_SYSERR to stop further processing with error
2214 */ 2261 */
2215static int 2262static int
2216message_token (void *cls, const struct GNUNET_MessageHeader *message) 2263message_token(void *cls, const struct GNUNET_MessageHeader *message)
2217{ 2264{
2218 const struct GNUNET_TUN_Layer2PacketHeader *tun; 2265 const struct GNUNET_TUN_Layer2PacketHeader *tun;
2219 size_t mlen; 2266 size_t mlen;
2220 struct GNUNET_HashCode key; 2267 struct GNUNET_HashCode key;
2221 struct DestinationEntry *de; 2268 struct DestinationEntry *de;
2222 2269
2223 GNUNET_STATISTICS_update (stats, 2270 GNUNET_STATISTICS_update(stats,
2224 gettext_noop ( 2271 gettext_noop(
2225 "# Packets received from TUN interface"), 2272 "# Packets received from TUN interface"),
2226 1, 2273 1,
2227 GNUNET_NO); 2274 GNUNET_NO);
2228 mlen = ntohs (message->size); 2275 mlen = ntohs(message->size);
2229 if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || 2276 if ((ntohs(message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
2230 (mlen < sizeof (struct GNUNET_MessageHeader) + 2277 (mlen < sizeof(struct GNUNET_MessageHeader) +
2231 sizeof (struct GNUNET_TUN_Layer2PacketHeader))) 2278 sizeof(struct GNUNET_TUN_Layer2PacketHeader)))
2232 {
2233 GNUNET_break (0);
2234 return GNUNET_OK;
2235 }
2236 tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
2237 mlen -= (sizeof (struct GNUNET_MessageHeader) +
2238 sizeof (struct GNUNET_TUN_Layer2PacketHeader));
2239 switch (ntohs (tun->proto))
2240 {
2241 case ETH_P_IPV6: {
2242 const struct GNUNET_TUN_IPv6Header *pkt6;
2243
2244 if (mlen < sizeof (struct GNUNET_TUN_IPv6Header))
2245 { 2279 {
2246 /* blame kernel */ 2280 GNUNET_break(0);
2247 GNUNET_break (0);
2248 return GNUNET_OK; 2281 return GNUNET_OK;
2249 } 2282 }
2250 pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1]; 2283 tun = (const struct GNUNET_TUN_Layer2PacketHeader *)&message[1];
2251 get_destination_key_from_ip (AF_INET6, &pkt6->destination_address, &key); 2284 mlen -= (sizeof(struct GNUNET_MessageHeader) +
2252 de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key); 2285 sizeof(struct GNUNET_TUN_Layer2PacketHeader));
2253 if (NULL == de) 2286 switch (ntohs(tun->proto))
2254 { 2287 {
2255 char buf[INET6_ADDRSTRLEN]; 2288 case ETH_P_IPV6: {
2289 const struct GNUNET_TUN_IPv6Header *pkt6;
2256 2290
2257 GNUNET_log ( 2291 if (mlen < sizeof(struct GNUNET_TUN_IPv6Header))
2258 GNUNET_ERROR_TYPE_INFO, 2292 {
2259 _ ("Packet received for unmapped destination `%s' (dropping it)\n"), 2293 /* blame kernel */
2260 inet_ntop (AF_INET6, &pkt6->destination_address, buf, sizeof (buf))); 2294 GNUNET_break(0);
2261 return GNUNET_OK; 2295 return GNUNET_OK;
2296 }
2297 pkt6 = (const struct GNUNET_TUN_IPv6Header *)&tun[1];
2298 get_destination_key_from_ip(AF_INET6, &pkt6->destination_address, &key);
2299 de = GNUNET_CONTAINER_multihashmap_get(destination_map, &key);
2300 if (NULL == de)
2301 {
2302 char buf[INET6_ADDRSTRLEN];
2303
2304 GNUNET_log(
2305 GNUNET_ERROR_TYPE_INFO,
2306 _("Packet received for unmapped destination `%s' (dropping it)\n"),
2307 inet_ntop(AF_INET6, &pkt6->destination_address, buf, sizeof(buf)));
2308 return GNUNET_OK;
2309 }
2310 route_packet(de,
2311 AF_INET6,
2312 pkt6->next_header,
2313 &pkt6->source_address,
2314 &pkt6->destination_address,
2315 &pkt6[1],
2316 mlen - sizeof(struct GNUNET_TUN_IPv6Header));
2262 } 2317 }
2263 route_packet (de, 2318 break;
2264 AF_INET6,
2265 pkt6->next_header,
2266 &pkt6->source_address,
2267 &pkt6->destination_address,
2268 &pkt6[1],
2269 mlen - sizeof (struct GNUNET_TUN_IPv6Header));
2270 }
2271 break;
2272 case ETH_P_IPV4: {
2273 struct GNUNET_TUN_IPv4Header *pkt4;
2274 2319
2275 if (mlen < sizeof (struct GNUNET_TUN_IPv4Header)) 2320 case ETH_P_IPV4: {
2276 { 2321 struct GNUNET_TUN_IPv4Header *pkt4;
2277 /* blame kernel */ 2322
2278 GNUNET_break (0); 2323 if (mlen < sizeof(struct GNUNET_TUN_IPv4Header))
2279 return GNUNET_OK; 2324 {
2325 /* blame kernel */
2326 GNUNET_break(0);
2327 return GNUNET_OK;
2328 }
2329 pkt4 = (struct GNUNET_TUN_IPv4Header *)&tun[1];
2330 get_destination_key_from_ip(AF_INET, &pkt4->destination_address, &key);
2331 de = GNUNET_CONTAINER_multihashmap_get(destination_map, &key);
2332 if (NULL == de)
2333 {
2334 char buf[INET_ADDRSTRLEN];
2335
2336 GNUNET_log(
2337 GNUNET_ERROR_TYPE_INFO,
2338 _("Packet received for unmapped destination `%s' (dropping it)\n"),
2339 inet_ntop(AF_INET, &pkt4->destination_address, buf, sizeof(buf)));
2340 return GNUNET_OK;
2341 }
2342 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
2343 {
2344 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2345 _("Received IPv4 packet with options (dropping it)\n"));
2346 return GNUNET_OK;
2347 }
2348 route_packet(de,
2349 AF_INET,
2350 pkt4->protocol,
2351 &pkt4->source_address,
2352 &pkt4->destination_address,
2353 &pkt4[1],
2354 mlen - sizeof(struct GNUNET_TUN_IPv4Header));
2280 } 2355 }
2281 pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; 2356 break;
2282 get_destination_key_from_ip (AF_INET, &pkt4->destination_address, &key);
2283 de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
2284 if (NULL == de)
2285 {
2286 char buf[INET_ADDRSTRLEN];
2287 2357
2288 GNUNET_log ( 2358 default:
2359 GNUNET_log(
2289 GNUNET_ERROR_TYPE_INFO, 2360 GNUNET_ERROR_TYPE_INFO,
2290 _ ("Packet received for unmapped destination `%s' (dropping it)\n"), 2361 _("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2291 inet_ntop (AF_INET, &pkt4->destination_address, buf, sizeof (buf))); 2362 (unsigned int)ntohs(tun->proto));
2292 return GNUNET_OK; 2363 break;
2293 }
2294 if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
2295 {
2296 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2297 _ ("Received IPv4 packet with options (dropping it)\n"));
2298 return GNUNET_OK;
2299 } 2364 }
2300 route_packet (de,
2301 AF_INET,
2302 pkt4->protocol,
2303 &pkt4->source_address,
2304 &pkt4->destination_address,
2305 &pkt4[1],
2306 mlen - sizeof (struct GNUNET_TUN_IPv4Header));
2307 }
2308 break;
2309 default:
2310 GNUNET_log (
2311 GNUNET_ERROR_TYPE_INFO,
2312 _ ("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2313 (unsigned int) ntohs (tun->proto));
2314 break;
2315 }
2316 return GNUNET_OK; 2365 return GNUNET_OK;
2317} 2366}
2318 2367
@@ -2326,7 +2375,7 @@ message_token (void *cls, const struct GNUNET_MessageHeader *message)
2326 * #GNUNET_SYSERR on error 2375 * #GNUNET_SYSERR on error
2327 */ 2376 */
2328static int 2377static int
2329allocate_v4_address (struct in_addr *v4) 2378allocate_v4_address(struct in_addr *v4)
2330{ 2379{
2331 const char *ipv4addr = vpn_argv[4]; 2380 const char *ipv4addr = vpn_argv[4];
2332 const char *ipv4mask = vpn_argv[5]; 2381 const char *ipv4mask = vpn_argv[5];
@@ -2336,30 +2385,31 @@ allocate_v4_address (struct in_addr *v4)
2336 struct GNUNET_HashCode key; 2385 struct GNUNET_HashCode key;
2337 unsigned int tries; 2386 unsigned int tries;
2338 2387
2339 GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr)); 2388 GNUNET_assert(1 == inet_pton(AF_INET, ipv4addr, &addr));
2340 GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask)); 2389 GNUNET_assert(1 == inet_pton(AF_INET, ipv4mask, &mask));
2341 /* Given 192.168.0.1/255.255.0.0, we want a mask 2390 /* Given 192.168.0.1/255.255.0.0, we want a mask
2342 of '192.168.255.255', thus: */ 2391 of '192.168.255.255', thus: */
2343 mask.s_addr = addr.s_addr | ~mask.s_addr; 2392 mask.s_addr = addr.s_addr | ~mask.s_addr;
2344 tries = 0; 2393 tries = 0;
2345 do 2394 do
2346 {
2347 tries++;
2348 if (tries > 16)
2349 { 2395 {
2350 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2396 tries++;
2351 _ ( 2397 if (tries > 16)
2352 "Failed to find unallocated IPv4 address in VPN's range\n")); 2398 {
2353 return GNUNET_SYSERR; 2399 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2400 _(
2401 "Failed to find unallocated IPv4 address in VPN's range\n"));
2402 return GNUNET_SYSERR;
2403 }
2404 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2405 rnd.s_addr =
2406 GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
2407 v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2408 get_destination_key_from_ip(AF_INET, v4, &key);
2354 } 2409 }
2355 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */ 2410 while ((GNUNET_YES ==
2356 rnd.s_addr = 2411 GNUNET_CONTAINER_multihashmap_contains(destination_map, &key)) ||
2357 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); 2412 (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2358 v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2359 get_destination_key_from_ip (AF_INET, v4, &key);
2360 } while ((GNUNET_YES ==
2361 GNUNET_CONTAINER_multihashmap_contains (destination_map, &key)) ||
2362 (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2363 return GNUNET_OK; 2413 return GNUNET_OK;
2364} 2414}
2365 2415
@@ -2373,7 +2423,7 @@ allocate_v4_address (struct in_addr *v4)
2373 * #GNUNET_SYSERR on error 2423 * #GNUNET_SYSERR on error
2374 */ 2424 */
2375static int 2425static int
2376allocate_v6_address (struct in6_addr *v6) 2426allocate_v6_address(struct in6_addr *v6)
2377{ 2427{
2378 const char *ipv6addr = vpn_argv[2]; 2428 const char *ipv6addr = vpn_argv[2];
2379 struct in6_addr addr; 2429 struct in6_addr addr;
@@ -2383,8 +2433,8 @@ allocate_v6_address (struct in6_addr *v6)
2383 struct GNUNET_HashCode key; 2433 struct GNUNET_HashCode key;
2384 unsigned int tries; 2434 unsigned int tries;
2385 2435
2386 GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr)); 2436 GNUNET_assert(1 == inet_pton(AF_INET6, ipv6addr, &addr));
2387 GNUNET_assert (ipv6prefix < 128); 2437 GNUNET_assert(ipv6prefix < 128);
2388 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF, 2438 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2389 thus: */ 2439 thus: */
2390 mask = addr; 2440 mask = addr;
@@ -2394,27 +2444,28 @@ allocate_v6_address (struct in6_addr *v6)
2394 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */ 2444 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2395 tries = 0; 2445 tries = 0;
2396 do 2446 do
2397 {
2398 tries++;
2399 if (tries > 16)
2400 { 2447 {
2401 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2448 tries++;
2402 _ ( 2449 if (tries > 16)
2403 "Failed to find unallocated IPv6 address in VPN's range\n")); 2450 {
2404 return GNUNET_SYSERR; 2451 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2452 _(
2453 "Failed to find unallocated IPv6 address in VPN's range\n"));
2454 return GNUNET_SYSERR;
2455 }
2456 for (i = 0; i < 16; i++)
2457 {
2458 rnd.s6_addr[i] =
2459 (unsigned char)GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK,
2460 256);
2461 v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2462 }
2463 get_destination_key_from_ip(AF_INET6, v6, &key);
2405 } 2464 }
2406 for (i = 0; i < 16; i++) 2465 while ((GNUNET_YES ==
2407 { 2466 GNUNET_CONTAINER_multihashmap_contains(destination_map, &key)) ||
2408 rnd.s6_addr[i] = 2467 (0 == GNUNET_memcmp(v6, &addr)) ||
2409 (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2468 (0 == GNUNET_memcmp(v6, &mask)));
2410 256);
2411 v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2412 }
2413 get_destination_key_from_ip (AF_INET6, v6, &key);
2414 } while ((GNUNET_YES ==
2415 GNUNET_CONTAINER_multihashmap_contains (destination_map, &key)) ||
2416 (0 == GNUNET_memcmp (v6, &addr)) ||
2417 (0 == GNUNET_memcmp (v6, &mask)));
2418 return GNUNET_OK; 2469 return GNUNET_OK;
2419} 2470}
2420 2471
@@ -2425,31 +2476,31 @@ allocate_v6_address (struct in6_addr *v6)
2425 * @param de entry to free 2476 * @param de entry to free
2426 */ 2477 */
2427static void 2478static void
2428free_destination_entry (struct DestinationEntry *de) 2479free_destination_entry(struct DestinationEntry *de)
2429{ 2480{
2430 struct DestinationChannel *dt; 2481 struct DestinationChannel *dt;
2431 2482
2432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2483 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2433 "Cleaning up destination entry `%s'\n", 2484 "Cleaning up destination entry `%s'\n",
2434 print_channel_destination (de)); 2485 print_channel_destination(de));
2435 GNUNET_STATISTICS_update (stats, 2486 GNUNET_STATISTICS_update(stats,
2436 gettext_noop ("# Active destinations"), 2487 gettext_noop("# Active destinations"),
2437 -1, 2488 -1,
2438 GNUNET_NO); 2489 GNUNET_NO);
2439 while (NULL != (dt = de->dt_head)) 2490 while (NULL != (dt = de->dt_head))
2440 { 2491 {
2441 GNUNET_CONTAINER_DLL_remove (de->dt_head, de->dt_tail, dt); 2492 GNUNET_CONTAINER_DLL_remove(de->dt_head, de->dt_tail, dt);
2442 GNUNET_free (dt); 2493 GNUNET_free(dt);
2443 } 2494 }
2444 if (NULL != de->heap_node) 2495 if (NULL != de->heap_node)
2445 { 2496 {
2446 GNUNET_CONTAINER_heap_remove_node (de->heap_node); 2497 GNUNET_CONTAINER_heap_remove_node(de->heap_node);
2447 de->heap_node = NULL; 2498 de->heap_node = NULL;
2448 GNUNET_assert ( 2499 GNUNET_assert(
2449 GNUNET_YES == 2500 GNUNET_YES ==
2450 GNUNET_CONTAINER_multihashmap_remove (destination_map, &de->key, de)); 2501 GNUNET_CONTAINER_multihashmap_remove(destination_map, &de->key, de));
2451 } 2502 }
2452 GNUNET_free (de); 2503 GNUNET_free(de);
2453} 2504}
2454 2505
2455 2506
@@ -2459,15 +2510,15 @@ free_destination_entry (struct DestinationEntry *de)
2459 * @param except destination that must NOT be cleaned up, even if it is the oldest 2510 * @param except destination that must NOT be cleaned up, even if it is the oldest
2460 */ 2511 */
2461static void 2512static void
2462expire_destination (struct DestinationEntry *except) 2513expire_destination(struct DestinationEntry *except)
2463{ 2514{
2464 struct DestinationEntry *de; 2515 struct DestinationEntry *de;
2465 2516
2466 de = GNUNET_CONTAINER_heap_peek (destination_heap); 2517 de = GNUNET_CONTAINER_heap_peek(destination_heap);
2467 GNUNET_assert (NULL != de); 2518 GNUNET_assert(NULL != de);
2468 if (except == de) 2519 if (except == de)
2469 return; /* can't do this */ 2520 return; /* can't do this */
2470 free_destination_entry (de); 2521 free_destination_entry(de);
2471} 2522}
2472 2523
2473 2524
@@ -2486,42 +2537,45 @@ expire_destination (struct DestinationEntry *except)
2486 * an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC) 2537 * an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC)
2487 */ 2538 */
2488static int 2539static int
2489allocate_response_ip (int *result_af, 2540allocate_response_ip(int *result_af,
2490 void **addr, 2541 void **addr,
2491 struct in_addr *v4, 2542 struct in_addr *v4,
2492 struct in6_addr *v6) 2543 struct in6_addr *v6)
2493{ 2544{
2494 *addr = NULL; 2545 *addr = NULL;
2495 switch (*result_af) 2546 switch (*result_af)
2496 {
2497 case AF_INET:
2498 if (GNUNET_OK != allocate_v4_address (v4))
2499 *result_af = AF_UNSPEC;
2500 else
2501 *addr = v4;
2502 break;
2503 case AF_INET6:
2504 if (GNUNET_OK != allocate_v6_address (v6))
2505 *result_af = AF_UNSPEC;
2506 else
2507 *addr = v6;
2508 break;
2509 case AF_UNSPEC:
2510 if (GNUNET_OK == allocate_v4_address (v4))
2511 {
2512 *addr = v4;
2513 *result_af = AF_INET;
2514 }
2515 else if (GNUNET_OK == allocate_v6_address (v6))
2516 { 2547 {
2517 *addr = v6; 2548 case AF_INET:
2518 *result_af = AF_INET6; 2549 if (GNUNET_OK != allocate_v4_address(v4))
2550 *result_af = AF_UNSPEC;
2551 else
2552 *addr = v4;
2553 break;
2554
2555 case AF_INET6:
2556 if (GNUNET_OK != allocate_v6_address(v6))
2557 *result_af = AF_UNSPEC;
2558 else
2559 *addr = v6;
2560 break;
2561
2562 case AF_UNSPEC:
2563 if (GNUNET_OK == allocate_v4_address(v4))
2564 {
2565 *addr = v4;
2566 *result_af = AF_INET;
2567 }
2568 else if (GNUNET_OK == allocate_v6_address(v6))
2569 {
2570 *addr = v6;
2571 *result_af = AF_INET6;
2572 }
2573 break;
2574
2575 default:
2576 GNUNET_break(0);
2577 return GNUNET_SYSERR;
2519 } 2578 }
2520 break;
2521 default:
2522 GNUNET_break (0);
2523 return GNUNET_SYSERR;
2524 }
2525 return GNUNET_OK; 2579 return GNUNET_OK;
2526} 2580}
2527 2581
@@ -2536,34 +2590,36 @@ allocate_response_ip (int *result_af,
2536 * @return #GNUNET_OK if @a msg is well-formed 2590 * @return #GNUNET_OK if @a msg is well-formed
2537 */ 2591 */
2538static int 2592static int
2539check_client_redirect_to_ip (void *cls, 2593check_client_redirect_to_ip(void *cls,
2540 const struct RedirectToIpRequestMessage *msg) 2594 const struct RedirectToIpRequestMessage *msg)
2541{ 2595{
2542 size_t alen; 2596 size_t alen;
2543 int addr_af; 2597 int addr_af;
2544 2598
2545 alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage); 2599 alen = ntohs(msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2546 addr_af = (int) htonl (msg->addr_af); 2600 addr_af = (int)htonl(msg->addr_af);
2547 switch (addr_af) 2601 switch (addr_af)
2548 {
2549 case AF_INET:
2550 if (alen != sizeof (struct in_addr))
2551 {
2552 GNUNET_break (0);
2553 return GNUNET_SYSERR;
2554 }
2555 break;
2556 case AF_INET6:
2557 if (alen != sizeof (struct in6_addr))
2558 { 2602 {
2559 GNUNET_break (0); 2603 case AF_INET:
2604 if (alen != sizeof(struct in_addr))
2605 {
2606 GNUNET_break(0);
2607 return GNUNET_SYSERR;
2608 }
2609 break;
2610
2611 case AF_INET6:
2612 if (alen != sizeof(struct in6_addr))
2613 {
2614 GNUNET_break(0);
2615 return GNUNET_SYSERR;
2616 }
2617 break;
2618
2619 default:
2620 GNUNET_break(0);
2560 return GNUNET_SYSERR; 2621 return GNUNET_SYSERR;
2561 } 2622 }
2562 break;
2563 default:
2564 GNUNET_break (0);
2565 return GNUNET_SYSERR;
2566 }
2567 return GNUNET_OK; 2623 return GNUNET_OK;
2568} 2624}
2569 2625
@@ -2577,8 +2633,8 @@ check_client_redirect_to_ip (void *cls,
2577 * @param msg redirection request 2633 * @param msg redirection request
2578 */ 2634 */
2579static void 2635static void
2580handle_client_redirect_to_ip (void *cls, 2636handle_client_redirect_to_ip(void *cls,
2581 const struct RedirectToIpRequestMessage *msg) 2637 const struct RedirectToIpRequestMessage *msg)
2582{ 2638{
2583 struct GNUNET_SERVICE_Client *client = cls; 2639 struct GNUNET_SERVICE_Client *client = cls;
2584 size_t alen; 2640 size_t alen;
@@ -2590,59 +2646,59 @@ handle_client_redirect_to_ip (void *cls,
2590 struct DestinationEntry *de; 2646 struct DestinationEntry *de;
2591 struct GNUNET_HashCode key; 2647 struct GNUNET_HashCode key;
2592 2648
2593 alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage); 2649 alen = ntohs(msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2594 addr_af = (int) htonl (msg->addr_af); 2650 addr_af = (int)htonl(msg->addr_af);
2595 /* allocate response IP */ 2651 /* allocate response IP */
2596 result_af = (int) htonl (msg->result_af); 2652 result_af = (int)htonl(msg->result_af);
2597 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6)) 2653 if (GNUNET_OK != allocate_response_ip(&result_af, &addr, &v4, &v6))
2598 { 2654 {
2599 GNUNET_SERVICE_client_drop (client); 2655 GNUNET_SERVICE_client_drop(client);
2600 return; 2656 return;
2601 } 2657 }
2602 /* send reply with our IP address */ 2658 /* send reply with our IP address */
2603 send_client_reply (client, msg->request_id, result_af, addr); 2659 send_client_reply(client, msg->request_id, result_af, addr);
2604 if (result_af == AF_UNSPEC) 2660 if (result_af == AF_UNSPEC)
2605 { 2661 {
2606 /* failure, we're done */ 2662 /* failure, we're done */
2607 GNUNET_SERVICE_client_continue (client); 2663 GNUNET_SERVICE_client_continue(client);
2608 return; 2664 return;
2609 } 2665 }
2610 2666
2611 { 2667 {
2612 char sbuf[INET6_ADDRSTRLEN]; 2668 char sbuf[INET6_ADDRSTRLEN];
2613 char dbuf[INET6_ADDRSTRLEN]; 2669 char dbuf[INET6_ADDRSTRLEN];
2614 2670
2615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2671 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2616 "Allocated address %s for redirection via exit to %s\n", 2672 "Allocated address %s for redirection via exit to %s\n",
2617 inet_ntop (result_af, addr, sbuf, sizeof (sbuf)), 2673 inet_ntop(result_af, addr, sbuf, sizeof(sbuf)),
2618 inet_ntop (addr_af, &msg[1], dbuf, sizeof (dbuf))); 2674 inet_ntop(addr_af, &msg[1], dbuf, sizeof(dbuf)));
2619 } 2675 }
2620 2676
2621 /* setup destination record */ 2677 /* setup destination record */
2622 de = GNUNET_new (struct DestinationEntry); 2678 de = GNUNET_new(struct DestinationEntry);
2623 de->is_service = GNUNET_NO; 2679 de->is_service = GNUNET_NO;
2624 de->details.exit_destination.af = addr_af; 2680 de->details.exit_destination.af = addr_af;
2625 GNUNET_memcpy (&de->details.exit_destination.ip, &msg[1], alen); 2681 GNUNET_memcpy(&de->details.exit_destination.ip, &msg[1], alen);
2626 get_destination_key_from_ip (result_af, addr, &key); 2682 get_destination_key_from_ip(result_af, addr, &key);
2627 de->key = key; 2683 de->key = key;
2628 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( 2684 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
2629 destination_map, 2685 destination_map,
2630 &key, 2686 &key,
2631 de, 2687 de,
2632 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 2688 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2633 de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap, 2689 de->heap_node = GNUNET_CONTAINER_heap_insert(destination_heap,
2634 de, 2690 de,
2635 GNUNET_TIME_absolute_ntoh ( 2691 GNUNET_TIME_absolute_ntoh(
2636 msg->expiration_time) 2692 msg->expiration_time)
2637 .abs_value_us); 2693 .abs_value_us);
2638 GNUNET_STATISTICS_update (stats, 2694 GNUNET_STATISTICS_update(stats,
2639 gettext_noop ("# Active destinations"), 2695 gettext_noop("# Active destinations"),
2640 1, 2696 1,
2641 GNUNET_NO); 2697 GNUNET_NO);
2642 while (GNUNET_CONTAINER_multihashmap_size (destination_map) > 2698 while (GNUNET_CONTAINER_multihashmap_size(destination_map) >
2643 max_destination_mappings) 2699 max_destination_mappings)
2644 expire_destination (de); 2700 expire_destination(de);
2645 GNUNET_SERVICE_client_continue (client); 2701 GNUNET_SERVICE_client_continue(client);
2646} 2702}
2647 2703
2648 2704
@@ -2655,7 +2711,7 @@ handle_client_redirect_to_ip (void *cls,
2655 * @param msg redirection request 2711 * @param msg redirection request
2656 */ 2712 */
2657static void 2713static void
2658handle_client_redirect_to_service ( 2714handle_client_redirect_to_service(
2659 void *cls, 2715 void *cls,
2660 const struct RedirectToServiceRequestMessage *msg) 2716 const struct RedirectToServiceRequestMessage *msg)
2661{ 2717{
@@ -2669,59 +2725,59 @@ handle_client_redirect_to_service (
2669 struct DestinationChannel *dt; 2725 struct DestinationChannel *dt;
2670 2726
2671 /* allocate response IP */ 2727 /* allocate response IP */
2672 result_af = (int) htonl (msg->result_af); 2728 result_af = (int)htonl(msg->result_af);
2673 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6)) 2729 if (GNUNET_OK != allocate_response_ip(&result_af, &addr, &v4, &v6))
2674 { 2730 {
2675 GNUNET_break (0); 2731 GNUNET_break(0);
2676 GNUNET_SERVICE_client_drop (client); 2732 GNUNET_SERVICE_client_drop(client);
2677 return; 2733 return;
2678 } 2734 }
2679 send_client_reply (client, msg->request_id, result_af, addr); 2735 send_client_reply(client, msg->request_id, result_af, addr);
2680 if (result_af == AF_UNSPEC) 2736 if (result_af == AF_UNSPEC)
2681 { 2737 {
2682 /* failure, we're done */ 2738 /* failure, we're done */
2683 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2739 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2684 _ ("Failed to allocate IP address for new destination\n")); 2740 _("Failed to allocate IP address for new destination\n"));
2685 GNUNET_SERVICE_client_continue (client); 2741 GNUNET_SERVICE_client_continue(client);
2686 return; 2742 return;
2687 } 2743 }
2688 2744
2689 { 2745 {
2690 char sbuf[INET6_ADDRSTRLEN]; 2746 char sbuf[INET6_ADDRSTRLEN];
2691 2747
2692 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2748 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2693 "Allocated address %s for redirection to service %s on peer %s\n", 2749 "Allocated address %s for redirection to service %s on peer %s\n",
2694 inet_ntop (result_af, addr, sbuf, sizeof (sbuf)), 2750 inet_ntop(result_af, addr, sbuf, sizeof(sbuf)),
2695 GNUNET_h2s (&msg->service_descriptor), 2751 GNUNET_h2s(&msg->service_descriptor),
2696 GNUNET_i2s (&msg->target)); 2752 GNUNET_i2s(&msg->target));
2697 } 2753 }
2698 2754
2699 /* setup destination record */ 2755 /* setup destination record */
2700 de = GNUNET_new (struct DestinationEntry); 2756 de = GNUNET_new(struct DestinationEntry);
2701 de->is_service = GNUNET_YES; 2757 de->is_service = GNUNET_YES;
2702 de->details.service_destination.target = msg->target; 2758 de->details.service_destination.target = msg->target;
2703 de->details.service_destination.service_descriptor = msg->service_descriptor; 2759 de->details.service_destination.service_descriptor = msg->service_descriptor;
2704 get_destination_key_from_ip (result_af, addr, &key); 2760 get_destination_key_from_ip(result_af, addr, &key);
2705 de->key = key; 2761 de->key = key;
2706 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( 2762 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
2707 destination_map, 2763 destination_map,
2708 &key, 2764 &key,
2709 de, 2765 de,
2710 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 2766 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2711 de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap, 2767 de->heap_node = GNUNET_CONTAINER_heap_insert(destination_heap,
2712 de, 2768 de,
2713 GNUNET_TIME_absolute_ntoh ( 2769 GNUNET_TIME_absolute_ntoh(
2714 msg->expiration_time) 2770 msg->expiration_time)
2715 .abs_value_us); 2771 .abs_value_us);
2716 while (GNUNET_CONTAINER_multihashmap_size (destination_map) > 2772 while (GNUNET_CONTAINER_multihashmap_size(destination_map) >
2717 max_destination_mappings) 2773 max_destination_mappings)
2718 expire_destination (de); 2774 expire_destination(de);
2719 2775
2720 dt = GNUNET_new (struct DestinationChannel); 2776 dt = GNUNET_new(struct DestinationChannel);
2721 dt->destination = de; 2777 dt->destination = de;
2722 GNUNET_CONTAINER_DLL_insert (de->dt_head, de->dt_tail, dt); 2778 GNUNET_CONTAINER_DLL_insert(de->dt_head, de->dt_tail, dt);
2723 /* we're done */ 2779 /* we're done */
2724 GNUNET_SERVICE_client_continue (client); 2780 GNUNET_SERVICE_client_continue(client);
2725} 2781}
2726 2782
2727 2783
@@ -2734,11 +2790,11 @@ handle_client_redirect_to_service (
2734 * @return #GNUNET_OK (continue to iterate) 2790 * @return #GNUNET_OK (continue to iterate)
2735 */ 2791 */
2736static int 2792static int
2737cleanup_destination (void *cls, const struct GNUNET_HashCode *key, void *value) 2793cleanup_destination(void *cls, const struct GNUNET_HashCode *key, void *value)
2738{ 2794{
2739 struct DestinationEntry *de = value; 2795 struct DestinationEntry *de = value;
2740 2796
2741 free_destination_entry (de); 2797 free_destination_entry(de);
2742 return GNUNET_OK; 2798 return GNUNET_OK;
2743} 2799}
2744 2800
@@ -2752,14 +2808,14 @@ cleanup_destination (void *cls, const struct GNUNET_HashCode *key, void *value)
2752 * @return #GNUNET_OK (continue to iterate) 2808 * @return #GNUNET_OK (continue to iterate)
2753 */ 2809 */
2754static int 2810static int
2755cleanup_channel (void *cls, const struct GNUNET_HashCode *key, void *value) 2811cleanup_channel(void *cls, const struct GNUNET_HashCode *key, void *value)
2756{ 2812{
2757 struct ChannelState *ts = value; 2813 struct ChannelState *ts = value;
2758 2814
2759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2815 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2760 "Tearing down channel to `%s' during cleanup\n", 2816 "Tearing down channel to `%s' during cleanup\n",
2761 print_channel_destination (&ts->destination)); 2817 print_channel_destination(&ts->destination));
2762 free_channel_state (ts); 2818 free_channel_state(ts);
2763 return GNUNET_OK; 2819 return GNUNET_OK;
2764} 2820}
2765 2821
@@ -2770,53 +2826,53 @@ cleanup_channel (void *cls, const struct GNUNET_HashCode *key, void *value)
2770 * @param cls unused 2826 * @param cls unused
2771 */ 2827 */
2772static void 2828static void
2773cleanup (void *cls) 2829cleanup(void *cls)
2774{ 2830{
2775 unsigned int i; 2831 unsigned int i;
2776 2832
2777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n"); 2833 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n");
2778 if (NULL != destination_map) 2834 if (NULL != destination_map)
2779 { 2835 {
2780 GNUNET_CONTAINER_multihashmap_iterate (destination_map, 2836 GNUNET_CONTAINER_multihashmap_iterate(destination_map,
2781 &cleanup_destination, 2837 &cleanup_destination,
2782 NULL); 2838 NULL);
2783 GNUNET_CONTAINER_multihashmap_destroy (destination_map); 2839 GNUNET_CONTAINER_multihashmap_destroy(destination_map);
2784 destination_map = NULL; 2840 destination_map = NULL;
2785 } 2841 }
2786 if (NULL != destination_heap) 2842 if (NULL != destination_heap)
2787 { 2843 {
2788 GNUNET_CONTAINER_heap_destroy (destination_heap); 2844 GNUNET_CONTAINER_heap_destroy(destination_heap);
2789 destination_heap = NULL; 2845 destination_heap = NULL;
2790 } 2846 }
2791 if (NULL != channel_map) 2847 if (NULL != channel_map)
2792 { 2848 {
2793 GNUNET_CONTAINER_multihashmap_iterate (channel_map, &cleanup_channel, NULL); 2849 GNUNET_CONTAINER_multihashmap_iterate(channel_map, &cleanup_channel, NULL);
2794 GNUNET_CONTAINER_multihashmap_destroy (channel_map); 2850 GNUNET_CONTAINER_multihashmap_destroy(channel_map);
2795 channel_map = NULL; 2851 channel_map = NULL;
2796 } 2852 }
2797 if (NULL != channel_heap) 2853 if (NULL != channel_heap)
2798 { 2854 {
2799 GNUNET_CONTAINER_heap_destroy (channel_heap); 2855 GNUNET_CONTAINER_heap_destroy(channel_heap);
2800 channel_heap = NULL; 2856 channel_heap = NULL;
2801 } 2857 }
2802 if (NULL != cadet_handle) 2858 if (NULL != cadet_handle)
2803 { 2859 {
2804 GNUNET_CADET_disconnect (cadet_handle); 2860 GNUNET_CADET_disconnect(cadet_handle);
2805 cadet_handle = NULL; 2861 cadet_handle = NULL;
2806 } 2862 }
2807 if (NULL != helper_handle) 2863 if (NULL != helper_handle)
2808 { 2864 {
2809 GNUNET_HELPER_kill (helper_handle, GNUNET_NO); 2865 GNUNET_HELPER_kill(helper_handle, GNUNET_NO);
2810 GNUNET_HELPER_wait (helper_handle); 2866 GNUNET_HELPER_wait(helper_handle);
2811 helper_handle = NULL; 2867 helper_handle = NULL;
2812 } 2868 }
2813 if (NULL != stats) 2869 if (NULL != stats)
2814 { 2870 {
2815 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 2871 GNUNET_STATISTICS_destroy(stats, GNUNET_NO);
2816 stats = NULL; 2872 stats = NULL;
2817 } 2873 }
2818 for (i = 0; i < 5; i++) 2874 for (i = 0; i < 5; i++)
2819 GNUNET_free_non_null (vpn_argv[i]); 2875 GNUNET_free_non_null(vpn_argv[i]);
2820} 2876}
2821 2877
2822 2878
@@ -2829,9 +2885,9 @@ cleanup (void *cls)
2829 * @return @a c 2885 * @return @a c
2830 */ 2886 */
2831static void * 2887static void *
2832client_connect_cb (void *cls, 2888client_connect_cb(void *cls,
2833 struct GNUNET_SERVICE_Client *c, 2889 struct GNUNET_SERVICE_Client *c,
2834 struct GNUNET_MQ_Handle *mq) 2890 struct GNUNET_MQ_Handle *mq)
2835{ 2891{
2836 return c; 2892 return c;
2837} 2893}
@@ -2845,11 +2901,11 @@ client_connect_cb (void *cls,
2845 * @param internal_cls should be equal to @a c 2901 * @param internal_cls should be equal to @a c
2846 */ 2902 */
2847static void 2903static void
2848client_disconnect_cb (void *cls, 2904client_disconnect_cb(void *cls,
2849 struct GNUNET_SERVICE_Client *c, 2905 struct GNUNET_SERVICE_Client *c,
2850 void *internal_cls) 2906 void *internal_cls)
2851{ 2907{
2852 GNUNET_assert (c == internal_cls); 2908 GNUNET_assert(c == internal_cls);
2853} 2909}
2854 2910
2855 2911
@@ -2861,9 +2917,9 @@ client_disconnect_cb (void *cls,
2861 * @param service the initialized service 2917 * @param service the initialized service
2862 */ 2918 */
2863static void 2919static void
2864run (void *cls, 2920run(void *cls,
2865 const struct GNUNET_CONFIGURATION_Handle *cfg_, 2921 const struct GNUNET_CONFIGURATION_Handle *cfg_,
2866 struct GNUNET_SERVICE_Handle *service) 2922 struct GNUNET_SERVICE_Handle *service)
2867{ 2923{
2868 char *ifname; 2924 char *ifname;
2869 char *ipv6addr; 2925 char *ipv6addr;
@@ -2874,187 +2930,187 @@ run (void *cls,
2874 struct in6_addr v6; 2930 struct in6_addr v6;
2875 char *binary; 2931 char *binary;
2876 2932
2877 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); 2933 binary = GNUNET_OS_get_libexec_binary_path("gnunet-helper-vpn");
2878 2934
2879 if (GNUNET_YES != 2935 if (GNUNET_YES !=
2880 GNUNET_OS_check_helper_binary ( 2936 GNUNET_OS_check_helper_binary(
2881 binary, 2937 binary,
2882 GNUNET_YES, 2938 GNUNET_YES,
2883 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please! 2939 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please!
2884 { 2940 {
2885 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2941 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2886 "`%s' is not SUID, refusing to run.\n", 2942 "`%s' is not SUID, refusing to run.\n",
2887 "gnunet-helper-vpn"); 2943 "gnunet-helper-vpn");
2888 GNUNET_free (binary); 2944 GNUNET_free(binary);
2889 global_ret = 1; 2945 global_ret = 1;
2890 /* we won't "really" exit here, as the 'service' is still running; 2946 /* we won't "really" exit here, as the 'service' is still running;
2891 however, as no handlers are registered, the service won't do 2947 however, as no handlers are registered, the service won't do
2892 anything either */ 2948 anything either */
2893 return; 2949 return;
2894 } 2950 }
2895 GNUNET_free (binary); 2951 GNUNET_free(binary);
2896 cfg = cfg_; 2952 cfg = cfg_;
2897 stats = GNUNET_STATISTICS_create ("vpn", cfg); 2953 stats = GNUNET_STATISTICS_create("vpn", cfg);
2898 if (GNUNET_OK != 2954 if (GNUNET_OK !=
2899 GNUNET_CONFIGURATION_get_value_number (cfg, 2955 GNUNET_CONFIGURATION_get_value_number(cfg,
2900 "VPN", 2956 "VPN",
2901 "MAX_MAPPING", 2957 "MAX_MAPPING",
2902 &max_destination_mappings)) 2958 &max_destination_mappings))
2903 max_destination_mappings = 200; 2959 max_destination_mappings = 200;
2904 if (GNUNET_OK != 2960 if (GNUNET_OK !=
2905 GNUNET_CONFIGURATION_get_value_number (cfg, 2961 GNUNET_CONFIGURATION_get_value_number(cfg,
2906 "VPN", 2962 "VPN",
2907 "MAX_TUNNELS", 2963 "MAX_TUNNELS",
2908 &max_channel_mappings)) 2964 &max_channel_mappings))
2909 max_channel_mappings = 200; 2965 max_channel_mappings = 200;
2910 2966
2911 destination_map = 2967 destination_map =
2912 GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2, 2968 GNUNET_CONTAINER_multihashmap_create(max_destination_mappings * 2,
2913 GNUNET_NO); 2969 GNUNET_NO);
2914 destination_heap = 2970 destination_heap =
2915 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 2971 GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
2916 channel_map = 2972 channel_map =
2917 GNUNET_CONTAINER_multihashmap_create (max_channel_mappings * 2, GNUNET_NO); 2973 GNUNET_CONTAINER_multihashmap_create(max_channel_mappings * 2, GNUNET_NO);
2918 channel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 2974 channel_heap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
2919 2975
2920 2976
2921 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet"); 2977 vpn_argv[0] = GNUNET_strdup("vpn-gnunet");
2922 if (GNUNET_SYSERR == 2978 if (GNUNET_SYSERR ==
2923 GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname)) 2979 GNUNET_CONFIGURATION_get_value_string(cfg, "VPN", "IFNAME", &ifname))
2924 {
2925 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
2926 GNUNET_SCHEDULER_shutdown ();
2927 return;
2928 }
2929 vpn_argv[1] = ifname;
2930 ipv6addr = NULL;
2931 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
2932 {
2933 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2934 "VPN",
2935 "IPV6ADDR",
2936 &ipv6addr) ||
2937 (1 != inet_pton (AF_INET6, ipv6addr, &v6))))
2938 {
2939 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2940 "VPN",
2941 "IPV6ADDR",
2942 _ ("Must specify valid IPv6 address"));
2943 GNUNET_SCHEDULER_shutdown ();
2944 GNUNET_free_non_null (ipv6addr);
2945 return;
2946 }
2947 vpn_argv[2] = ipv6addr;
2948 ipv6prefix_s = NULL;
2949 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2950 "VPN",
2951 "IPV6PREFIX",
2952 &ipv6prefix_s))
2953 { 2980 {
2954 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX"); 2981 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
2955 GNUNET_SCHEDULER_shutdown (); 2982 GNUNET_SCHEDULER_shutdown();
2956 GNUNET_free_non_null (ipv6prefix_s);
2957 return; 2983 return;
2958 } 2984 }
2959 vpn_argv[3] = ipv6prefix_s; 2985 vpn_argv[1] = ifname;
2960 if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, 2986 ipv6addr = NULL;
2961 "VPN", 2987 if (GNUNET_OK == GNUNET_NETWORK_test_pf(PF_INET6))
2962 "IPV6PREFIX",
2963 &ipv6prefix)) ||
2964 (ipv6prefix >= 127))
2965 { 2988 {
2966 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 2989 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
2967 "VPN", 2990 "VPN",
2968 "IPV4MASK", 2991 "IPV6ADDR",
2969 _ ("Must specify valid IPv6 mask")); 2992 &ipv6addr) ||
2970 GNUNET_SCHEDULER_shutdown (); 2993 (1 != inet_pton(AF_INET6, ipv6addr, &v6))))
2971 return; 2994 {
2995 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
2996 "VPN",
2997 "IPV6ADDR",
2998 _("Must specify valid IPv6 address"));
2999 GNUNET_SCHEDULER_shutdown();
3000 GNUNET_free_non_null(ipv6addr);
3001 return;
3002 }
3003 vpn_argv[2] = ipv6addr;
3004 ipv6prefix_s = NULL;
3005 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
3006 "VPN",
3007 "IPV6PREFIX",
3008 &ipv6prefix_s))
3009 {
3010 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
3011 GNUNET_SCHEDULER_shutdown();
3012 GNUNET_free_non_null(ipv6prefix_s);
3013 return;
3014 }
3015 vpn_argv[3] = ipv6prefix_s;
3016 if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
3017 "VPN",
3018 "IPV6PREFIX",
3019 &ipv6prefix)) ||
3020 (ipv6prefix >= 127))
3021 {
3022 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
3023 "VPN",
3024 "IPV4MASK",
3025 _("Must specify valid IPv6 mask"));
3026 GNUNET_SCHEDULER_shutdown();
3027 return;
3028 }
2972 } 3029 }
2973 }
2974 else 3030 else
2975 {
2976 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2977 _ (
2978 "IPv6 support disabled as this system does not support IPv6\n"));
2979 vpn_argv[2] = GNUNET_strdup ("-");
2980 vpn_argv[3] = GNUNET_strdup ("-");
2981 }
2982 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
2983 {
2984 ipv4addr = NULL;
2985 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2986 "vpn",
2987 "IPV4ADDR",
2988 &ipv4addr) ||
2989 (1 != inet_pton (AF_INET, ipv4addr, &v4))))
2990 { 3031 {
2991 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 3032 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2992 "VPN", 3033 _(
2993 "IPV4ADDR", 3034 "IPv6 support disabled as this system does not support IPv6\n"));
2994 _ ("Must specify valid IPv4 address")); 3035 vpn_argv[2] = GNUNET_strdup("-");
2995 GNUNET_SCHEDULER_shutdown (); 3036 vpn_argv[3] = GNUNET_strdup("-");
2996 GNUNET_free_non_null (ipv4addr);
2997 return;
2998 } 3037 }
2999 vpn_argv[4] = ipv4addr; 3038 if (GNUNET_OK == GNUNET_NETWORK_test_pf(PF_INET))
3000 ipv4mask = NULL;
3001 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
3002 "vpn",
3003 "IPV4MASK",
3004 &ipv4mask) ||
3005 (1 != inet_pton (AF_INET, ipv4mask, &v4))))
3006 { 3039 {
3007 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 3040 ipv4addr = NULL;
3008 "VPN", 3041 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
3009 "IPV4MASK", 3042 "vpn",
3010 _ ("Must specify valid IPv4 mask")); 3043 "IPV4ADDR",
3011 GNUNET_SCHEDULER_shutdown (); 3044 &ipv4addr) ||
3012 GNUNET_free_non_null (ipv4mask); 3045 (1 != inet_pton(AF_INET, ipv4addr, &v4))))
3013 return; 3046 {
3047 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
3048 "VPN",
3049 "IPV4ADDR",
3050 _("Must specify valid IPv4 address"));
3051 GNUNET_SCHEDULER_shutdown();
3052 GNUNET_free_non_null(ipv4addr);
3053 return;
3054 }
3055 vpn_argv[4] = ipv4addr;
3056 ipv4mask = NULL;
3057 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
3058 "vpn",
3059 "IPV4MASK",
3060 &ipv4mask) ||
3061 (1 != inet_pton(AF_INET, ipv4mask, &v4))))
3062 {
3063 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
3064 "VPN",
3065 "IPV4MASK",
3066 _("Must specify valid IPv4 mask"));
3067 GNUNET_SCHEDULER_shutdown();
3068 GNUNET_free_non_null(ipv4mask);
3069 return;
3070 }
3071 vpn_argv[5] = ipv4mask;
3014 } 3072 }
3015 vpn_argv[5] = ipv4mask;
3016 }
3017 else 3073 else
3018 { 3074 {
3019 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3075 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
3020 _ ( 3076 _(
3021 "IPv4 support disabled as this system does not support IPv4\n")); 3077 "IPv4 support disabled as this system does not support IPv4\n"));
3022 vpn_argv[4] = GNUNET_strdup ("-"); 3078 vpn_argv[4] = GNUNET_strdup("-");
3023 vpn_argv[5] = GNUNET_strdup ("-"); 3079 vpn_argv[5] = GNUNET_strdup("-");
3024 } 3080 }
3025 vpn_argv[6] = NULL; 3081 vpn_argv[6] = NULL;
3026 3082
3027 cadet_handle = GNUNET_CADET_connect (cfg_); 3083 cadet_handle = GNUNET_CADET_connect(cfg_);
3028 // FIXME never opens ports??? 3084 // FIXME never opens ports???
3029 helper_handle = GNUNET_HELPER_start (GNUNET_NO, 3085 helper_handle = GNUNET_HELPER_start(GNUNET_NO,
3030 "gnunet-helper-vpn", 3086 "gnunet-helper-vpn",
3031 vpn_argv, 3087 vpn_argv,
3032 &message_token, 3088 &message_token,
3033 NULL, 3089 NULL,
3034 NULL); 3090 NULL);
3035 GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); 3091 GNUNET_SCHEDULER_add_shutdown(&cleanup, NULL);
3036} 3092}
3037 3093
3038 3094
3039/** 3095/**
3040 * Define "main" method using service macro. 3096 * Define "main" method using service macro.
3041 */ 3097 */
3042GNUNET_SERVICE_MAIN ( 3098GNUNET_SERVICE_MAIN(
3043 "vpn", 3099 "vpn",
3044 GNUNET_SERVICE_OPTION_NONE, 3100 GNUNET_SERVICE_OPTION_NONE,
3045 &run, 3101 &run,
3046 &client_connect_cb, 3102 &client_connect_cb,
3047 &client_disconnect_cb, 3103 &client_disconnect_cb,
3048 NULL, 3104 NULL,
3049 GNUNET_MQ_hd_var_size (client_redirect_to_ip, 3105 GNUNET_MQ_hd_var_size(client_redirect_to_ip,
3050 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 3106 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP,
3051 struct RedirectToIpRequestMessage, 3107 struct RedirectToIpRequestMessage,
3052 NULL), 3108 NULL),
3053 GNUNET_MQ_hd_fixed_size (client_redirect_to_service, 3109 GNUNET_MQ_hd_fixed_size(client_redirect_to_service,
3054 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, 3110 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE,
3055 struct RedirectToServiceRequestMessage, 3111 struct RedirectToServiceRequestMessage,
3056 NULL), 3112 NULL),
3057 GNUNET_MQ_handler_end ()); 3113 GNUNET_MQ_handler_end());
3058 3114
3059 3115
3060/* end of gnunet-service-vpn.c */ 3116/* end of gnunet-service-vpn.c */
diff --git a/src/vpn/gnunet-vpn.c b/src/vpn/gnunet-vpn.c
index 1651767f4..e5b79be6e 100644
--- a/src/vpn/gnunet-vpn.c
+++ b/src/vpn/gnunet-vpn.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file src/vpn/gnunet-vpn.c 22 * @file src/vpn/gnunet-vpn.c
@@ -88,28 +88,28 @@ static int ret;
88/** 88/**
89 * Option '-d': duration of the mapping 89 * Option '-d': duration of the mapping
90 */ 90 */
91static struct GNUNET_TIME_Relative duration = {5 * 60 * 1000}; 91static struct GNUNET_TIME_Relative duration = { 5 * 60 * 1000 };
92 92
93 93
94/** 94/**
95 * Shutdown. 95 * Shutdown.
96 */ 96 */
97static void 97static void
98do_disconnect (void *cls) 98do_disconnect(void *cls)
99{ 99{
100 if (NULL != request) 100 if (NULL != request)
101 { 101 {
102 GNUNET_VPN_cancel_request (request); 102 GNUNET_VPN_cancel_request(request);
103 request = NULL; 103 request = NULL;
104 } 104 }
105 if (NULL != handle) 105 if (NULL != handle)
106 { 106 {
107 GNUNET_VPN_disconnect (handle); 107 GNUNET_VPN_disconnect(handle);
108 handle = NULL; 108 handle = NULL;
109 } 109 }
110 GNUNET_free_non_null (peer_id); 110 GNUNET_free_non_null(peer_id);
111 GNUNET_free_non_null (service_name); 111 GNUNET_free_non_null(service_name);
112 GNUNET_free_non_null (target_ip); 112 GNUNET_free_non_null(target_ip);
113} 113}
114 114
115 115
@@ -127,25 +127,27 @@ do_disconnect (void *cls)
127 * specified target peer; NULL on error 127 * specified target peer; NULL on error
128 */ 128 */
129static void 129static void
130allocation_cb (void *cls, int af, const void *address) 130allocation_cb(void *cls, int af, const void *address)
131{ 131{
132 char buf[INET6_ADDRSTRLEN]; 132 char buf[INET6_ADDRSTRLEN];
133 133
134 request = NULL; 134 request = NULL;
135 switch (af) 135 switch (af)
136 { 136 {
137 case AF_INET6: 137 case AF_INET6:
138 case AF_INET: 138 case AF_INET:
139 fprintf (stdout, "%s\n", inet_ntop (af, address, buf, sizeof (buf))); 139 fprintf(stdout, "%s\n", inet_ntop(af, address, buf, sizeof(buf)));
140 break; 140 break;
141 case AF_UNSPEC: 141
142 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Error creating tunnel\n")); 142 case AF_UNSPEC:
143 ret = 1; 143 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Error creating tunnel\n"));
144 break; 144 ret = 1;
145 default: 145 break;
146 break; 146
147 } 147 default:
148 GNUNET_SCHEDULER_shutdown (); 148 break;
149 }
150 GNUNET_SCHEDULER_shutdown();
149} 151}
150 152
151 153
@@ -158,10 +160,10 @@ allocation_cb (void *cls, int af, const void *address)
158 * @param cfg configuration 160 * @param cfg configuration
159 */ 161 */
160static void 162static void
161run (void *cls, 163run(void *cls,
162 char *const *args, 164 char *const *args,
163 const char *cfgfile, 165 const char *cfgfile,
164 const struct GNUNET_CONFIGURATION_Handle *cfg) 166 const struct GNUNET_CONFIGURATION_Handle *cfg)
165{ 167{
166 int dst_af; 168 int dst_af;
167 int req_af; 169 int req_af;
@@ -173,188 +175,189 @@ run (void *cls,
173 uint8_t protocol; 175 uint8_t protocol;
174 struct GNUNET_TIME_Absolute etime; 176 struct GNUNET_TIME_Absolute etime;
175 177
176 etime = GNUNET_TIME_relative_to_absolute (duration); 178 etime = GNUNET_TIME_relative_to_absolute(duration);
177 GNUNET_SCHEDULER_add_shutdown (&do_disconnect, NULL); 179 GNUNET_SCHEDULER_add_shutdown(&do_disconnect, NULL);
178 handle = GNUNET_VPN_connect (cfg); 180 handle = GNUNET_VPN_connect(cfg);
179 if (NULL == handle) 181 if (NULL == handle)
180 goto error; 182 goto error;
181 req_af = AF_UNSPEC; 183 req_af = AF_UNSPEC;
182 if (ipv4) 184 if (ipv4)
183 {
184 if (ipv6)
185 { 185 {
186 fprintf (stderr, 186 if (ipv6)
187 _ ("Option `%s' makes no sense with option `%s'.\n"), 187 {
188 "-4", 188 fprintf(stderr,
189 "-6"); 189 _("Option `%s' makes no sense with option `%s'.\n"),
190 goto error; 190 "-4",
191 "-6");
192 goto error;
193 }
194 req_af = AF_INET;
191 } 195 }
192 req_af = AF_INET;
193 }
194 if (ipv6) 196 if (ipv6)
195 req_af = AF_INET6; 197 req_af = AF_INET6;
196 198
197 if (NULL == target_ip) 199 if (NULL == target_ip)
198 {
199 if (NULL == service_name)
200 {
201 fprintf (stderr, _ ("Option `%s' or `%s' is required.\n"), "-i", "-s");
202 goto error;
203 }
204 if (NULL == peer_id)
205 {
206 fprintf (stderr,
207 _ ("Option `%s' is required when using option `%s'.\n"),
208 "-p",
209 "-s");
210 goto error;
211 }
212 if (! (tcp | udp))
213 {
214 fprintf (stderr,
215 _ ("Option `%s' or `%s' is required when using option `%s'.\n"),
216 "-t",
217 "-u",
218 "-s");
219 goto error;
220 }
221 if (tcp & udp)
222 { 200 {
223 fprintf (stderr, 201 if (NULL == service_name)
224 _ ("Option `%s' makes no sense with option `%s'.\n"), 202 {
225 "-t", 203 fprintf(stderr, _("Option `%s' or `%s' is required.\n"), "-i", "-s");
226 "-u"); 204 goto error;
227 goto error; 205 }
206 if (NULL == peer_id)
207 {
208 fprintf(stderr,
209 _("Option `%s' is required when using option `%s'.\n"),
210 "-p",
211 "-s");
212 goto error;
213 }
214 if (!(tcp | udp))
215 {
216 fprintf(stderr,
217 _("Option `%s' or `%s' is required when using option `%s'.\n"),
218 "-t",
219 "-u",
220 "-s");
221 goto error;
222 }
223 if (tcp & udp)
224 {
225 fprintf(stderr,
226 _("Option `%s' makes no sense with option `%s'.\n"),
227 "-t",
228 "-u");
229 goto error;
230 }
231 if (tcp)
232 protocol = IPPROTO_TCP;
233 if (udp)
234 protocol = IPPROTO_UDP;
235 if (GNUNET_OK !=
236 GNUNET_CRYPTO_eddsa_public_key_from_string(peer_id,
237 strlen(peer_id),
238 &peer.public_key))
239 {
240 fprintf(stderr, _("`%s' is not a valid peer identifier.\n"), peer_id);
241 goto error;
242 }
243 GNUNET_TUN_service_name_to_hash(service_name, &sd);
244 request = GNUNET_VPN_redirect_to_peer(handle,
245 req_af,
246 protocol,
247 &peer,
248 &sd,
249 etime,
250 &allocation_cb,
251 NULL);
228 } 252 }
229 if (tcp)
230 protocol = IPPROTO_TCP;
231 if (udp)
232 protocol = IPPROTO_UDP;
233 if (GNUNET_OK !=
234 GNUNET_CRYPTO_eddsa_public_key_from_string (peer_id,
235 strlen (peer_id),
236 &peer.public_key))
237 {
238 fprintf (stderr, _ ("`%s' is not a valid peer identifier.\n"), peer_id);
239 goto error;
240 }
241 GNUNET_TUN_service_name_to_hash (service_name, &sd);
242 request = GNUNET_VPN_redirect_to_peer (handle,
243 req_af,
244 protocol,
245 &peer,
246 &sd,
247 etime,
248 &allocation_cb,
249 NULL);
250 }
251 else 253 else
252 {
253 if (1 != inet_pton (AF_INET6, target_ip, &v6))
254 { 254 {
255 if (1 != inet_pton (AF_INET, target_ip, &v4)) 255 if (1 != inet_pton(AF_INET6, target_ip, &v6))
256 { 256 {
257 fprintf (stderr, _ ("`%s' is not a valid IP address.\n"), target_ip); 257 if (1 != inet_pton(AF_INET, target_ip, &v4))
258 goto error; 258 {
259 } 259 fprintf(stderr, _("`%s' is not a valid IP address.\n"), target_ip);
260 goto error;
261 }
262 else
263 {
264 dst_af = AF_INET;
265 addr = &v4;
266 }
267 }
260 else 268 else
261 { 269 {
262 dst_af = AF_INET; 270 dst_af = AF_INET6;
263 addr = &v4; 271 addr = &v6;
264 } 272 }
265 } 273 request = GNUNET_VPN_redirect_to_ip(handle,
266 else 274 req_af,
267 { 275 dst_af,
268 dst_af = AF_INET6; 276 addr,
269 addr = &v6; 277 etime,
278 &allocation_cb,
279 NULL);
270 } 280 }
271 request = GNUNET_VPN_redirect_to_ip (handle,
272 req_af,
273 dst_af,
274 addr,
275 etime,
276 &allocation_cb,
277 NULL);
278 }
279 return; 281 return;
280 282
281error: 283error:
282 GNUNET_SCHEDULER_shutdown (); 284 GNUNET_SCHEDULER_shutdown();
283 ret = 1; 285 ret = 1;
284} 286}
285 287
286 288
287int 289int
288main (int argc, char *const *argv) 290main(int argc, char *const *argv)
289{ 291{
290 struct GNUNET_GETOPT_CommandLineOption options[] = 292 struct GNUNET_GETOPT_CommandLineOption options[] =
291 {GNUNET_GETOPT_option_flag ('4', 293 { GNUNET_GETOPT_option_flag('4',
292 "ipv4", 294 "ipv4",
293 gettext_noop ( 295 gettext_noop(
294 "request that result should be an IPv4 address"), 296 "request that result should be an IPv4 address"),
295 &ipv4), 297 &ipv4),
296 298
297 GNUNET_GETOPT_option_flag ('6', 299 GNUNET_GETOPT_option_flag('6',
298 "ipv6", 300 "ipv6",
299 gettext_noop ( 301 gettext_noop(
300 "request that result should be an IPv6 address"), 302 "request that result should be an IPv6 address"),
301 &ipv6), 303 &ipv6),
302 304
303 GNUNET_GETOPT_option_relative_time ( 305 GNUNET_GETOPT_option_relative_time(
304 'd', 306 'd',
305 "duration", 307 "duration",
306 "TIME", 308 "TIME",
307 gettext_noop ("how long should the mapping be valid for new tunnels?"), 309 gettext_noop("how long should the mapping be valid for new tunnels?"),
308 &duration), 310 &duration),
309 311
310 GNUNET_GETOPT_option_string ('i', 312 GNUNET_GETOPT_option_string('i',
311 "ip", 313 "ip",
312 "IP", 314 "IP",
313 gettext_noop ( 315 gettext_noop(
314 "destination IP for the tunnel"), 316 "destination IP for the tunnel"),
315 &target_ip), 317 &target_ip),
316 318
317 GNUNET_GETOPT_option_string ( 319 GNUNET_GETOPT_option_string(
318 'p', 320 'p',
319 "peer", 321 "peer",
320 "PEERID", 322 "PEERID",
321 gettext_noop ("peer offering the service we would like to access"), 323 gettext_noop("peer offering the service we would like to access"),
322 &peer_id), 324 &peer_id),
323 325
324 GNUNET_GETOPT_option_string ('s', 326 GNUNET_GETOPT_option_string('s',
325 "service", 327 "service",
326 "NAME", 328 "NAME",
327 gettext_noop ( 329 gettext_noop(
328 "name of the service we would like to access"), 330 "name of the service we would like to access"),
329 &service_name), 331 &service_name),
330 332
331 GNUNET_GETOPT_option_flag ('t', 333 GNUNET_GETOPT_option_flag('t',
332 "tcp", 334 "tcp",
333 gettext_noop ("service is offered via TCP"), 335 gettext_noop("service is offered via TCP"),
334 &tcp), 336 &tcp),
335 337
336 GNUNET_GETOPT_option_flag ('u', 338 GNUNET_GETOPT_option_flag('u',
337 "udp", 339 "udp",
338 gettext_noop ("service is offered via UDP"), 340 gettext_noop("service is offered via UDP"),
339 &udp), 341 &udp),
340 342
341 GNUNET_GETOPT_option_verbose (&verbosity), 343 GNUNET_GETOPT_option_verbose(&verbosity),
342 344
343 GNUNET_GETOPT_OPTION_END}; 345 GNUNET_GETOPT_OPTION_END };
344 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 346
347 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
345 return 2; 348 return 2;
346 349
347 ret = 350 ret =
348 (GNUNET_OK == GNUNET_PROGRAM_run (argc, 351 (GNUNET_OK == GNUNET_PROGRAM_run(argc,
349 argv, 352 argv,
350 "gnunet-vpn", 353 "gnunet-vpn",
351 gettext_noop ("Setup tunnels via VPN."), 354 gettext_noop("Setup tunnels via VPN."),
352 options, 355 options,
353 &run, 356 &run,
354 NULL)) 357 NULL))
355 ? ret 358 ? ret
356 : 1; 359 : 1;
357 GNUNET_free ((void *) argv); 360 GNUNET_free((void *)argv);
358 return ret; 361 return ret;
359} 362}
360 363
diff --git a/src/vpn/vpn.h b/src/vpn/vpn.h
index 4c106361e..38c5e88d3 100644
--- a/src/vpn/vpn.h
+++ b/src/vpn/vpn.h
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file vpn/vpn.h 22 * @file vpn/vpn.h
@@ -35,8 +35,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
35 * the setup of a redirection from some IP via an exit node to 35 * the setup of a redirection from some IP via an exit node to
36 * some global Internet address. 36 * some global Internet address.
37 */ 37 */
38struct RedirectToIpRequestMessage 38struct RedirectToIpRequestMessage {
39{
40 /** 39 /**
41 * Type is #GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP 40 * Type is #GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP
42 */ 41 */
@@ -69,7 +68,6 @@ struct RedirectToIpRequestMessage
69 uint64_t request_id GNUNET_PACKED; 68 uint64_t request_id GNUNET_PACKED;
70 69
71 /* followed by destination address ('struct in_addr' or 'struct in6_addr') */ 70 /* followed by destination address ('struct in_addr' or 'struct in6_addr') */
72
73}; 71};
74 72
75 73
@@ -78,8 +76,7 @@ struct RedirectToIpRequestMessage
78 * the setup of a redirection from some IP to a service running 76 * the setup of a redirection from some IP to a service running
79 * at a particular peer. 77 * at a particular peer.
80 */ 78 */
81struct RedirectToServiceRequestMessage 79struct RedirectToServiceRequestMessage {
82{
83 /** 80 /**
84 * Type is #GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE 81 * Type is #GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE
85 */ 82 */
@@ -120,7 +117,6 @@ struct RedirectToServiceRequestMessage
120 * Picked by the client. 117 * Picked by the client.
121 */ 118 */
122 uint64_t request_id GNUNET_PACKED; 119 uint64_t request_id GNUNET_PACKED;
123
124}; 120};
125 121
126 122
@@ -128,9 +124,7 @@ struct RedirectToServiceRequestMessage
128 * Response from the VPN service to a VPN client informing about 124 * Response from the VPN service to a VPN client informing about
129 * the IP that was assigned for the requested redirection. 125 * the IP that was assigned for the requested redirection.
130 */ 126 */
131struct RedirectToIpResponseMessage 127struct RedirectToIpResponseMessage {
132{
133
134 /** 128 /**
135 * Type is #GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP 129 * Type is #GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP
136 */ 130 */
@@ -148,7 +142,6 @@ struct RedirectToIpResponseMessage
148 uint64_t request_id GNUNET_PACKED; 142 uint64_t request_id GNUNET_PACKED;
149 143
150 /* followed by destination address ('struct in_addr' or 'struct in6_addr') */ 144 /* followed by destination address ('struct in_addr' or 'struct in6_addr') */
151
152}; 145};
153 146
154GNUNET_NETWORK_STRUCT_END 147GNUNET_NETWORK_STRUCT_END
diff --git a/src/vpn/vpn_api.c b/src/vpn/vpn_api.c
index b53c32e64..dcb1d99c9 100644
--- a/src/vpn/vpn_api.c
+++ b/src/vpn/vpn_api.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file vpn/vpn_api.c 22 * @file vpn/vpn_api.c
@@ -31,8 +31,7 @@
31/** 31/**
32 * Opaque VPN handle 32 * Opaque VPN handle
33 */ 33 */
34struct GNUNET_VPN_Handle 34struct GNUNET_VPN_Handle {
35{
36 /** 35 /**
37 * Configuration we use. 36 * Configuration we use.
38 */ 37 */
@@ -67,15 +66,13 @@ struct GNUNET_VPN_Handle
67 * ID of the last request that was submitted to the service. 66 * ID of the last request that was submitted to the service.
68 */ 67 */
69 uint64_t request_id_gen; 68 uint64_t request_id_gen;
70
71}; 69};
72 70
73 71
74/** 72/**
75 * Opaque redirection request handle. 73 * Opaque redirection request handle.
76 */ 74 */
77struct GNUNET_VPN_RedirectionRequest 75struct GNUNET_VPN_RedirectionRequest {
78{
79 /** 76 /**
80 * Element in DLL. 77 * Element in DLL.
81 */ 78 */
@@ -141,7 +138,6 @@ struct GNUNET_VPN_RedirectionRequest
141 * For service redirection, IPPROT_UDP or IPPROTO_TCP. 138 * For service redirection, IPPROT_UDP or IPPROTO_TCP.
142 */ 139 */
143 uint8_t protocol; 140 uint8_t protocol;
144
145}; 141};
146 142
147 143
@@ -151,7 +147,7 @@ struct GNUNET_VPN_RedirectionRequest
151 * @param vh handle to reconnect. 147 * @param vh handle to reconnect.
152 */ 148 */
153static void 149static void
154reconnect (struct GNUNET_VPN_Handle *vh); 150reconnect(struct GNUNET_VPN_Handle *vh);
155 151
156 152
157/** 153/**
@@ -163,34 +159,37 @@ reconnect (struct GNUNET_VPN_Handle *vh);
163 * @return #GNUNET_OK if @a rm is well-formed 159 * @return #GNUNET_OK if @a rm is well-formed
164 */ 160 */
165static int 161static int
166check_use_ip (void *cls, 162check_use_ip(void *cls,
167 const struct RedirectToIpResponseMessage *rm) 163 const struct RedirectToIpResponseMessage *rm)
168{ 164{
169 size_t alen; 165 size_t alen;
170 int af; 166 int af;
171 167
172 af = (int) ntohl (rm->result_af); 168 af = (int)ntohl(rm->result_af);
173 switch (af) 169 switch (af)
174 { 170 {
175 case AF_UNSPEC: 171 case AF_UNSPEC:
176 alen = 0; 172 alen = 0;
177 break; 173 break;
178 case AF_INET: 174
179 alen = sizeof (struct in_addr); 175 case AF_INET:
180 break; 176 alen = sizeof(struct in_addr);
181 case AF_INET6: 177 break;
182 alen = sizeof (struct in6_addr); 178
183 break; 179 case AF_INET6:
184 default: 180 alen = sizeof(struct in6_addr);
185 GNUNET_break (0); 181 break;
186 return GNUNET_SYSERR; 182
187 } 183 default:
188 if ( (ntohs (rm->header.size) != alen + sizeof (*rm)) || 184 GNUNET_break(0);
189 (0 == rm->request_id) ) 185 return GNUNET_SYSERR;
190 { 186 }
191 GNUNET_break (0); 187 if ((ntohs(rm->header.size) != alen + sizeof(*rm)) ||
192 return GNUNET_SYSERR; 188 (0 == rm->request_id))
193 } 189 {
190 GNUNET_break(0);
191 return GNUNET_SYSERR;
192 }
194 return GNUNET_OK; 193 return GNUNET_OK;
195} 194}
196 195
@@ -203,28 +202,28 @@ check_use_ip (void *cls,
203 * @param rm message received 202 * @param rm message received
204 */ 203 */
205static void 204static void
206handle_use_ip (void *cls, 205handle_use_ip(void *cls,
207 const struct RedirectToIpResponseMessage *rm) 206 const struct RedirectToIpResponseMessage *rm)
208{ 207{
209 struct GNUNET_VPN_Handle *vh = cls; 208 struct GNUNET_VPN_Handle *vh = cls;
210 struct GNUNET_VPN_RedirectionRequest *rr; 209 struct GNUNET_VPN_RedirectionRequest *rr;
211 int af; 210 int af;
212 211
213 af = (int) ntohl (rm->result_af); 212 af = (int)ntohl(rm->result_af);
214 for (rr = vh->rr_head; NULL != rr; rr = rr->next) 213 for (rr = vh->rr_head; NULL != rr; rr = rr->next)
215 {
216 if (rr->request_id == rm->request_id)
217 { 214 {
218 GNUNET_CONTAINER_DLL_remove (vh->rr_head, 215 if (rr->request_id == rm->request_id)
219 vh->rr_tail, 216 {
220 rr); 217 GNUNET_CONTAINER_DLL_remove(vh->rr_head,
221 rr->cb (rr->cb_cls, 218 vh->rr_tail,
222 af, 219 rr);
223 (af == AF_UNSPEC) ? NULL : &rm[1]); 220 rr->cb(rr->cb_cls,
224 GNUNET_free (rr); 221 af,
225 break; 222 (af == AF_UNSPEC) ? NULL : &rm[1]);
223 GNUNET_free(rr);
224 break;
225 }
226 } 226 }
227 }
228} 227}
229 228
230 229
@@ -234,7 +233,7 @@ handle_use_ip (void *cls,
234 * @param rr request to queue and transmit. 233 * @param rr request to queue and transmit.
235 */ 234 */
236static void 235static void
237send_request (struct GNUNET_VPN_RedirectionRequest *rr) 236send_request(struct GNUNET_VPN_RedirectionRequest *rr)
238{ 237{
239 struct GNUNET_VPN_Handle *vh = rr->vh; 238 struct GNUNET_VPN_Handle *vh = rr->vh;
240 struct RedirectToIpRequestMessage *rip; 239 struct RedirectToIpRequestMessage *rip;
@@ -245,45 +244,47 @@ send_request (struct GNUNET_VPN_RedirectionRequest *rr)
245 if (NULL == vh->mq) 244 if (NULL == vh->mq)
246 return; 245 return;
247 if (NULL == rr->addr) 246 if (NULL == rr->addr)
248 { 247 {
249 env = GNUNET_MQ_msg (rs, 248 env = GNUNET_MQ_msg(rs,
250 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE); 249 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE);
251 rs->reserved = htonl (0); 250 rs->reserved = htonl(0);
252 rs->expiration_time = GNUNET_TIME_absolute_hton (rr->expiration_time); 251 rs->expiration_time = GNUNET_TIME_absolute_hton(rr->expiration_time);
253 rs->protocol = htonl (rr->protocol); 252 rs->protocol = htonl(rr->protocol);
254 rs->result_af = htonl (rr->result_af); 253 rs->result_af = htonl(rr->result_af);
255 rs->target = rr->peer; 254 rs->target = rr->peer;
256 rs->service_descriptor = rr->serv; 255 rs->service_descriptor = rr->serv;
257 rs->request_id = rr->request_id = ++vh->request_id_gen; 256 rs->request_id = rr->request_id = ++vh->request_id_gen;
258 } 257 }
259 else 258 else
260 {
261 switch (rr->addr_af)
262 { 259 {
263 case AF_INET: 260 switch (rr->addr_af)
264 alen = sizeof (struct in_addr); 261 {
265 break; 262 case AF_INET:
266 case AF_INET6: 263 alen = sizeof(struct in_addr);
267 alen = sizeof (struct in6_addr); 264 break;
268 break; 265
269 default: 266 case AF_INET6:
270 GNUNET_assert (0); 267 alen = sizeof(struct in6_addr);
271 return; 268 break;
269
270 default:
271 GNUNET_assert(0);
272 return;
273 }
274 env = GNUNET_MQ_msg_extra(rip,
275 alen,
276 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP);
277 rip->reserved = htonl(0);
278 rip->expiration_time = GNUNET_TIME_absolute_hton(rr->expiration_time);
279 rip->result_af = htonl(rr->result_af);
280 rip->addr_af = htonl(rr->addr_af);
281 rip->request_id = rr->request_id = ++vh->request_id_gen;
282 GNUNET_memcpy(&rip[1],
283 rr->addr,
284 alen);
272 } 285 }
273 env = GNUNET_MQ_msg_extra (rip, 286 GNUNET_MQ_send(vh->mq,
274 alen, 287 env);
275 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP);
276 rip->reserved = htonl (0);
277 rip->expiration_time = GNUNET_TIME_absolute_hton (rr->expiration_time);
278 rip->result_af = htonl (rr->result_af);
279 rip->addr_af = htonl (rr->addr_af);
280 rip->request_id = rr->request_id = ++vh->request_id_gen;
281 GNUNET_memcpy (&rip[1],
282 rr->addr,
283 alen);
284 }
285 GNUNET_MQ_send (vh->mq,
286 env);
287} 288}
288 289
289 290
@@ -296,12 +297,12 @@ send_request (struct GNUNET_VPN_RedirectionRequest *rr)
296 * @param error error code 297 * @param error error code
297 */ 298 */
298static void 299static void
299mq_error_handler (void *cls, 300mq_error_handler(void *cls,
300 enum GNUNET_MQ_Error error) 301 enum GNUNET_MQ_Error error)
301{ 302{
302 struct GNUNET_VPN_Handle *vh = cls; 303 struct GNUNET_VPN_Handle *vh = cls;
303 304
304 reconnect (vh); 305 reconnect(vh);
305} 306}
306 307
307 308
@@ -311,28 +312,28 @@ mq_error_handler (void *cls,
311 * @param cls the `struct GNUNET_VPN_Handle *` 312 * @param cls the `struct GNUNET_VPN_Handle *`
312 */ 313 */
313static void 314static void
314connect_task (void *cls) 315connect_task(void *cls)
315{ 316{
316 struct GNUNET_VPN_Handle *vh = cls; 317 struct GNUNET_VPN_Handle *vh = cls;
317 struct GNUNET_MQ_MessageHandler handlers[] = { 318 struct GNUNET_MQ_MessageHandler handlers[] = {
318 GNUNET_MQ_hd_var_size (use_ip, 319 GNUNET_MQ_hd_var_size(use_ip,
319 GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP, 320 GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP,
320 struct RedirectToIpResponseMessage, 321 struct RedirectToIpResponseMessage,
321 cls), 322 cls),
322 GNUNET_MQ_handler_end () 323 GNUNET_MQ_handler_end()
323 }; 324 };
324 struct GNUNET_VPN_RedirectionRequest *rr; 325 struct GNUNET_VPN_RedirectionRequest *rr;
325 326
326 vh->rt = NULL; 327 vh->rt = NULL;
327 vh->mq = GNUNET_CLIENT_connect (vh->cfg, 328 vh->mq = GNUNET_CLIENT_connect(vh->cfg,
328 "vpn", 329 "vpn",
329 handlers, 330 handlers,
330 &mq_error_handler, 331 &mq_error_handler,
331 vh); 332 vh);
332 if (NULL == vh->mq) 333 if (NULL == vh->mq)
333 return; 334 return;
334 for (rr = vh->rr_head; NULL != rr; rr = rr->next) 335 for (rr = vh->rr_head; NULL != rr; rr = rr->next)
335 send_request (rr); 336 send_request(rr);
336} 337}
337 338
338 339
@@ -342,21 +343,21 @@ connect_task (void *cls)
342 * @param vh handle to reconnect. 343 * @param vh handle to reconnect.
343 */ 344 */
344static void 345static void
345reconnect (struct GNUNET_VPN_Handle *vh) 346reconnect(struct GNUNET_VPN_Handle *vh)
346{ 347{
347 struct GNUNET_VPN_RedirectionRequest *rr; 348 struct GNUNET_VPN_RedirectionRequest *rr;
348 349
349 GNUNET_MQ_destroy (vh->mq); 350 GNUNET_MQ_destroy(vh->mq);
350 vh->mq = NULL; 351 vh->mq = NULL;
351 vh->request_id_gen = 0; 352 vh->request_id_gen = 0;
352 for (rr = vh->rr_head; NULL != rr; rr = rr->next) 353 for (rr = vh->rr_head; NULL != rr; rr = rr->next)
353 rr->request_id = 0; 354 rr->request_id = 0;
354 vh->backoff = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, 355 vh->backoff = GNUNET_TIME_relative_max(GNUNET_TIME_UNIT_MILLISECONDS,
355 GNUNET_TIME_relative_min (GNUNET_TIME_relative_saturating_multiply (vh->backoff, 2), 356 GNUNET_TIME_relative_min(GNUNET_TIME_relative_saturating_multiply(vh->backoff, 2),
356 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30))); 357 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)));
357 vh->rt = GNUNET_SCHEDULER_add_delayed (vh->backoff, 358 vh->rt = GNUNET_SCHEDULER_add_delayed(vh->backoff,
358 &connect_task, 359 &connect_task,
359 vh); 360 vh);
360} 361}
361 362
362 363
@@ -366,15 +367,15 @@ reconnect (struct GNUNET_VPN_Handle *vh)
366 * @param rr request to cancel 367 * @param rr request to cancel
367 */ 368 */
368void 369void
369GNUNET_VPN_cancel_request (struct GNUNET_VPN_RedirectionRequest *rr) 370GNUNET_VPN_cancel_request(struct GNUNET_VPN_RedirectionRequest *rr)
370{ 371{
371 struct GNUNET_VPN_Handle *vh; 372 struct GNUNET_VPN_Handle *vh;
372 373
373 vh = rr->vh; 374 vh = rr->vh;
374 GNUNET_CONTAINER_DLL_remove (vh->rr_head, 375 GNUNET_CONTAINER_DLL_remove(vh->rr_head,
375 vh->rr_tail, 376 vh->rr_tail,
376 rr); 377 rr);
377 GNUNET_free (rr); 378 GNUNET_free(rr);
378} 379}
379 380
380 381
@@ -401,18 +402,18 @@ GNUNET_VPN_cancel_request (struct GNUNET_VPN_RedirectionRequest *rr)
401 * anyway) 402 * anyway)
402 */ 403 */
403struct GNUNET_VPN_RedirectionRequest * 404struct GNUNET_VPN_RedirectionRequest *
404GNUNET_VPN_redirect_to_peer (struct GNUNET_VPN_Handle *vh, 405GNUNET_VPN_redirect_to_peer(struct GNUNET_VPN_Handle *vh,
405 int result_af, 406 int result_af,
406 uint8_t protocol, 407 uint8_t protocol,
407 const struct GNUNET_PeerIdentity *peer, 408 const struct GNUNET_PeerIdentity *peer,
408 const struct GNUNET_HashCode *serv, 409 const struct GNUNET_HashCode *serv,
409 struct GNUNET_TIME_Absolute expiration_time, 410 struct GNUNET_TIME_Absolute expiration_time,
410 GNUNET_VPN_AllocationCallback cb, 411 GNUNET_VPN_AllocationCallback cb,
411 void *cb_cls) 412 void *cb_cls)
412{ 413{
413 struct GNUNET_VPN_RedirectionRequest *rr; 414 struct GNUNET_VPN_RedirectionRequest *rr;
414 415
415 rr = GNUNET_new (struct GNUNET_VPN_RedirectionRequest); 416 rr = GNUNET_new(struct GNUNET_VPN_RedirectionRequest);
416 rr->vh = vh; 417 rr->vh = vh;
417 rr->cb = cb; 418 rr->cb = cb;
418 rr->cb_cls = cb_cls; 419 rr->cb_cls = cb_cls;
@@ -421,10 +422,10 @@ GNUNET_VPN_redirect_to_peer (struct GNUNET_VPN_Handle *vh,
421 rr->expiration_time = expiration_time; 422 rr->expiration_time = expiration_time;
422 rr->result_af = result_af; 423 rr->result_af = result_af;
423 rr->protocol = protocol; 424 rr->protocol = protocol;
424 GNUNET_CONTAINER_DLL_insert_tail (vh->rr_head, 425 GNUNET_CONTAINER_DLL_insert_tail(vh->rr_head,
425 vh->rr_tail, 426 vh->rr_tail,
426 rr); 427 rr);
427 send_request (rr); 428 send_request(rr);
428 return rr; 429 return rr;
429} 430}
430 431
@@ -452,30 +453,32 @@ GNUNET_VPN_redirect_to_peer (struct GNUNET_VPN_Handle *vh,
452 * anyway) 453 * anyway)
453 */ 454 */
454struct GNUNET_VPN_RedirectionRequest * 455struct GNUNET_VPN_RedirectionRequest *
455GNUNET_VPN_redirect_to_ip (struct GNUNET_VPN_Handle *vh, 456GNUNET_VPN_redirect_to_ip(struct GNUNET_VPN_Handle *vh,
456 int result_af, 457 int result_af,
457 int addr_af, 458 int addr_af,
458 const void *addr, 459 const void *addr,
459 struct GNUNET_TIME_Absolute expiration_time, 460 struct GNUNET_TIME_Absolute expiration_time,
460 GNUNET_VPN_AllocationCallback cb, 461 GNUNET_VPN_AllocationCallback cb,
461 void *cb_cls) 462 void *cb_cls)
462{ 463{
463 struct GNUNET_VPN_RedirectionRequest *rr; 464 struct GNUNET_VPN_RedirectionRequest *rr;
464 size_t alen; 465 size_t alen;
465 466
466 switch (addr_af) 467 switch (addr_af)
467 { 468 {
468 case AF_INET: 469 case AF_INET:
469 alen = sizeof (struct in_addr); 470 alen = sizeof(struct in_addr);
470 break; 471 break;
471 case AF_INET6: 472
472 alen = sizeof (struct in6_addr); 473 case AF_INET6:
473 break; 474 alen = sizeof(struct in6_addr);
474 default: 475 break;
475 GNUNET_break (0); 476
476 return NULL; 477 default:
477 } 478 GNUNET_break(0);
478 rr = GNUNET_malloc (sizeof (struct GNUNET_VPN_RedirectionRequest) + alen); 479 return NULL;
480 }
481 rr = GNUNET_malloc(sizeof(struct GNUNET_VPN_RedirectionRequest) + alen);
479 rr->vh = vh; 482 rr->vh = vh;
480 rr->addr = &rr[1]; 483 rr->addr = &rr[1];
481 rr->cb = cb; 484 rr->cb = cb;
@@ -483,13 +486,13 @@ GNUNET_VPN_redirect_to_ip (struct GNUNET_VPN_Handle *vh,
483 rr->expiration_time = expiration_time; 486 rr->expiration_time = expiration_time;
484 rr->result_af = result_af; 487 rr->result_af = result_af;
485 rr->addr_af = addr_af; 488 rr->addr_af = addr_af;
486 GNUNET_memcpy (&rr[1], 489 GNUNET_memcpy(&rr[1],
487 addr, 490 addr,
488 alen); 491 alen);
489 GNUNET_CONTAINER_DLL_insert_tail (vh->rr_head, 492 GNUNET_CONTAINER_DLL_insert_tail(vh->rr_head,
490 vh->rr_tail, 493 vh->rr_tail,
491 rr); 494 rr);
492 send_request (rr); 495 send_request(rr);
493 return rr; 496 return rr;
494} 497}
495 498
@@ -501,18 +504,18 @@ GNUNET_VPN_redirect_to_ip (struct GNUNET_VPN_Handle *vh,
501 * @return VPN handle 504 * @return VPN handle
502 */ 505 */
503struct GNUNET_VPN_Handle * 506struct GNUNET_VPN_Handle *
504GNUNET_VPN_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) 507GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
505{ 508{
506 struct GNUNET_VPN_Handle *vh 509 struct GNUNET_VPN_Handle *vh
507 = GNUNET_new (struct GNUNET_VPN_Handle); 510 = GNUNET_new(struct GNUNET_VPN_Handle);
508 511
509 vh->cfg = cfg; 512 vh->cfg = cfg;
510 connect_task (vh); 513 connect_task(vh);
511 if (NULL == vh->mq) 514 if (NULL == vh->mq)
512 { 515 {
513 GNUNET_free (vh); 516 GNUNET_free(vh);
514 return NULL; 517 return NULL;
515 } 518 }
516 return vh; 519 return vh;
517} 520}
518 521
@@ -523,20 +526,20 @@ GNUNET_VPN_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
523 * @param vh VPN handle 526 * @param vh VPN handle
524 */ 527 */
525void 528void
526GNUNET_VPN_disconnect (struct GNUNET_VPN_Handle *vh) 529GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
527{ 530{
528 GNUNET_assert (NULL == vh->rr_head); 531 GNUNET_assert(NULL == vh->rr_head);
529 if (NULL != vh->mq) 532 if (NULL != vh->mq)
530 { 533 {
531 GNUNET_MQ_destroy (vh->mq); 534 GNUNET_MQ_destroy(vh->mq);
532 vh->mq = NULL; 535 vh->mq = NULL;
533 } 536 }
534 if (NULL != vh->rt) 537 if (NULL != vh->rt)
535 { 538 {
536 GNUNET_SCHEDULER_cancel (vh->rt); 539 GNUNET_SCHEDULER_cancel(vh->rt);
537 vh->rt = NULL; 540 vh->rt = NULL;
538 } 541 }
539 GNUNET_free (vh); 542 GNUNET_free(vh);
540} 543}
541 544
542/* end of vpn_api.c */ 545/* end of vpn_api.c */