1 | /* |
1 | /* |
2 | vpn.C -- handle the protocol, encryption, handshaking etc. |
2 | vpn.C -- handle the protocol, encryption, handshaking etc. |
3 | Copyright (C) 2003 Marc Lehmann <pcg@goof.com> |
3 | Copyright (C) 2003-2004 Marc Lehmann <pcg@goof.com> |
4 | |
4 | |
5 | This program is free software; you can redistribute it and/or modify |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by |
6 | it under the terms of the GNU General Public License as published by |
7 | the Free Software Foundation; either version 2 of the License, or |
7 | the Free Software Foundation; either version 2 of the License, or |
8 | (at your option) any later version. |
8 | (at your option) any later version. |
… | |
… | |
101 | { |
101 | { |
102 | slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); |
102 | slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); |
103 | exit (1); |
103 | exit (1); |
104 | } |
104 | } |
105 | |
105 | |
106 | ipv4_ev_watcher.start (ipv4_fd, POLLIN); |
106 | ipv4_ev_watcher.start (ipv4_fd, EVENT_READ); |
107 | } |
107 | } |
108 | |
108 | |
109 | udpv4_fd = -1; |
109 | udpv4_fd = -1; |
110 | |
110 | |
111 | if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) |
111 | if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) |
… | |
… | |
139 | { |
139 | { |
140 | slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); |
140 | slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); |
141 | exit (1); |
141 | exit (1); |
142 | } |
142 | } |
143 | |
143 | |
144 | udpv4_ev_watcher.start (udpv4_fd, POLLIN); |
144 | udpv4_ev_watcher.start (udpv4_fd, EVENT_READ); |
145 | } |
145 | } |
146 | |
146 | |
147 | icmpv4_fd = -1; |
147 | icmpv4_fd = -1; |
148 | |
148 | |
149 | #if ENABLE_ICMP |
149 | #if ENABLE_ICMP |
… | |
… | |
183 | { |
183 | { |
184 | slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); |
184 | slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); |
185 | exit (1); |
185 | exit (1); |
186 | } |
186 | } |
187 | |
187 | |
188 | icmpv4_ev_watcher.start (icmpv4_fd, POLLIN); |
188 | icmpv4_ev_watcher.start (icmpv4_fd, EVENT_READ); |
189 | } |
189 | } |
190 | #endif |
190 | #endif |
191 | |
191 | |
192 | tcpv4_fd = -1; |
192 | tcpv4_fd = -1; |
193 | |
193 | |
… | |
… | |
219 | { |
219 | { |
220 | slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); |
220 | slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); |
221 | exit (1); |
221 | exit (1); |
222 | } |
222 | } |
223 | |
223 | |
224 | tcpv4_ev_watcher.start (tcpv4_fd, POLLIN); |
224 | tcpv4_ev_watcher.start (tcpv4_fd, EVENT_READ); |
225 | } |
225 | } |
226 | #endif |
226 | #endif |
227 | |
227 | |
228 | tap = new tap_device (); |
228 | tap = new tap_device (); |
229 | if (!tap) //D this, of course, never catches |
229 | if (!tap) //D this, of course, never catches |
… | |
… | |
232 | exit (1); |
232 | exit (1); |
233 | } |
233 | } |
234 | |
234 | |
235 | run_script (run_script_cb (this, &vpn::script_if_up), true); |
235 | run_script (run_script_cb (this, &vpn::script_if_up), true); |
236 | |
236 | |
237 | tap_ev_watcher.start (tap->fd, POLLIN); |
237 | tap_ev_watcher.start (tap->fd, EVENT_READ); |
238 | |
238 | |
239 | reconnect_all (); |
239 | reconnect_all (); |
240 | |
240 | |
241 | return 0; |
241 | return 0; |
242 | } |
242 | } |
… | |
… | |
396 | } |
396 | } |
397 | |
397 | |
398 | void |
398 | void |
399 | vpn::ipv4_ev (io_watcher &w, short revents) |
399 | vpn::ipv4_ev (io_watcher &w, short revents) |
400 | { |
400 | { |
401 | if (revents & (POLLIN | POLLERR)) |
401 | if (revents & EVENT_READ) |
402 | { |
402 | { |
403 | vpn_packet *pkt = new vpn_packet; |
403 | vpn_packet *pkt = new vpn_packet; |
404 | struct sockaddr_in sa; |
404 | struct sockaddr_in sa; |
405 | socklen_t sa_len = sizeof (sa); |
405 | socklen_t sa_len = sizeof (sa); |
406 | int len; |
406 | int len; |
… | |
… | |
425 | slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); |
425 | slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); |
426 | } |
426 | } |
427 | |
427 | |
428 | delete pkt; |
428 | delete pkt; |
429 | } |
429 | } |
430 | else if (revents & POLLHUP) |
|
|
431 | { |
|
|
432 | // this cannot ;) happen on udp sockets |
|
|
433 | slog (L_ERR, _("FATAL: POLLHUP on ipv4 fd, terminating.")); |
|
|
434 | exit (1); |
|
|
435 | } |
|
|
436 | else |
430 | else |
437 | { |
431 | { |
438 | slog (L_ERR, |
432 | slog (L_ERR, |
439 | _("FATAL: unknown revents %08x in socket, terminating\n"), |
433 | _("FATAL: unknown revents %08x in socket, terminating\n"), |
440 | revents); |
434 | revents); |
… | |
… | |
444 | |
438 | |
445 | #if ENABLE_ICMP |
439 | #if ENABLE_ICMP |
446 | void |
440 | void |
447 | vpn::icmpv4_ev (io_watcher &w, short revents) |
441 | vpn::icmpv4_ev (io_watcher &w, short revents) |
448 | { |
442 | { |
449 | if (revents & (POLLIN | POLLERR)) |
443 | if (revents & EVENT_READ) |
450 | { |
444 | { |
451 | vpn_packet *pkt = new vpn_packet; |
445 | vpn_packet *pkt = new vpn_packet; |
452 | struct sockaddr_in sa; |
446 | struct sockaddr_in sa; |
453 | socklen_t sa_len = sizeof (sa); |
447 | socklen_t sa_len = sizeof (sa); |
454 | int len; |
448 | int len; |
… | |
… | |
479 | slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); |
473 | slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); |
480 | } |
474 | } |
481 | |
475 | |
482 | delete pkt; |
476 | delete pkt; |
483 | } |
477 | } |
484 | else if (revents & POLLHUP) |
|
|
485 | { |
|
|
486 | // this cannot ;) happen on udp sockets |
|
|
487 | slog (L_ERR, _("FATAL: POLLHUP on icmpv4 fd, terminating.")); |
|
|
488 | exit (1); |
|
|
489 | } |
|
|
490 | else |
478 | else |
491 | { |
479 | { |
492 | slog (L_ERR, |
480 | slog (L_ERR, |
493 | _("FATAL: unknown revents %08x in socket, terminating\n"), |
481 | _("FATAL: unknown revents %08x in socket, terminating\n"), |
494 | revents); |
482 | revents); |
… | |
… | |
498 | #endif |
486 | #endif |
499 | |
487 | |
500 | void |
488 | void |
501 | vpn::udpv4_ev (io_watcher &w, short revents) |
489 | vpn::udpv4_ev (io_watcher &w, short revents) |
502 | { |
490 | { |
503 | if (revents & (POLLIN | POLLERR)) |
491 | if (revents & EVENT_READ) |
504 | { |
492 | { |
505 | vpn_packet *pkt = new vpn_packet; |
493 | vpn_packet *pkt = new vpn_packet; |
506 | struct sockaddr_in sa; |
494 | struct sockaddr_in sa; |
507 | socklen_t sa_len = sizeof (sa); |
495 | socklen_t sa_len = sizeof (sa); |
508 | int len; |
496 | int len; |
… | |
… | |
523 | slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); |
511 | slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); |
524 | } |
512 | } |
525 | |
513 | |
526 | delete pkt; |
514 | delete pkt; |
527 | } |
515 | } |
528 | else if (revents & POLLHUP) |
|
|
529 | { |
|
|
530 | // this cannot ;) happen on udp sockets |
|
|
531 | slog (L_ERR, _("FATAL: POLLHUP on udp v4 fd, terminating.")); |
|
|
532 | exit (1); |
|
|
533 | } |
|
|
534 | else |
516 | else |
535 | { |
517 | { |
536 | slog (L_ERR, |
518 | slog (L_ERR, |
537 | _("FATAL: unknown revents %08x in socket, terminating\n"), |
519 | _("FATAL: unknown revents %08x in socket, terminating\n"), |
538 | revents); |
520 | revents); |
… | |
… | |
541 | } |
523 | } |
542 | |
524 | |
543 | void |
525 | void |
544 | vpn::tap_ev (io_watcher &w, short revents) |
526 | vpn::tap_ev (io_watcher &w, short revents) |
545 | { |
527 | { |
546 | if (revents & POLLIN) |
528 | if (revents & EVENT_READ) |
547 | { |
529 | { |
548 | /* process data */ |
530 | /* process data */ |
549 | tap_packet *pkt; |
531 | tap_packet *pkt; |
550 | |
532 | |
551 | pkt = tap->recv (); |
533 | pkt = tap->recv (); |
… | |
… | |
576 | inject_data_packet (pkt, dst); |
558 | inject_data_packet (pkt, dst); |
577 | } |
559 | } |
578 | |
560 | |
579 | delete pkt; |
561 | delete pkt; |
580 | } |
562 | } |
581 | else if (revents & (POLLHUP | POLLERR)) |
|
|
582 | { |
|
|
583 | slog (L_ERR, _("FATAL: POLLHUP or POLLERR on network device fd, terminating.")); |
|
|
584 | exit (1); |
|
|
585 | } |
|
|
586 | else |
563 | else |
587 | abort (); |
564 | abort (); |
588 | } |
565 | } |
589 | |
566 | |
590 | void |
567 | void |
… | |
… | |
595 | if (events & EVENT_SHUTDOWN) |
572 | if (events & EVENT_SHUTDOWN) |
596 | { |
573 | { |
597 | slog (L_INFO, _("preparing shutdown...")); |
574 | slog (L_INFO, _("preparing shutdown...")); |
598 | |
575 | |
599 | shutdown_all (); |
576 | shutdown_all (); |
600 | |
|
|
601 | remove_pid (pidfilename); |
577 | remove_pid (pidfilename); |
602 | |
|
|
603 | slog (L_INFO, _("terminating")); |
578 | slog (L_INFO, _("terminating")); |
604 | |
|
|
605 | exit (0); |
579 | exit (0); |
606 | } |
580 | } |
607 | |
581 | |
608 | if (events & EVENT_RECONNECT) |
582 | if (events & EVENT_RECONNECT) |
609 | { |
583 | { |
… | |
… | |
612 | reconnect_all (); |
586 | reconnect_all (); |
613 | } |
587 | } |
614 | |
588 | |
615 | events = 0; |
589 | events = 0; |
616 | } |
590 | } |
617 | |
|
|
618 | w.at = TSTAMP_CANCEL; |
|
|
619 | } |
591 | } |
620 | |
592 | |
621 | void |
593 | void |
622 | vpn::shutdown_all () |
594 | vpn::shutdown_all () |
623 | { |
595 | { |