aboutsummaryrefslogtreecommitdiff
path: root/src/dns/gnunet-helper-dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns/gnunet-helper-dns.c')
-rw-r--r--src/dns/gnunet-helper-dns.c1336
1 files changed, 668 insertions, 668 deletions
diff --git a/src/dns/gnunet-helper-dns.c b/src/dns/gnunet-helper-dns.c
index 554727094..85c72579d 100644
--- a/src/dns/gnunet-helper-dns.c
+++ b/src/dns/gnunet-helper-dns.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 dns/gnunet-helper-dns.c 22 * @file dns/gnunet-helper-dns.c
@@ -87,8 +87,7 @@
87/** 87/**
88 * This is in linux/include/net/ipv6.h, but not always exported... 88 * This is in linux/include/net/ipv6.h, but not always exported...
89 */ 89 */
90struct in6_ifreq 90struct in6_ifreq {
91{
92 struct in6_addr ifr6_addr; 91 struct in6_addr ifr6_addr;
93 uint32_t ifr6_prefixlen; 92 uint32_t ifr6_prefixlen;
94 unsigned int ifr6_ifindex; 93 unsigned int ifr6_ifindex;
@@ -152,11 +151,11 @@ static int cpipe[2];
152 * @param signal signal number of the signal (not used) 151 * @param signal signal number of the signal (not used)
153 */ 152 */
154static void 153static void
155signal_handler (int signal) 154signal_handler(int signal)
156{ 155{
157 /* ignore return value, as the signal handler could theoretically 156 /* ignore return value, as the signal handler could theoretically
158 be called many times before the shutdown can actually happen */ 157 be called many times before the shutdown can actually happen */
159 (void) write (cpipe[1], "K", 1); 158 (void)write(cpipe[1], "K", 1);
160} 159}
161 160
162 161
@@ -168,22 +167,22 @@ signal_handler (int signal)
168 * @param flags open flags (O_RDONLY, O_WRONLY) 167 * @param flags open flags (O_RDONLY, O_WRONLY)
169 */ 168 */
170static void 169static void
171open_dev_null (int target_fd, 170open_dev_null(int target_fd,
172 int flags) 171 int flags)
173{ 172{
174 int fd; 173 int fd;
175 174
176 fd = open ("/dev/null", flags); 175 fd = open("/dev/null", flags);
177 if (-1 == fd) 176 if (-1 == fd)
178 abort (); 177 abort();
179 if (fd == target_fd) 178 if (fd == target_fd)
180 return; 179 return;
181 if (-1 == dup2 (fd, target_fd)) 180 if (-1 == dup2(fd, target_fd))
182 { 181 {
183 (void) close (fd); 182 (void)close(fd);
184 abort (); 183 abort();
185 } 184 }
186 (void) close (fd); 185 (void)close(fd);
187} 186}
188 187
189 188
@@ -195,49 +194,50 @@ open_dev_null (int target_fd,
195 * @return 0 on success, 1 on any error 194 * @return 0 on success, 1 on any error
196 */ 195 */
197static int 196static int
198fork_and_exec (const char *file, 197fork_and_exec(const char *file,
199 char *const cmd[]) 198 char *const cmd[])
200{ 199{
201 int status; 200 int status;
202 pid_t pid; 201 pid_t pid;
203 pid_t ret; 202 pid_t ret;
204 203
205 pid = fork (); 204 pid = fork();
206 if (-1 == pid) 205 if (-1 == pid)
207 { 206 {
208 fprintf (stderr, 207 fprintf(stderr,
209 "fork failed: %s\n", 208 "fork failed: %s\n",
210 strerror (errno)); 209 strerror(errno));
211 return 1; 210 return 1;
212 } 211 }
213 if (0 == pid) 212 if (0 == pid)
214 { 213 {
215 /* we are the child process */ 214 /* we are the child process */
216 /* close stdin/stdout to not cause interference 215 /* close stdin/stdout to not cause interference
217 with the helper's main protocol! */ 216 with the helper's main protocol! */
218 (void) close (0); 217 (void)close(0);
219 open_dev_null (0, O_RDONLY); 218 open_dev_null(0, O_RDONLY);
220 (void) close (1); 219 (void)close(1);
221 open_dev_null (1, O_WRONLY); 220 open_dev_null(1, O_WRONLY);
222 (void) execv (file, cmd); 221 (void)execv(file, cmd);
223 /* can only get here on error */ 222 /* can only get here on error */
224 fprintf (stderr, 223 fprintf(stderr,
225 "exec `%s' failed: %s\n", 224 "exec `%s' failed: %s\n",
226 file, 225 file,
227 strerror (errno)); 226 strerror(errno));
228 _exit (1); 227 _exit(1);
229 } 228 }
230 /* keep running waitpid as long as the only error we get is 'EINTR' */ 229 /* keep running waitpid as long as the only error we get is 'EINTR' */
231 while ( (-1 == (ret = waitpid (pid, &status, 0))) && 230 while ((-1 == (ret = waitpid(pid, &status, 0))) &&
232 (errno == EINTR) ); 231 (errno == EINTR))
232 ;
233 if (-1 == ret) 233 if (-1 == ret)
234 { 234 {
235 fprintf (stderr, 235 fprintf(stderr,
236 "waitpid failed: %s\n", 236 "waitpid failed: %s\n",
237 strerror (errno)); 237 strerror(errno));
238 return 1; 238 return 1;
239 } 239 }
240 if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) 240 if (!(WIFEXITED(status) && (0 == WEXITSTATUS(status))))
241 return 1; 241 return 1;
242 /* child process completed and returned success, we're happy */ 242 /* child process completed and returned success, we're happy */
243 return 0; 243 return 0;
@@ -252,45 +252,45 @@ fork_and_exec (const char *file,
252 * @return the fd to the tun or -1 on error 252 * @return the fd to the tun or -1 on error
253 */ 253 */
254static int 254static int
255init_tun (char *dev) 255init_tun(char *dev)
256{ 256{
257 struct ifreq ifr; 257 struct ifreq ifr;
258 int fd; 258 int fd;
259 259
260 if (NULL == dev) 260 if (NULL == dev)
261 { 261 {
262 errno = EINVAL; 262 errno = EINVAL;
263 return -1; 263 return -1;
264 } 264 }
265 265
266 if (-1 == (fd = open ("/dev/net/tun", O_RDWR))) 266 if (-1 == (fd = open("/dev/net/tun", O_RDWR)))
267 { 267 {
268 fprintf (stderr, "Error opening `%s': %s\n", "/dev/net/tun", 268 fprintf(stderr, "Error opening `%s': %s\n", "/dev/net/tun",
269 strerror (errno)); 269 strerror(errno));
270 return -1; 270 return -1;
271 } 271 }
272 272
273 if (fd >= FD_SETSIZE) 273 if (fd >= FD_SETSIZE)
274 { 274 {
275 fprintf (stderr, "File descriptor to large: %d", fd); 275 fprintf(stderr, "File descriptor to large: %d", fd);
276 (void) close (fd); 276 (void)close(fd);
277 return -1; 277 return -1;
278 } 278 }
279 279
280 memset (&ifr, 0, sizeof (ifr)); 280 memset(&ifr, 0, sizeof(ifr));
281 ifr.ifr_flags = IFF_TUN; 281 ifr.ifr_flags = IFF_TUN;
282 282
283 if ('\0' != *dev) 283 if ('\0' != *dev)
284 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 284 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
285 285
286 if (-1 == ioctl (fd, TUNSETIFF, (void *) &ifr)) 286 if (-1 == ioctl(fd, TUNSETIFF, (void *)&ifr))
287 { 287 {
288 fprintf (stderr, "Error with ioctl on `%s': %s\n", "/dev/net/tun", 288 fprintf(stderr, "Error with ioctl on `%s': %s\n", "/dev/net/tun",
289 strerror (errno)); 289 strerror(errno));
290 (void) close (fd); 290 (void)close(fd);
291 return -1; 291 return -1;
292 } 292 }
293 strcpy (dev, ifr.ifr_name); 293 strcpy(dev, ifr.ifr_name);
294 return fd; 294 return fd;
295} 295}
296 296
@@ -303,7 +303,7 @@ init_tun (char *dev)
303 * @param prefix_len the length of the network-prefix 303 * @param prefix_len the length of the network-prefix
304 */ 304 */
305static void 305static void
306set_address6 (const char *dev, const char *address, unsigned long prefix_len) 306set_address6(const char *dev, const char *address, unsigned long prefix_len)
307{ 307{
308 struct ifreq ifr; 308 struct ifreq ifr;
309 struct in6_ifreq ifr6; 309 struct in6_ifreq ifr6;
@@ -313,39 +313,39 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
313 /* 313 /*
314 * parse the new address 314 * parse the new address
315 */ 315 */
316 memset (&sa6, 0, sizeof (struct sockaddr_in6)); 316 memset(&sa6, 0, sizeof(struct sockaddr_in6));
317 sa6.sin6_family = AF_INET6; 317 sa6.sin6_family = AF_INET6;
318 if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) 318 if (1 != inet_pton(AF_INET6, address, sa6.sin6_addr.s6_addr))
319 { 319 {
320 fprintf (stderr, 320 fprintf(stderr,
321 "Failed to parse IPv6 address `%s': %s\n", 321 "Failed to parse IPv6 address `%s': %s\n",
322 address, 322 address,
323 strerror (errno)); 323 strerror(errno));
324 exit (1); 324 exit(1);
325 } 325 }
326 326
327 if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) 327 if (-1 == (fd = socket(PF_INET6, SOCK_DGRAM, 0)))
328 { 328 {
329 fprintf (stderr, 329 fprintf(stderr,
330 "Error creating IPv6 socket: %s (ignored)\n", 330 "Error creating IPv6 socket: %s (ignored)\n",
331 strerror (errno)); 331 strerror(errno));
332 /* ignore error, maybe only IPv4 works on this system! */ 332 /* ignore error, maybe only IPv4 works on this system! */
333 return; 333 return;
334 } 334 }
335 335
336 memset (&ifr, 0, sizeof (struct ifreq)); 336 memset(&ifr, 0, sizeof(struct ifreq));
337 /* 337 /*
338 * Get the index of the if 338 * Get the index of the if
339 */ 339 */
340 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 340 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
341 if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) 341 if (-1 == ioctl(fd, SIOGIFINDEX, &ifr))
342 { 342 {
343 fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); 343 fprintf(stderr, "ioctl failed at %d: %s\n", __LINE__, strerror(errno));
344 (void) close (fd); 344 (void)close(fd);
345 exit (1); 345 exit(1);
346 } 346 }
347 347
348 memset (&ifr6, 0, sizeof (struct in6_ifreq)); 348 memset(&ifr6, 0, sizeof(struct in6_ifreq));
349 ifr6.ifr6_addr = sa6.sin6_addr; 349 ifr6.ifr6_addr = sa6.sin6_addr;
350 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 350 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
351 ifr6.ifr6_prefixlen = prefix_len; 351 ifr6.ifr6_prefixlen = prefix_len;
@@ -353,42 +353,42 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
353 /* 353 /*
354 * Set the address 354 * Set the address
355 */ 355 */
356 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6)) 356 if (-1 == ioctl(fd, SIOCSIFADDR, &ifr6))
357 { 357 {
358 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 358 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
359 strerror (errno)); 359 strerror(errno));
360 (void) close (fd); 360 (void)close(fd);
361 exit (1); 361 exit(1);
362 } 362 }
363 363
364 /* 364 /*
365 * Get the flags 365 * Get the flags
366 */ 366 */
367 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) 367 if (-1 == ioctl(fd, SIOCGIFFLAGS, &ifr))
368 { 368 {
369 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 369 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
370 strerror (errno)); 370 strerror(errno));
371 (void) close (fd); 371 (void)close(fd);
372 exit (1); 372 exit(1);
373 } 373 }
374 374
375 /* 375 /*
376 * Add the UP and RUNNING flags 376 * Add the UP and RUNNING flags
377 */ 377 */
378 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 378 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
379 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) 379 if (-1 == ioctl(fd, SIOCSIFFLAGS, &ifr))
380 { 380 {
381 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 381 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
382 strerror (errno)); 382 strerror(errno));
383 (void) close (fd); 383 (void)close(fd);
384 exit (1); 384 exit(1);
385 } 385 }
386 386
387 if (0 != close (fd)) 387 if (0 != close(fd))
388 { 388 {
389 fprintf (stderr, "close failed: %s\n", strerror (errno)); 389 fprintf(stderr, "close failed: %s\n", strerror(errno));
390 exit (1); 390 exit(1);
391 } 391 }
392} 392}
393 393
394 394
@@ -400,100 +400,100 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
400 * @param mask the netmask 400 * @param mask the netmask
401 */ 401 */
402static void 402static void
403set_address4 (const char *dev, const char *address, const char *mask) 403set_address4(const char *dev, const char *address, const char *mask)
404{ 404{
405 int fd; 405 int fd;
406 struct sockaddr_in *addr; 406 struct sockaddr_in *addr;
407 struct ifreq ifr; 407 struct ifreq ifr;
408 408
409 memset (&ifr, 0, sizeof (struct ifreq)); 409 memset(&ifr, 0, sizeof(struct ifreq));
410 addr = (struct sockaddr_in *) &(ifr.ifr_addr); 410 addr = (struct sockaddr_in *)&(ifr.ifr_addr);
411 addr->sin_family = AF_INET; 411 addr->sin_family = AF_INET;
412 412
413 /* 413 /*
414 * Parse the address 414 * Parse the address
415 */ 415 */
416 if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr)) 416 if (1 != inet_pton(AF_INET, address, &addr->sin_addr.s_addr))
417 { 417 {
418 fprintf (stderr, 418 fprintf(stderr,
419 "Failed to parse IPv4 address `%s': %s\n", 419 "Failed to parse IPv4 address `%s': %s\n",
420 address, 420 address,
421 strerror (errno)); 421 strerror(errno));
422 exit (1); 422 exit(1);
423 } 423 }
424 424
425 if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) 425 if (-1 == (fd = socket(PF_INET, SOCK_DGRAM, 0)))
426 { 426 {
427 fprintf (stderr, 427 fprintf(stderr,
428 "Error creating IPv4 socket: %s\n", 428 "Error creating IPv4 socket: %s\n",
429 strerror (errno)); 429 strerror(errno));
430 exit (1); 430 exit(1);
431 } 431 }
432 432
433 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 433 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
434 434
435 /* 435 /*
436 * Set the address 436 * Set the address
437 */ 437 */
438 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr)) 438 if (-1 == ioctl(fd, SIOCSIFADDR, &ifr))
439 { 439 {
440 fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); 440 fprintf(stderr, "ioctl failed at %d: %s\n", __LINE__, strerror(errno));
441 (void) close (fd); 441 (void)close(fd);
442 exit (1); 442 exit(1);
443 } 443 }
444 444
445 /* 445 /*
446 * Parse the netmask 446 * Parse the netmask
447 */ 447 */
448 addr = (struct sockaddr_in *) &(ifr.ifr_netmask); 448 addr = (struct sockaddr_in *)&(ifr.ifr_netmask);
449 if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr)) 449 if (1 != inet_pton(AF_INET, mask, &addr->sin_addr.s_addr))
450 { 450 {
451 fprintf (stderr, "Failed to parse address `%s': %s\n", mask, 451 fprintf(stderr, "Failed to parse address `%s': %s\n", mask,
452 strerror (errno)); 452 strerror(errno));
453 (void) close (fd); 453 (void)close(fd);
454 exit (1); 454 exit(1);
455 } 455 }
456 456
457 /* 457 /*
458 * Set the netmask 458 * Set the netmask
459 */ 459 */
460 if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr)) 460 if (-1 == ioctl(fd, SIOCSIFNETMASK, &ifr))
461 { 461 {
462 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 462 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
463 strerror (errno)); 463 strerror(errno));
464 (void) close (fd); 464 (void)close(fd);
465 exit (1); 465 exit(1);
466 } 466 }
467 467
468 /* 468 /*
469 * Get the flags 469 * Get the flags
470 */ 470 */
471 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) 471 if (-1 == ioctl(fd, SIOCGIFFLAGS, &ifr))
472 { 472 {
473 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 473 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
474 strerror (errno)); 474 strerror(errno));
475 (void) close (fd); 475 (void)close(fd);
476 exit (1); 476 exit(1);
477 } 477 }
478 478
479 /* 479 /*
480 * Add the UP and RUNNING flags 480 * Add the UP and RUNNING flags
481 */ 481 */
482 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 482 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
483 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) 483 if (-1 == ioctl(fd, SIOCSIFFLAGS, &ifr))
484 { 484 {
485 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 485 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
486 strerror (errno)); 486 strerror(errno));
487 (void) close (fd); 487 (void)close(fd);
488 exit (1); 488 exit(1);
489 } 489 }
490 490
491 if (0 != close (fd)) 491 if (0 != close(fd))
492 { 492 {
493 fprintf (stderr, "close failed: %s\n", strerror (errno)); 493 fprintf(stderr, "close failed: %s\n", strerror(errno));
494 (void) close (fd); 494 (void)close(fd);
495 exit (1); 495 exit(1);
496 } 496 }
497} 497}
498 498
499 499
@@ -505,7 +505,7 @@ set_address4 (const char *dev, const char *address, const char *mask)
505 * @param fd_tun tunnel FD 505 * @param fd_tun tunnel FD
506 */ 506 */
507static void 507static void
508run (int fd_tun) 508run(int fd_tun)
509{ 509{
510 /* 510 /*
511 * The buffer filled by reading from fd_tun 511 * The buffer filled by reading from fd_tun
@@ -526,176 +526,176 @@ run (int fd_tun)
526 int max; 526 int max;
527 527
528 while (1) 528 while (1)
529 {
530 FD_ZERO (&fds_w);
531 FD_ZERO (&fds_r);
532
533 /*
534 * We are supposed to read and the buffer is empty
535 * -> select on read from tun
536 */
537 if (0 == buftun_size)
538 FD_SET (fd_tun, &fds_r);
539
540 /*
541 * We are supposed to read and the buffer is not empty
542 * -> select on write to stdout
543 */
544 if (0 < buftun_size)
545 FD_SET (1, &fds_w);
546
547 /*
548 * We are supposed to write and the buffer is empty
549 * -> select on read from stdin
550 */
551 if (NULL == bufin_read)
552 FD_SET (0, &fds_r);
553
554 /*
555 * We are supposed to write and the buffer is not empty
556 * -> select on write to tun
557 */
558 if (NULL != bufin_read)
559 FD_SET (fd_tun, &fds_w);
560
561 FD_SET (cpipe[0], &fds_r);
562 max = (fd_tun > cpipe[0]) ? fd_tun : cpipe[0];
563
564 int r = select (max + 1, &fds_r, &fds_w, NULL, NULL);
565
566 if (-1 == r)
567 {
568 if (EINTR == errno)
569 continue;
570 fprintf (stderr, "select failed: %s\n", strerror (errno));
571 return;
572 }
573
574 if (r > 0)
575 { 529 {
576 if (FD_ISSET (cpipe[0], &fds_r)) 530 FD_ZERO(&fds_w);
577 return; /* aborted by signal */ 531 FD_ZERO(&fds_r);
578 532
579 if (FD_ISSET (fd_tun, &fds_r)) 533 /*
580 { 534 * We are supposed to read and the buffer is empty
581 buftun_size = 535 * -> select on read from tun
582 read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), 536 */
583 MAX_SIZE - sizeof (struct GNUNET_MessageHeader)); 537 if (0 == buftun_size)
584 if (-1 == buftun_size) 538 FD_SET(fd_tun, &fds_r);
539
540 /*
541 * We are supposed to read and the buffer is not empty
542 * -> select on write to stdout
543 */
544 if (0 < buftun_size)
545 FD_SET(1, &fds_w);
546
547 /*
548 * We are supposed to write and the buffer is empty
549 * -> select on read from stdin
550 */
551 if (NULL == bufin_read)
552 FD_SET(0, &fds_r);
553
554 /*
555 * We are supposed to write and the buffer is not empty
556 * -> select on write to tun
557 */
558 if (NULL != bufin_read)
559 FD_SET(fd_tun, &fds_w);
560
561 FD_SET(cpipe[0], &fds_r);
562 max = (fd_tun > cpipe[0]) ? fd_tun : cpipe[0];
563
564 int r = select(max + 1, &fds_r, &fds_w, NULL, NULL);
565
566 if (-1 == r)
585 { 567 {
586 if ( (errno == EINTR) || 568 if (EINTR == errno)
587 (errno == EAGAIN) ) 569 continue;
588 { 570 fprintf(stderr, "select failed: %s\n", strerror(errno));
589 buftun_size = 0;
590 continue;
591 }
592 fprintf (stderr, "read-error: %s\n", strerror (errno));
593 return;
594 }
595 if (0 == buftun_size)
596 {
597 fprintf (stderr, "EOF on tun\n");
598 return;
599 }
600 buftun_read = buftun;
601 {
602 struct GNUNET_MessageHeader *hdr =
603 (struct GNUNET_MessageHeader *) buftun;
604 buftun_size += sizeof (struct GNUNET_MessageHeader);
605 hdr->type = htons (GNUNET_MESSAGE_TYPE_DNS_HELPER);
606 hdr->size = htons (buftun_size);
607 }
608 }
609 else if (FD_ISSET (1, &fds_w))
610 {
611 ssize_t written = write (1, buftun_read, buftun_size);
612
613 if (-1 == written)
614 {
615 if ( (errno == EINTR) ||
616 (errno == EAGAIN) )
617 continue;
618 fprintf (stderr, "write-error to stdout: %s\n", strerror (errno));
619 return;
620 }
621 if (0 == written)
622 {
623 fprintf (stderr, "write returned 0\n");
624 return; 571 return;
625 } 572 }
626 buftun_size -= written;
627 buftun_read += written;
628 }
629 573
630 if (FD_ISSET (0, &fds_r)) 574 if (r > 0)
631 {
632 bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos);
633 if (-1 == bufin_size)
634 { 575 {
635 bufin_read = NULL; 576 if (FD_ISSET(cpipe[0], &fds_r))
636 if ( (errno == EINTR) || 577 return; /* aborted by signal */
637 (errno == EAGAIN) ) 578
638 continue; 579 if (FD_ISSET(fd_tun, &fds_r))
639 fprintf (stderr, "read-error: %s\n", strerror (errno)); 580 {
640 return; 581 buftun_size =
641 } 582 read(fd_tun, buftun + sizeof(struct GNUNET_MessageHeader),
642 if (0 == bufin_size) 583 MAX_SIZE - sizeof(struct GNUNET_MessageHeader));
643 { 584 if (-1 == buftun_size)
644 bufin_read = NULL; 585 {
645 fprintf (stderr, "EOF on stdin\n"); 586 if ((errno == EINTR) ||
646 return; 587 (errno == EAGAIN))
647 } 588 {
648 { 589 buftun_size = 0;
649 struct GNUNET_MessageHeader *hdr; 590 continue;
591 }
592 fprintf(stderr, "read-error: %s\n", strerror(errno));
593 return;
594 }
595 if (0 == buftun_size)
596 {
597 fprintf(stderr, "EOF on tun\n");
598 return;
599 }
600 buftun_read = buftun;
601 {
602 struct GNUNET_MessageHeader *hdr =
603 (struct GNUNET_MessageHeader *)buftun;
604 buftun_size += sizeof(struct GNUNET_MessageHeader);
605 hdr->type = htons(GNUNET_MESSAGE_TYPE_DNS_HELPER);
606 hdr->size = htons(buftun_size);
607 }
608 }
609 else if (FD_ISSET(1, &fds_w))
610 {
611 ssize_t written = write(1, buftun_read, buftun_size);
612
613 if (-1 == written)
614 {
615 if ((errno == EINTR) ||
616 (errno == EAGAIN))
617 continue;
618 fprintf(stderr, "write-error to stdout: %s\n", strerror(errno));
619 return;
620 }
621 if (0 == written)
622 {
623 fprintf(stderr, "write returned 0\n");
624 return;
625 }
626 buftun_size -= written;
627 buftun_read += written;
628 }
629
630 if (FD_ISSET(0, &fds_r))
631 {
632 bufin_size = read(0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos);
633 if (-1 == bufin_size)
634 {
635 bufin_read = NULL;
636 if ((errno == EINTR) ||
637 (errno == EAGAIN))
638 continue;
639 fprintf(stderr, "read-error: %s\n", strerror(errno));
640 return;
641 }
642 if (0 == bufin_size)
643 {
644 bufin_read = NULL;
645 fprintf(stderr, "EOF on stdin\n");
646 return;
647 }
648 {
649 struct GNUNET_MessageHeader *hdr;
650 650
651PROCESS_BUFFER: 651PROCESS_BUFFER:
652 bufin_rpos += bufin_size; 652 bufin_rpos += bufin_size;
653 if (bufin_rpos < sizeof (struct GNUNET_MessageHeader)) 653 if (bufin_rpos < sizeof(struct GNUNET_MessageHeader))
654 continue; 654 continue;
655 hdr = (struct GNUNET_MessageHeader *) bufin; 655 hdr = (struct GNUNET_MessageHeader *)bufin;
656 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_DNS_HELPER) 656 if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_DNS_HELPER)
657 { 657 {
658 fprintf (stderr, "protocol violation!\n"); 658 fprintf(stderr, "protocol violation!\n");
659 return; 659 return;
660 } 660 }
661 if (ntohs (hdr->size) > bufin_rpos) 661 if (ntohs(hdr->size) > bufin_rpos)
662 continue; 662 continue;
663 bufin_read = bufin + sizeof (struct GNUNET_MessageHeader); 663 bufin_read = bufin + sizeof(struct GNUNET_MessageHeader);
664 bufin_size = ntohs (hdr->size) - sizeof (struct GNUNET_MessageHeader); 664 bufin_size = ntohs(hdr->size) - sizeof(struct GNUNET_MessageHeader);
665 bufin_rpos -= bufin_size + sizeof (struct GNUNET_MessageHeader); 665 bufin_rpos -= bufin_size + sizeof(struct GNUNET_MessageHeader);
666 } 666 }
667 } 667 }
668 else if (FD_ISSET (fd_tun, &fds_w)) 668 else if (FD_ISSET(fd_tun, &fds_w))
669 { 669 {
670 ssize_t written = write (fd_tun, bufin_read, bufin_size); 670 ssize_t written = write(fd_tun, bufin_read, bufin_size);
671 671
672 if (-1 == written) 672 if (-1 == written)
673 { 673 {
674 if ( (errno == EINTR) || 674 if ((errno == EINTR) ||
675 (errno == EAGAIN) ) 675 (errno == EAGAIN))
676 continue; 676 continue;
677 fprintf (stderr, "write-error to tun: %s\n", strerror (errno)); 677 fprintf(stderr, "write-error to tun: %s\n", strerror(errno));
678 return; 678 return;
679 } 679 }
680 if (0 == written) 680 if (0 == written)
681 { 681 {
682 fprintf (stderr, "write returned 0\n"); 682 fprintf(stderr, "write returned 0\n");
683 return; 683 return;
684 }
685 {
686 bufin_size -= written;
687 bufin_read += written;
688 if (0 == bufin_size)
689 {
690 memmove(bufin, bufin_read, bufin_rpos);
691 bufin_read = NULL; /* start reading again */
692 bufin_size = 0;
693 goto PROCESS_BUFFER;
694 }
695 }
696 }
684 } 697 }
685 {
686 bufin_size -= written;
687 bufin_read += written;
688 if (0 == bufin_size)
689 {
690 memmove (bufin, bufin_read, bufin_rpos);
691 bufin_read = NULL; /* start reading again */
692 bufin_size = 0;
693 goto PROCESS_BUFFER;
694 }
695 }
696 }
697 } 698 }
698 }
699} 699}
700 700
701 701
@@ -732,7 +732,7 @@ PROCESS_BUFFER:
732 * 255 failed to handle kill signal properly 732 * 255 failed to handle kill signal properly
733 */ 733 */
734int 734int
735main (int argc, char *const*argv) 735main(int argc, char *const*argv)
736{ 736{
737 int r; 737 int r;
738 char dev[IFNAMSIZ]; 738 char dev[IFNAMSIZ];
@@ -742,224 +742,224 @@ main (int argc, char *const*argv)
742 int nortsetup = 0; 742 int nortsetup = 0;
743 743
744 if (7 != argc) 744 if (7 != argc)
745 { 745 {
746 fprintf (stderr, "Fatal: must supply 6 arguments!\n"); 746 fprintf(stderr, "Fatal: must supply 6 arguments!\n");
747 return 1; 747 return 1;
748 } 748 }
749 749
750 /* assert privs so we can modify the firewall rules! */ 750 /* assert privs so we can modify the firewall rules! */
751 uid = getuid (); 751 uid = getuid();
752#ifdef HAVE_SETRESUID 752#ifdef HAVE_SETRESUID
753 if (0 != setresuid (uid, 0, 0)) 753 if (0 != setresuid(uid, 0, 0))
754 { 754 {
755 fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno)); 755 fprintf(stderr, "Failed to setresuid to root: %s\n", strerror(errno));
756 return 254; 756 return 254;
757 } 757 }
758#else 758#else
759 if (0 != seteuid (0)) 759 if (0 != seteuid(0))
760 { 760 {
761 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno)); 761 fprintf(stderr, "Failed to seteuid back to root: %s\n", strerror(errno));
762 return 254; 762 return 254;
763 } 763 }
764#endif 764#endif
765 if (0 == strncmp (argv[6], "1", 2)) 765 if (0 == strncmp(argv[6], "1", 2))
766 nortsetup = 1; 766 nortsetup = 1;
767 767
768 if (0 == nortsetup) 768 if (0 == nortsetup)
769 { 769 {
770 /* verify that the binaries we care about are executable */ 770 /* verify that the binaries we care about are executable */
771#ifdef IPTABLES 771#ifdef IPTABLES
772 if (0 == access (IPTABLES, X_OK)) 772 if (0 == access(IPTABLES, X_OK))
773 sbin_iptables = IPTABLES; 773 sbin_iptables = IPTABLES;
774 else 774 else
775#endif 775#endif
776 if (0 == access ("/sbin/iptables", X_OK)) 776 if (0 == access("/sbin/iptables", X_OK))
777 sbin_iptables = "/sbin/iptables"; 777 sbin_iptables = "/sbin/iptables";
778 else if (0 == access ("/usr/sbin/iptables", X_OK)) 778 else if (0 == access("/usr/sbin/iptables", X_OK))
779 sbin_iptables = "/usr/sbin/iptables"; 779 sbin_iptables = "/usr/sbin/iptables";
780 else 780 else
781 { 781 {
782 fprintf (stderr, 782 fprintf(stderr,
783 "Fatal: executable iptables not found in approved directories: %s\n", 783 "Fatal: executable iptables not found in approved directories: %s\n",
784 strerror (errno)); 784 strerror(errno));
785 return 3; 785 return 3;
786 } 786 }
787#ifdef IP6TABLES 787#ifdef IP6TABLES
788 if (0 == access (IP6TABLES, X_OK)) 788 if (0 == access(IP6TABLES, X_OK))
789 sbin_ip6tables = IP6TABLES; 789 sbin_ip6tables = IP6TABLES;
790 else 790 else
791#endif 791#endif
792 if (0 == access ("/sbin/ip6tables", X_OK)) 792 if (0 == access("/sbin/ip6tables", X_OK))
793 sbin_ip6tables = "/sbin/ip6tables"; 793 sbin_ip6tables = "/sbin/ip6tables";
794 else if (0 == access ("/usr/sbin/ip6tables", X_OK)) 794 else if (0 == access("/usr/sbin/ip6tables", X_OK))
795 sbin_ip6tables = "/usr/sbin/ip6tables"; 795 sbin_ip6tables = "/usr/sbin/ip6tables";
796 else 796 else
797 { 797 {
798 fprintf (stderr, 798 fprintf(stderr,
799 "Fatal: executable ip6tables not found in approved directories: %s\n", 799 "Fatal: executable ip6tables not found in approved directories: %s\n",
800 strerror (errno)); 800 strerror(errno));
801 return 3; 801 return 3;
802 } 802 }
803#ifdef PATH_TO_IP 803#ifdef PATH_TO_IP
804 if (0 == access (PATH_TO_IP, X_OK)) 804 if (0 == access(PATH_TO_IP, X_OK))
805 sbin_ip = PATH_TO_IP; 805 sbin_ip = PATH_TO_IP;
806 else 806 else
807#endif 807#endif
808 if (0 == access ("/sbin/ip", X_OK)) 808 if (0 == access("/sbin/ip", X_OK))
809 sbin_ip = "/sbin/ip"; 809 sbin_ip = "/sbin/ip";
810 else if (0 == access ("/usr/sbin/ip", X_OK)) 810 else if (0 == access("/usr/sbin/ip", X_OK))
811 sbin_ip = "/usr/sbin/ip"; 811 sbin_ip = "/usr/sbin/ip";
812 else if (0 == access ("/bin/ip", X_OK)) /* gentoo has it there */ 812 else if (0 == access("/bin/ip", X_OK)) /* gentoo has it there */
813 sbin_ip = "/bin/ip"; 813 sbin_ip = "/bin/ip";
814 else 814 else
815 { 815 {
816 fprintf (stderr, 816 fprintf(stderr,
817 "Fatal: executable ip not found in approved directories: %s\n", 817 "Fatal: executable ip not found in approved directories: %s\n",
818 strerror (errno)); 818 strerror(errno));
819 return 4; 819 return 4;
820 } 820 }
821#ifdef SYSCTL 821#ifdef SYSCTL
822 if (0 == access (SYSCTL, X_OK)) 822 if (0 == access(SYSCTL, X_OK))
823 sbin_sysctl = SYSCTL; 823 sbin_sysctl = SYSCTL;
824 else 824 else
825#endif 825#endif
826 if (0 == access ("/sbin/sysctl", X_OK)) 826 if (0 == access("/sbin/sysctl", X_OK))
827 sbin_sysctl = "/sbin/sysctl"; 827 sbin_sysctl = "/sbin/sysctl";
828 else if (0 == access ("/usr/sbin/sysctl", X_OK)) 828 else if (0 == access("/usr/sbin/sysctl", X_OK))
829 sbin_sysctl = "/usr/sbin/sysctl"; 829 sbin_sysctl = "/usr/sbin/sysctl";
830 else 830 else
831 { 831 {
832 fprintf (stderr, 832 fprintf(stderr,
833 "Fatal: executable sysctl not found in approved directories: %s\n", 833 "Fatal: executable sysctl not found in approved directories: %s\n",
834 strerror (errno)); 834 strerror(errno));
835 return 5; 835 return 5;
836 }
836 } 837 }
837 }
838 838
839 /* setup 'mygid' string */ 839 /* setup 'mygid' string */
840 snprintf (mygid, sizeof (mygid), "%d", (int) getegid()); 840 snprintf(mygid, sizeof(mygid), "%d", (int)getegid());
841 841
842 /* do not die on SIGPIPE */ 842 /* do not die on SIGPIPE */
843 if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) 843 if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
844 { 844 {
845 fprintf (stderr, "Failed to protect against SIGPIPE: %s\n", 845 fprintf(stderr, "Failed to protect against SIGPIPE: %s\n",
846 strerror (errno)); 846 strerror(errno));
847 return 7; 847 return 7;
848 } 848 }
849 849
850 /* setup pipe to shutdown nicely on SIGINT */ 850 /* setup pipe to shutdown nicely on SIGINT */
851 if (0 != pipe (cpipe)) 851 if (0 != pipe(cpipe))
852 {
853 fprintf (stderr,
854 "Fatal: could not setup control pipe: %s\n",
855 strerror (errno));
856 return 6;
857 }
858 if (cpipe[0] >= FD_SETSIZE)
859 {
860 fprintf (stderr, "Pipe file descriptor to large: %d", cpipe[0]);
861 (void) close (cpipe[0]);
862 (void) close (cpipe[1]);
863 return 6;
864 }
865 {
866 /* make pipe non-blocking, as we theoretically could otherwise block
867 in the signal handler */
868 int flags = fcntl (cpipe[1], F_GETFL);
869 if (-1 == flags)
870 { 852 {
871 fprintf (stderr, "Failed to read flags for pipe: %s", strerror (errno)); 853 fprintf(stderr,
872 (void) close (cpipe[0]); 854 "Fatal: could not setup control pipe: %s\n",
873 (void) close (cpipe[1]); 855 strerror(errno));
874 return 6; 856 return 6;
875 } 857 }
876 flags |= O_NONBLOCK; 858 if (cpipe[0] >= FD_SETSIZE)
877 if (0 != fcntl (cpipe[1], F_SETFL, flags))
878 { 859 {
879 fprintf (stderr, "Failed to make pipe non-blocking: %s", strerror (errno)); 860 fprintf(stderr, "Pipe file descriptor to large: %d", cpipe[0]);
880 (void) close (cpipe[0]); 861 (void)close(cpipe[0]);
881 (void) close (cpipe[1]); 862 (void)close(cpipe[1]);
882 return 6; 863 return 6;
883 } 864 }
865 {
866 /* make pipe non-blocking, as we theoretically could otherwise block
867 in the signal handler */
868 int flags = fcntl(cpipe[1], F_GETFL);
869 if (-1 == flags)
870 {
871 fprintf(stderr, "Failed to read flags for pipe: %s", strerror(errno));
872 (void)close(cpipe[0]);
873 (void)close(cpipe[1]);
874 return 6;
875 }
876 flags |= O_NONBLOCK;
877 if (0 != fcntl(cpipe[1], F_SETFL, flags))
878 {
879 fprintf(stderr, "Failed to make pipe non-blocking: %s", strerror(errno));
880 (void)close(cpipe[0]);
881 (void)close(cpipe[1]);
882 return 6;
883 }
884 } 884 }
885 if ( (SIG_ERR == signal (SIGTERM, &signal_handler)) || 885 if ((SIG_ERR == signal(SIGTERM, &signal_handler)) ||
886#if (SIGTERM != GNUNET_TERM_SIG) 886#if (SIGTERM != GNUNET_TERM_SIG)
887 (SIG_ERR == signal (GNUNET_TERM_SIG, &signal_handler)) || 887 (SIG_ERR == signal(GNUNET_TERM_SIG, &signal_handler)) ||
888#endif 888#endif
889 (SIG_ERR == signal (SIGINT, &signal_handler)) || 889 (SIG_ERR == signal(SIGINT, &signal_handler)) ||
890 (SIG_ERR == signal (SIGHUP, &signal_handler)) ) 890 (SIG_ERR == signal(SIGHUP, &signal_handler)))
891 { 891 {
892 fprintf (stderr, 892 fprintf(stderr,
893 "Fatal: could not initialize signal handler: %s\n", 893 "Fatal: could not initialize signal handler: %s\n",
894 strerror (errno)); 894 strerror(errno));
895 (void) close (cpipe[0]); 895 (void)close(cpipe[0]);
896 (void) close (cpipe[1]); 896 (void)close(cpipe[1]);
897 return 7; 897 return 7;
898 } 898 }
899 899
900 900
901 /* get interface name */ 901 /* get interface name */
902 strncpy (dev, argv[1], IFNAMSIZ); 902 strncpy(dev, argv[1], IFNAMSIZ);
903 dev[IFNAMSIZ - 1] = '\0'; 903 dev[IFNAMSIZ - 1] = '\0';
904 904
905 /* Disable rp filtering */ 905 /* Disable rp filtering */
906 if (0 == nortsetup) 906 if (0 == nortsetup)
907 {
908 char *const sysctl_args[] = {"sysctl", "-w",
909 "net.ipv4.conf.all.rp_filter=0", NULL};
910 char *const sysctl_args2[] = {"sysctl", "-w",
911 "net.ipv4.conf.default.rp_filter=0", NULL};
912 if ((0 != fork_and_exec (sbin_sysctl, sysctl_args)) ||
913 (0 != fork_and_exec (sbin_sysctl, sysctl_args2)))
914 { 907 {
915 fprintf (stderr, 908 char *const sysctl_args[] = { "sysctl", "-w",
916 "Failed to disable rp filtering.\n"); 909 "net.ipv4.conf.all.rp_filter=0", NULL };
917 return 5; 910 char *const sysctl_args2[] = { "sysctl", "-w",
911 "net.ipv4.conf.default.rp_filter=0", NULL };
912 if ((0 != fork_and_exec(sbin_sysctl, sysctl_args)) ||
913 (0 != fork_and_exec(sbin_sysctl, sysctl_args2)))
914 {
915 fprintf(stderr,
916 "Failed to disable rp filtering.\n");
917 return 5;
918 }
918 } 919 }
919 }
920 920
921 921
922 /* now open virtual interface (first part that requires root) */ 922 /* now open virtual interface (first part that requires root) */
923 if (-1 == (fd_tun = init_tun (dev))) 923 if (-1 == (fd_tun = init_tun(dev)))
924 { 924 {
925 fprintf (stderr, "Fatal: could not initialize tun-interface\n"); 925 fprintf(stderr, "Fatal: could not initialize tun-interface\n");
926 (void) signal (SIGTERM, SIG_IGN); 926 (void)signal(SIGTERM, SIG_IGN);
927#if (SIGTERM != GNUNET_TERM_SIG) 927#if (SIGTERM != GNUNET_TERM_SIG)
928 (void) signal (GNUNET_TERM_SIG, SIG_IGN); 928 (void)signal(GNUNET_TERM_SIG, SIG_IGN);
929#endif 929#endif
930 (void) signal (SIGINT, SIG_IGN); 930 (void)signal(SIGINT, SIG_IGN);
931 (void) signal (SIGHUP, SIG_IGN); 931 (void)signal(SIGHUP, SIG_IGN);
932 (void) close (cpipe[0]); 932 (void)close(cpipe[0]);
933 (void) close (cpipe[1]); 933 (void)close(cpipe[1]);
934 return 5; 934 return 5;
935 } 935 }
936 936
937 /* now set interface addresses */ 937 /* now set interface addresses */
938 { 938 {
939 const char *address = argv[2]; 939 const char *address = argv[2];
940 long prefix_len = atol (argv[3]); 940 long prefix_len = atol(argv[3]);
941 941
942 if ((prefix_len < 1) || (prefix_len > 127)) 942 if ((prefix_len < 1) || (prefix_len > 127))
943 { 943 {
944 fprintf (stderr, "Fatal: prefix_len out of range\n"); 944 fprintf(stderr, "Fatal: prefix_len out of range\n");
945 (void) signal (SIGTERM, SIG_IGN); 945 (void)signal(SIGTERM, SIG_IGN);
946#if (SIGTERM != GNUNET_TERM_SIG) 946#if (SIGTERM != GNUNET_TERM_SIG)
947 (void) signal (GNUNET_TERM_SIG, SIG_IGN); 947 (void)signal(GNUNET_TERM_SIG, SIG_IGN);
948#endif 948#endif
949 (void) signal (SIGINT, SIG_IGN); 949 (void)signal(SIGINT, SIG_IGN);
950 (void) signal (SIGHUP, SIG_IGN); 950 (void)signal(SIGHUP, SIG_IGN);
951 (void) close (cpipe[0]); 951 (void)close(cpipe[0]);
952 (void) close (cpipe[1]); 952 (void)close(cpipe[1]);
953 return 2; 953 return 2;
954 } 954 }
955 set_address6 (dev, address, prefix_len); 955 set_address6(dev, address, prefix_len);
956 } 956 }
957 957
958 { 958 {
959 const char *address = argv[4]; 959 const char *address = argv[4];
960 const char *mask = argv[5]; 960 const char *mask = argv[5];
961 961
962 set_address4 (dev, address, mask); 962 set_address4(dev, address, mask);
963 } 963 }
964 964
965 965
@@ -968,237 +968,237 @@ main (int argc, char *const*argv)
968 by the 'gnunet-service-dns') and with destination 968 by the 'gnunet-service-dns') and with destination
969 to port 53 on UDP, without hijacking */ 969 to port 53 on UDP, without hijacking */
970 if (0 == nortsetup) 970 if (0 == nortsetup)
971 {
972 r = 8; /* failed to fully setup routing table */
973 { 971 {
974 char *const mangle_args[] = 972 r = 8; /* failed to fully setup routing table */
973 {
974 char *const mangle_args[] =
975 { 975 {
976 "iptables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p", 976 "iptables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p",
977 "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j", 977 "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j",
978 "ACCEPT", NULL 978 "ACCEPT", NULL
979 }; 979 };
980 if (0 != fork_and_exec (sbin_iptables, mangle_args)) 980 if (0 != fork_and_exec(sbin_iptables, mangle_args))
981 goto cleanup_rest; 981 goto cleanup_rest;
982 } 982 }
983 { 983 {
984 char *const mangle_args[] = 984 char *const mangle_args[] =
985 { 985 {
986 "ip6tables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p", 986 "ip6tables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p",
987 "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j", 987 "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j",
988 "ACCEPT", NULL 988 "ACCEPT", NULL
989 }; 989 };
990 if (0 != fork_and_exec (sbin_ip6tables, mangle_args)) 990 if (0 != fork_and_exec(sbin_ip6tables, mangle_args))
991 goto cleanup_mangle_1b; 991 goto cleanup_mangle_1b;
992 } 992 }
993 /* Mark all of the other DNS traffic using our mark DNS_MARK, 993 /* Mark all of the other DNS traffic using our mark DNS_MARK,
994 unless it is on a link-local IPv6 address, which we cannot support. */ 994 unless it is on a link-local IPv6 address, which we cannot support. */
995 { 995 {
996 char *const mark_args[] = 996 char *const mark_args[] =
997 { 997 {
998 "iptables", "-t", "mangle", "-I", "OUTPUT", "2", "-p", 998 "iptables", "-t", "mangle", "-I", "OUTPUT", "2", "-p",
999 "udp", "--dport", DNS_PORT, 999 "udp", "--dport", DNS_PORT,
1000 "-j", "MARK", "--set-mark", DNS_MARK, 1000 "-j", "MARK", "--set-mark", DNS_MARK,
1001 NULL 1001 NULL
1002 }; 1002 };
1003 if (0 != fork_and_exec (sbin_iptables, mark_args)) 1003 if (0 != fork_and_exec(sbin_iptables, mark_args))
1004 goto cleanup_mangle_1; 1004 goto cleanup_mangle_1;
1005 } 1005 }
1006 { 1006 {
1007 char *const mark_args[] = 1007 char *const mark_args[] =
1008 { 1008 {
1009 "ip6tables", "-t", "mangle", "-I", "OUTPUT", "2", "-p", 1009 "ip6tables", "-t", "mangle", "-I", "OUTPUT", "2", "-p",
1010 "udp", "--dport", DNS_PORT, 1010 "udp", "--dport", DNS_PORT,
1011 "!", "-s", "fe80::/10", /* this line excludes link-local traffic */ 1011 "!", "-s", "fe80::/10", /* this line excludes link-local traffic */
1012 "-j", "MARK", "--set-mark", DNS_MARK, 1012 "-j", "MARK", "--set-mark", DNS_MARK,
1013 NULL 1013 NULL
1014 }; 1014 };
1015 if (0 != fork_and_exec (sbin_ip6tables, mark_args)) 1015 if (0 != fork_and_exec(sbin_ip6tables, mark_args))
1016 goto cleanup_mark_2b; 1016 goto cleanup_mark_2b;
1017 } 1017 }
1018 /* Forward all marked DNS traffic to our DNS_TABLE */ 1018 /* Forward all marked DNS traffic to our DNS_TABLE */
1019 { 1019 {
1020 char *const forward_args[] = 1020 char *const forward_args[] =
1021 { 1021 {
1022 "ip", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL 1022 "ip", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
1023 }; 1023 };
1024 if (0 != fork_and_exec (sbin_ip, forward_args)) 1024 if (0 != fork_and_exec(sbin_ip, forward_args))
1025 goto cleanup_mark_2; 1025 goto cleanup_mark_2;
1026 } 1026 }
1027 { 1027 {
1028 char *const forward_args[] = 1028 char *const forward_args[] =
1029 { 1029 {
1030 "ip", "-6", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL 1030 "ip", "-6", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
1031 }; 1031 };
1032 if (0 != fork_and_exec (sbin_ip, forward_args)) 1032 if (0 != fork_and_exec(sbin_ip, forward_args))
1033 goto cleanup_forward_3b; 1033 goto cleanup_forward_3b;
1034 } 1034 }
1035 /* Finally, add rule in our forwarding table to pass to our virtual interface */ 1035 /* Finally, add rule in our forwarding table to pass to our virtual interface */
1036 { 1036 {
1037 char *const route_args[] = 1037 char *const route_args[] =
1038 { 1038 {
1039 "ip", "route", "add", "default", "dev", dev, 1039 "ip", "route", "add", "default", "dev", dev,
1040 "table", DNS_TABLE, NULL 1040 "table", DNS_TABLE, NULL
1041 }; 1041 };
1042 if (0 != fork_and_exec (sbin_ip, route_args)) 1042 if (0 != fork_and_exec(sbin_ip, route_args))
1043 goto cleanup_forward_3; 1043 goto cleanup_forward_3;
1044 } 1044 }
1045 { 1045 {
1046 char *const route_args[] = 1046 char *const route_args[] =
1047 { 1047 {
1048 "ip", "-6", "route", "add", "default", "dev", dev, 1048 "ip", "-6", "route", "add", "default", "dev", dev,
1049 "table", DNS_TABLE, NULL 1049 "table", DNS_TABLE, NULL
1050 }; 1050 };
1051 if (0 != fork_and_exec (sbin_ip, route_args)) 1051 if (0 != fork_and_exec(sbin_ip, route_args))
1052 goto cleanup_route_4b; 1052 goto cleanup_route_4b;
1053 }
1053 } 1054 }
1054 }
1055 1055
1056 /* drop privs *except* for the saved UID; this is not perfect, but better 1056 /* drop privs *except* for the saved UID; this is not perfect, but better
1057 than doing nothing */ 1057 than doing nothing */
1058#ifdef HAVE_SETRESUID 1058#ifdef HAVE_SETRESUID
1059 if (0 != setresuid (uid, uid, 0)) 1059 if (0 != setresuid(uid, uid, 0))
1060 { 1060 {
1061 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); 1061 fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
1062 r = 24; 1062 r = 24;
1063 goto cleanup_route_4; 1063 goto cleanup_route_4;
1064 } 1064 }
1065#else 1065#else
1066 /* Note: no 'setuid' here as we must keep our saved UID as root */ 1066 /* Note: no 'setuid' here as we must keep our saved UID as root */
1067 if (0 != seteuid (uid)) 1067 if (0 != seteuid(uid))
1068 { 1068 {
1069 fprintf (stderr, "Failed to seteuid: %s\n", strerror (errno)); 1069 fprintf(stderr, "Failed to seteuid: %s\n", strerror(errno));
1070 r = 24; 1070 r = 24;
1071 goto cleanup_route_4; 1071 goto cleanup_route_4;
1072 } 1072 }
1073#endif 1073#endif
1074 1074
1075 r = 0; /* did fully setup routing table (if nothing else happens, we were successful!) */ 1075 r = 0; /* did fully setup routing table (if nothing else happens, we were successful!) */
1076 1076
1077 /* now forward until we hit a problem */ 1077 /* now forward until we hit a problem */
1078 run (fd_tun); 1078 run(fd_tun);
1079 1079
1080 /* now need to regain privs so we can remove the firewall rules we added! */ 1080 /* now need to regain privs so we can remove the firewall rules we added! */
1081#ifdef HAVE_SETRESUID 1081#ifdef HAVE_SETRESUID
1082 if (0 != setresuid (uid, 0, 0)) 1082 if (0 != setresuid(uid, 0, 0))
1083 { 1083 {
1084 fprintf (stderr, "Failed to setresuid back to root: %s\n", strerror (errno)); 1084 fprintf(stderr, "Failed to setresuid back to root: %s\n", strerror(errno));
1085 r = 40; 1085 r = 40;
1086 goto cleanup_route_4; 1086 goto cleanup_route_4;
1087 } 1087 }
1088#else 1088#else
1089 if (0 != seteuid (0)) 1089 if (0 != seteuid(0))
1090 { 1090 {
1091 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno)); 1091 fprintf(stderr, "Failed to seteuid back to root: %s\n", strerror(errno));
1092 r = 40; 1092 r = 40;
1093 goto cleanup_route_4; 1093 goto cleanup_route_4;
1094 } 1094 }
1095#endif 1095#endif
1096 1096
1097 /* update routing tables again -- this is why we could not fully drop privs */ 1097 /* update routing tables again -- this is why we could not fully drop privs */
1098 /* now undo updating of routing tables; normal exit or clean-up-on-error case */ 1098 /* now undo updating of routing tables; normal exit or clean-up-on-error case */
1099 cleanup_route_4: 1099cleanup_route_4:
1100 if (0 == nortsetup) 1100 if (0 == nortsetup)
1101 { 1101 {
1102 char *const route_clean_args[] = 1102 char *const route_clean_args[] =
1103 { 1103 {
1104 "ip", "-6", "route", "del", "default", "dev", dev, 1104 "ip", "-6", "route", "del", "default", "dev", dev,
1105 "table", DNS_TABLE, NULL 1105 "table", DNS_TABLE, NULL
1106 }; 1106 };
1107 if (0 != fork_and_exec (sbin_ip, route_clean_args)) 1107 if (0 != fork_and_exec(sbin_ip, route_clean_args))
1108 r += 1; 1108 r += 1;
1109 } 1109 }
1110 cleanup_route_4b: 1110cleanup_route_4b:
1111 if (0 == nortsetup) 1111 if (0 == nortsetup)
1112 { 1112 {
1113 char *const route_clean_args[] = 1113 char *const route_clean_args[] =
1114 { 1114 {
1115 "ip", "route", "del", "default", "dev", dev, 1115 "ip", "route", "del", "default", "dev", dev,
1116 "table", DNS_TABLE, NULL 1116 "table", DNS_TABLE, NULL
1117 }; 1117 };
1118 if (0 != fork_and_exec (sbin_ip, route_clean_args)) 1118 if (0 != fork_and_exec(sbin_ip, route_clean_args))
1119 r += 1; 1119 r += 1;
1120 } 1120 }
1121 cleanup_forward_3: 1121cleanup_forward_3:
1122 if (0 == nortsetup) 1122 if (0 == nortsetup)
1123 { 1123 {
1124 char *const forward_clean_args[] = 1124 char *const forward_clean_args[] =
1125 { 1125 {
1126 "ip", "-6", "rule", "del", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL 1126 "ip", "-6", "rule", "del", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
1127 }; 1127 };
1128 if (0 != fork_and_exec (sbin_ip, forward_clean_args)) 1128 if (0 != fork_and_exec(sbin_ip, forward_clean_args))
1129 r += 2; 1129 r += 2;
1130 } 1130 }
1131 cleanup_forward_3b: 1131cleanup_forward_3b:
1132 if (0 == nortsetup) 1132 if (0 == nortsetup)
1133 { 1133 {
1134 char *const forward_clean_args[] = 1134 char *const forward_clean_args[] =
1135 { 1135 {
1136 "ip", "rule", "del", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL 1136 "ip", "rule", "del", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
1137 }; 1137 };
1138 if (0 != fork_and_exec (sbin_ip, forward_clean_args)) 1138 if (0 != fork_and_exec(sbin_ip, forward_clean_args))
1139 r += 2; 1139 r += 2;
1140 } 1140 }
1141 cleanup_mark_2: 1141cleanup_mark_2:
1142 if (0 == nortsetup) 1142 if (0 == nortsetup)
1143 { 1143 {
1144 char *const mark_clean_args[] = 1144 char *const mark_clean_args[] =
1145 { 1145 {
1146 "ip6tables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", 1146 "ip6tables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
1147 "--dport", DNS_PORT, 1147 "--dport", DNS_PORT,
1148 "!", "-s", "fe80::/10", /* this line excludes link-local traffic */ 1148 "!", "-s", "fe80::/10", /* this line excludes link-local traffic */
1149 "-j", "MARK", "--set-mark", DNS_MARK, NULL 1149 "-j", "MARK", "--set-mark", DNS_MARK, NULL
1150 }; 1150 };
1151 if (0 != fork_and_exec (sbin_ip6tables, mark_clean_args)) 1151 if (0 != fork_and_exec(sbin_ip6tables, mark_clean_args))
1152 r += 4; 1152 r += 4;
1153 } 1153 }
1154 cleanup_mark_2b: 1154cleanup_mark_2b:
1155 if (0 == nortsetup) 1155 if (0 == nortsetup)
1156 { 1156 {
1157 char *const mark_clean_args[] = 1157 char *const mark_clean_args[] =
1158 { 1158 {
1159 "iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", 1159 "iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
1160 "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK, NULL 1160 "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK, NULL
1161 }; 1161 };
1162 if (0 != fork_and_exec (sbin_iptables, mark_clean_args)) 1162 if (0 != fork_and_exec(sbin_iptables, mark_clean_args))
1163 r += 4; 1163 r += 4;
1164 } 1164 }
1165 cleanup_mangle_1: 1165cleanup_mangle_1:
1166 if (0 == nortsetup) 1166 if (0 == nortsetup)
1167 { 1167 {
1168 char *const mangle_clean_args[] = 1168 char *const mangle_clean_args[] =
1169 { 1169 {
1170 "ip6tables", "-m", "owner", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", 1170 "ip6tables", "-m", "owner", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
1171 "--gid-owner", mygid, "--dport", DNS_PORT, "-j", "ACCEPT", 1171 "--gid-owner", mygid, "--dport", DNS_PORT, "-j", "ACCEPT",
1172 NULL 1172 NULL
1173 }; 1173 };
1174 if (0 != fork_and_exec (sbin_ip6tables, mangle_clean_args)) 1174 if (0 != fork_and_exec(sbin_ip6tables, mangle_clean_args))
1175 r += 8; 1175 r += 8;
1176 } 1176 }
1177 cleanup_mangle_1b: 1177cleanup_mangle_1b:
1178 if (0 == nortsetup) 1178 if (0 == nortsetup)
1179 { 1179 {
1180 char *const mangle_clean_args[] = 1180 char *const mangle_clean_args[] =
1181 { 1181 {
1182 "iptables", "-m", "owner", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", 1182 "iptables", "-m", "owner", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
1183 "--gid-owner", mygid, "--dport", DNS_PORT, "-j", "ACCEPT", 1183 "--gid-owner", mygid, "--dport", DNS_PORT, "-j", "ACCEPT",
1184 NULL 1184 NULL
1185 }; 1185 };
1186 if (0 != fork_and_exec (sbin_iptables, mangle_clean_args)) 1186 if (0 != fork_and_exec(sbin_iptables, mangle_clean_args))
1187 r += 8; 1187 r += 8;
1188 } 1188 }
1189 1189
1190 cleanup_rest: 1190cleanup_rest:
1191 /* close virtual interface */ 1191 /* close virtual interface */
1192 (void) close (fd_tun); 1192 (void)close(fd_tun);
1193 /* remove signal handler so we can close the pipes */ 1193 /* remove signal handler so we can close the pipes */
1194 (void) signal (SIGTERM, SIG_IGN); 1194 (void)signal(SIGTERM, SIG_IGN);
1195#if (SIGTERM != GNUNET_TERM_SIG) 1195#if (SIGTERM != GNUNET_TERM_SIG)
1196 (void) signal (GNUNET_TERM_SIG, SIG_IGN); 1196 (void)signal(GNUNET_TERM_SIG, SIG_IGN);
1197#endif 1197#endif
1198 (void) signal (SIGINT, SIG_IGN); 1198 (void)signal(SIGINT, SIG_IGN);
1199 (void) signal (SIGHUP, SIG_IGN); 1199 (void)signal(SIGHUP, SIG_IGN);
1200 (void) close (cpipe[0]); 1200 (void)close(cpipe[0]);
1201 (void) close (cpipe[1]); 1201 (void)close(cpipe[1]);
1202 return r; 1202 return r;
1203} 1203}
1204 1204