ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
(Generate patch)

Comparing gvpe/src/vpn.C (file contents):
Revision 1.38 by pcg, Tue Apr 26 00:55:56 2005 UTC vs.
Revision 1.45 by pcg, Thu Dec 6 00:35:29 2007 UTC

1/* 1/*
2 vpn.C -- handle the protocol, encryption, handshaking etc. 2 vpn.C -- handle the protocol, encryption, handshaking etc.
3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2007 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify 7 GVPE is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
46 46
47vpn network; // THE vpn (bad design...) 47vpn network; // THE vpn (bad design...)
48 48
49///////////////////////////////////////////////////////////////////////////// 49/////////////////////////////////////////////////////////////////////////////
50 50
51static void inline
52set_tos (int fd, int &tos_prev, int tos)
53{
54#if defined(SOL_IP) && defined(IP_TOS)
55 if (tos_prev == tos)
56 return;
57
58 tos_prev = tos;
59 setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos);
60#endif
61}
62
51void 63void
52vpn::script_init_env () 64vpn::script_init_env ()
53{ 65{
54 // the tunnel device mtu should be the physical mtu - overhead 66 // the tunnel device mtu should be the physical mtu - overhead
55 // the tricky part is rounding to the cipher key blocksize 67 // the tricky part is rounding to the cipher key blocksize
75 snprintf (ext, 16, "_%d", (*c)->conf->id); 87 snprintf (ext, 16, "_%d", (*c)->conf->id);
76 (*c)->script_init_env (ext); 88 (*c)->script_init_env (ext);
77 } 89 }
78} 90}
79 91
92inline const char *
80const char *vpn::script_if_init () 93vpn::script_if_init ()
81{ 94{
82 script_init_env (); 95 script_init_env ();
83 96
84 return tap->if_up (); 97 return tap->if_up ();
85} 98}
86 99
100inline const char *
87const char *vpn::script_if_up () 101vpn::script_if_up ()
88{ 102{
89 script_init_env (); 103 script_init_env ();
90 104
91 char *filename; 105 char *filename;
92 asprintf (&filename, 106 asprintf (&filename,
98} 112}
99 113
100int 114int
101vpn::setup () 115vpn::setup ()
102{ 116{
117 ipv4_tos = -1;
103 ipv4_fd = -1; 118 ipv4_fd = -1;
104 119
105 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 120 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
106 { 121 {
107 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 122 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto);
108 123
128 { 143 {
129 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 144 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno));
130 exit (EXIT_FAILURE); 145 exit (EXIT_FAILURE);
131 } 146 }
132 147
133 ipv4_ev_watcher.start (ipv4_fd, EVENT_READ); 148 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
134 } 149 }
135 150
151 udpv4_tos = -1;
136 udpv4_fd = -1; 152 udpv4_fd = -1;
137 153
138 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 154 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
139 { 155 {
140 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 156 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
141 157
167 { 183 {
168 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 184 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno));
169 exit (EXIT_FAILURE); 185 exit (EXIT_FAILURE);
170 } 186 }
171 187
172 udpv4_ev_watcher.start (udpv4_fd, EVENT_READ); 188 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
173 } 189 }
174 190
191 icmpv4_tos = -1;
175 icmpv4_fd = -1; 192 icmpv4_fd = -1;
176 193
177#if ENABLE_ICMP 194#if ENABLE_ICMP
178 if (THISNODE->protocols & PROT_ICMPv4) 195 if (THISNODE->protocols & PROT_ICMPv4)
179 { 196 {
180 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 197 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP);
212 { 229 {
213 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 230 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno));
214 exit (EXIT_FAILURE); 231 exit (EXIT_FAILURE);
215 } 232 }
216 233
217 icmpv4_ev_watcher.start (icmpv4_fd, EVENT_READ); 234 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
218 } 235 }
219#endif 236#endif
220 237
221 tcpv4_fd = -1; 238 tcpv4_fd = -1;
222 239
249 { 266 {
250 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 267 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno));
251 exit (EXIT_FAILURE); 268 exit (EXIT_FAILURE);
252 } 269 }
253 270
254 tcpv4_ev_watcher.start (tcpv4_fd, EVENT_READ); 271 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
255 } 272 }
256#endif 273#endif
274
275 dnsv4_tos = -1;
276 dnsv4_fd = -1;
257 277
258#if ENABLE_DNS 278#if ENABLE_DNS
259 if (THISNODE->protocols & PROT_DNSv4) 279 if (THISNODE->protocols & PROT_DNSv4)
260 { 280 {
261 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 281 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
292 { 312 {
293 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno)); 313 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno));
294 exit (EXIT_FAILURE); 314 exit (EXIT_FAILURE);
295 } 315 }
296 316
297 dnsv4_ev_watcher.start (dnsv4_fd, EVENT_READ); 317 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
298 } 318 }
299#endif 319#endif
300 320
301 ///////////////////////////////////////////////////////////////////////////// 321 /////////////////////////////////////////////////////////////////////////////
302 322
311 exit (EXIT_FAILURE); 331 exit (EXIT_FAILURE);
312 } 332 }
313 333
314 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 334 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
315 335
336 run_script_cb cb;
337 cb.set<vpn, &vpn::script_if_init> (this);
338
316 if (tap->if_up () && 339 if (tap->if_up () &&
317 !run_script (run_script_cb (this, &vpn::script_if_init), true)) 340 !run_script (cb, true))
318 { 341 {
319 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 342 slog (L_ERR, _("interface initialization command '%s' failed, exiting."),
320 tap->if_up ()); 343 tap->if_up ());
321 exit (EXIT_FAILURE); 344 exit (EXIT_FAILURE);
322 } 345 }
323 346
324 if (!run_script (run_script_cb (this, &vpn::script_if_up), true)) 347 cb.set<vpn, &vpn::script_if_up> (this);
348 if (!run_script (cb, true))
325 { 349 {
326 slog (L_ERR, _("if-up command execution failed, exiting.")); 350 slog (L_ERR, _("if-up command execution failed, exiting."));
327 exit (EXIT_FAILURE); 351 exit (EXIT_FAILURE);
328 } 352 }
329 353
330 tap_ev_watcher.start (tap->fd, EVENT_READ); 354 tap_ev_watcher.start (tap->fd, EV_READ);
331 355
332 return 0; 356 return 0;
333} 357}
334 358
335bool 359bool
336vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 360vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
337{ 361{
338#if defined(SOL_IP) && defined(IP_TOS) 362 set_tos (ipv4_fd, ipv4_tos, tos);
339 setsockopt (ipv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
340#endif
341 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 363 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
342 364
343 return true; 365 return true;
344} 366}
345 367
368 390
369#if ENABLE_ICMP 391#if ENABLE_ICMP
370bool 392bool
371vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 393vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
372{ 394{
373#if defined(SOL_IP) && defined(IP_TOS)
374 setsockopt (icmpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
375#endif
376
377 pkt->unshift_hdr (4); 395 pkt->unshift_hdr (4);
378 396
379 icmp_header *hdr = (icmp_header *)&((*pkt)[0]); 397 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
380 hdr->type = ::conf.icmp_type; 398 hdr->type = ::conf.icmp_type;
381 hdr->code = 255; 399 hdr->code = 255;
382 hdr->checksum = 0; 400 hdr->checksum = 0;
383 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 401 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
384 402
403 set_tos (icmpv4_fd, icmpv4_tos, tos);
385 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 404 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
386 405
387 return true; 406 return true;
388} 407}
389#endif 408#endif
390 409
391bool 410bool
392vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 411vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
393{ 412{
394#if defined(SOL_IP) && defined(IP_TOS) 413 set_tos (udpv4_fd, udpv4_tos, tos);
395 setsockopt (udpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
396#endif
397 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 414 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
398 415
399 return true; 416 return true;
400} 417}
401 418
463{ 480{
464 switch (si.prot) 481 switch (si.prot)
465 { 482 {
466 case PROT_IPv4: 483 case PROT_IPv4:
467 return send_ipv4_packet (pkt, si, tos); 484 return send_ipv4_packet (pkt, si, tos);
485
468 case PROT_UDPv4: 486 case PROT_UDPv4:
469 return send_udpv4_packet (pkt, si, tos); 487 return send_udpv4_packet (pkt, si, tos);
488
470#if ENABLE_TCP 489#if ENABLE_TCP
471 case PROT_TCPv4: 490 case PROT_TCPv4:
472 return send_tcpv4_packet (pkt, si, tos); 491 return send_tcpv4_packet (pkt, si, tos);
473#endif 492#endif
474#if ENABLE_ICMP 493#if ENABLE_ICMP
477#endif 496#endif
478#if ENABLE_DNS 497#if ENABLE_DNS
479 case PROT_DNSv4: 498 case PROT_DNSv4:
480 return send_dnsv4_packet (pkt, si, tos); 499 return send_dnsv4_packet (pkt, si, tos);
481#endif 500#endif
482
483 default: 501 default:
484 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); 502 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si);
485 } 503 }
486 504
487 return false; 505 return false;
488} 506}
489 507
490void 508inline void
491vpn::ipv4_ev (io_watcher &w, short revents) 509vpn::ipv4_ev (ev::io &w, int revents)
492{ 510{
493 if (revents & EVENT_READ) 511 if (revents & EV_READ)
494 { 512 {
495 vpn_packet *pkt = new vpn_packet; 513 vpn_packet *pkt = new vpn_packet;
496 struct sockaddr_in sa; 514 struct sockaddr_in sa;
497 socklen_t sa_len = sizeof (sa); 515 socklen_t sa_len = sizeof (sa);
498 int len; 516 int len;
526 exit (EXIT_FAILURE); 544 exit (EXIT_FAILURE);
527 } 545 }
528} 546}
529 547
530#if ENABLE_ICMP 548#if ENABLE_ICMP
531void 549inline void
532vpn::icmpv4_ev (io_watcher &w, short revents) 550vpn::icmpv4_ev (ev::io &w, int revents)
533{ 551{
534 if (revents & EVENT_READ) 552 if (revents & EV_READ)
535 { 553 {
536 vpn_packet *pkt = new vpn_packet; 554 vpn_packet *pkt = new vpn_packet;
537 struct sockaddr_in sa; 555 struct sockaddr_in sa;
538 socklen_t sa_len = sizeof (sa); 556 socklen_t sa_len = sizeof (sa);
539 int len; 557 int len;
574 exit (EXIT_FAILURE); 592 exit (EXIT_FAILURE);
575 } 593 }
576} 594}
577#endif 595#endif
578 596
579void 597inline void
580vpn::udpv4_ev (io_watcher &w, short revents) 598vpn::udpv4_ev (ev::io &w, int revents)
581{ 599{
582 if (revents & EVENT_READ) 600 if (revents & EV_READ)
583 { 601 {
584 vpn_packet *pkt = new vpn_packet; 602 vpn_packet *pkt = new vpn_packet;
585 struct sockaddr_in sa; 603 struct sockaddr_in sa;
586 socklen_t sa_len = sizeof (sa); 604 socklen_t sa_len = sizeof (sa);
587 int len; 605 int len;
611 revents); 629 revents);
612 exit (EXIT_FAILURE); 630 exit (EXIT_FAILURE);
613 } 631 }
614} 632}
615 633
616void 634inline void
617vpn::tap_ev (io_watcher &w, short revents) 635vpn::tap_ev (ev::io &w, int revents)
618{ 636{
619 if (revents & EVENT_READ) 637 if (revents & EV_READ)
620 { 638 {
621 /* process data */ 639 /* process data */
622 tap_packet *pkt; 640 tap_packet *pkt;
623 641
624 pkt = tap->recv (); 642 pkt = tap->recv ();
653 } 671 }
654 else 672 else
655 abort (); 673 abort ();
656} 674}
657 675
658void 676inline void
659vpn::event_cb (time_watcher &w) 677vpn::event_cb (ev::timer &w, int)
660{ 678{
661 if (events) 679 if (events)
662 { 680 {
663 if (events & EVENT_SHUTDOWN) 681 if (events & EVENT_SHUTDOWN)
664 { 682 {
755} 773}
756 774
757void 775void
758vpn::dump_status () 776vpn::dump_status ()
759{ 777{
760 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)NOW); 778 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
761 779
762 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 780 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
763 (*c)->dump_status (); 781 (*c)->dump_status ();
764 782
765 slog (L_NOTICE, _("END status dump")); 783 slog (L_NOTICE, _("END status dump"));
766} 784}
767 785
768vpn::vpn (void) 786vpn::vpn (void)
787{
769: event (this, &vpn::event_cb) 788 event .set<vpn, &vpn::event_cb > (this);
770, udpv4_ev_watcher (this, &vpn::udpv4_ev) 789 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
771, ipv4_ev_watcher (this, &vpn::ipv4_ev) 790 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
772#if ENABLE_TCP 791#if ENABLE_TCP
773, tcpv4_ev_watcher (this, &vpn::tcpv4_ev) 792 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
774#endif 793#endif
775#if ENABLE_ICMP 794#if ENABLE_ICMP
776, icmpv4_ev_watcher(this, &vpn::icmpv4_ev) 795 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
777#endif 796#endif
778#if ENABLE_DNS 797#if ENABLE_DNS
779, dnsv4_ev_watcher (this, &vpn::dnsv4_ev) 798 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
780#endif 799#endif
781, tap_ev_watcher (this, &vpn::tap_ev) 800 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
782{
783} 801}
784 802
785vpn::~vpn () 803vpn::~vpn ()
786{ 804{
787} 805}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines