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.34 by pcg, Sat Mar 26 03:16:24 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
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with gvpe; if not, write to the Free Software 18 along with gvpe; if not, write to the Free Software
19 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/ 20*/
21 21
22#include "config.h" 22#include "config.h"
23 23
24#include <list> 24#include <list>
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
109 if (ipv4_fd < 0) 124 if (ipv4_fd < 0)
110 return -1; 125 return -1;
111 126
112 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK); 127 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
128 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
113 129
114#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 130#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
115 // this I really consider a linux bug. I am neither connected 131 // this I really consider a linux bug. I am neither connected
116 // nor do I fragment myself. Linux still sets DF and doesn't 132 // nor do I fragment myself. Linux still sets DF and doesn't
117 // fragment for me sometimes. 133 // fragment for me sometimes.
127 { 143 {
128 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));
129 exit (EXIT_FAILURE); 145 exit (EXIT_FAILURE);
130 } 146 }
131 147
132 ipv4_ev_watcher.start (ipv4_fd, EVENT_READ); 148 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
133 } 149 }
134 150
151 udpv4_tos = -1;
135 udpv4_fd = -1; 152 udpv4_fd = -1;
136 153
137 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 154 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
138 { 155 {
139 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 156 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
140 157
141 if (udpv4_fd < 0) 158 if (udpv4_fd < 0)
142 return -1; 159 return -1;
143 160
144 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK); 161 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
162 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
145 163
146 // standard daemon practise... 164 // standard daemon practise...
147 { 165 {
148 int oval = 1; 166 int oval = 1;
149 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 167 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
165 { 183 {
166 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));
167 exit (EXIT_FAILURE); 185 exit (EXIT_FAILURE);
168 } 186 }
169 187
170 udpv4_ev_watcher.start (udpv4_fd, EVENT_READ); 188 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
171 } 189 }
172 190
191 icmpv4_tos = -1;
173 icmpv4_fd = -1; 192 icmpv4_fd = -1;
174 193
175#if ENABLE_ICMP 194#if ENABLE_ICMP
176 if (THISNODE->protocols & PROT_ICMPv4) 195 if (THISNODE->protocols & PROT_ICMPv4)
177 { 196 {
178 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 197 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP);
179 198
180 if (icmpv4_fd < 0) 199 if (icmpv4_fd < 0)
181 return -1; 200 return -1;
182 201
183 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK); 202 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
203 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
184 204
185#ifdef ICMP_FILTER 205#ifdef ICMP_FILTER
186 { 206 {
187 icmp_filter oval; 207 icmp_filter oval;
188 oval.data = 0xffffffff; 208 oval.data = 0xffffffff;
197 // this I really consider a linux bug. I am neither connected 217 // this I really consider a linux bug. I am neither connected
198 // nor do I fragment myself. Linux still sets DF and doesn't 218 // nor do I fragment myself. Linux still sets DF and doesn't
199 // fragment for me sometimes. 219 // fragment for me sometimes.
200 { 220 {
201 int oval = IP_PMTUDISC_DONT; 221 int oval = IP_PMTUDISC_DONT;
202 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 222 setsockopt (icmpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
203 } 223 }
204#endif 224#endif
205 225
206 sockinfo si (THISNODE, PROT_ICMPv4); 226 sockinfo si (THISNODE, PROT_ICMPv4);
207 227
209 { 229 {
210 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));
211 exit (EXIT_FAILURE); 231 exit (EXIT_FAILURE);
212 } 232 }
213 233
214 icmpv4_ev_watcher.start (icmpv4_fd, EVENT_READ); 234 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
215 } 235 }
216#endif 236#endif
217 237
218 tcpv4_fd = -1; 238 tcpv4_fd = -1;
219 239
224 244
225 if (tcpv4_fd < 0) 245 if (tcpv4_fd < 0)
226 return -1; 246 return -1;
227 247
228 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK); 248 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
249 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
229 250
230 // standard daemon practise... 251 // standard daemon practise...
231 { 252 {
232 int oval = 1; 253 int oval = 1;
233 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 254 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
245 { 266 {
246 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));
247 exit (EXIT_FAILURE); 268 exit (EXIT_FAILURE);
248 } 269 }
249 270
250 tcpv4_ev_watcher.start (tcpv4_fd, EVENT_READ); 271 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
251 } 272 }
252#endif 273#endif
274
275 dnsv4_tos = -1;
276 dnsv4_fd = -1;
253 277
254#if ENABLE_DNS 278#if ENABLE_DNS
255 if (THISNODE->protocols & PROT_DNSv4) 279 if (THISNODE->protocols & PROT_DNSv4)
256 { 280 {
257 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);
259 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 283 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
260 284
261 if (dnsv4_fd < 0) 285 if (dnsv4_fd < 0)
262 return -1; 286 return -1;
263 287
288 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
289 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
290
264#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 291# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
265 // this I really consider a linux bug. I am neither connected 292 // this I really consider a linux bug. I am neither connected
266 // nor do I fragment myself. Linux still sets DF and doesn't 293 // nor do I fragment myself. Linux still sets DF and doesn't
267 // fragment for me sometimes. 294 // fragment for me sometimes.
268 { 295 {
269 int oval = IP_PMTUDISC_DONT; 296 int oval = IP_PMTUDISC_DONT;
270 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 297 setsockopt (dnsv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
271 } 298 }
272#endif 299# endif
273 300
274 // standard daemon practise... 301 // standard daemon practise...
275 { 302 {
276 int oval = 1; 303 int oval = 1;
277 setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 304 setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
285 { 312 {
286 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));
287 exit (EXIT_FAILURE); 314 exit (EXIT_FAILURE);
288 } 315 }
289 316
290 dnsv4_ev_watcher.start (dnsv4_fd, EVENT_READ); 317 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
291 } 318 }
292#endif 319#endif
293 320
294 ///////////////////////////////////////////////////////////////////////////// 321 /////////////////////////////////////////////////////////////////////////////
295 322
302 { 329 {
303 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 330 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname);
304 exit (EXIT_FAILURE); 331 exit (EXIT_FAILURE);
305 } 332 }
306 333
334 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
335
336 run_script_cb cb;
337 cb.set<vpn, &vpn::script_if_init> (this);
338
307 if (tap->if_up () && 339 if (tap->if_up () &&
308 !run_script (run_script_cb (this, &vpn::script_if_init), true)) 340 !run_script (cb, true))
309 { 341 {
310 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 342 slog (L_ERR, _("interface initialization command '%s' failed, exiting."),
311 tap->if_up ()); 343 tap->if_up ());
312 exit (EXIT_FAILURE); 344 exit (EXIT_FAILURE);
313 } 345 }
314 346
315 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))
316 { 349 {
317 slog (L_ERR, _("if-up command execution failed, exiting.")); 350 slog (L_ERR, _("if-up command execution failed, exiting."));
318 exit (EXIT_FAILURE); 351 exit (EXIT_FAILURE);
319 } 352 }
320 353
321 tap_ev_watcher.start (tap->fd, EVENT_READ); 354 tap_ev_watcher.start (tap->fd, EV_READ);
322 355
323 return 0; 356 return 0;
324} 357}
325 358
326bool 359bool
327vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 360vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
328{ 361{
329#if defined(SOL_IP) && defined(IP_TOS) 362 set_tos (ipv4_fd, ipv4_tos, tos);
330 setsockopt (ipv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
331#endif
332 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 ());
333 364
334 return true; 365 return true;
335} 366}
336 367
359 390
360#if ENABLE_ICMP 391#if ENABLE_ICMP
361bool 392bool
362vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 393vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
363{ 394{
364#if defined(SOL_IP) && defined(IP_TOS)
365 setsockopt (icmpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
366#endif
367
368 pkt->unshift_hdr (4); 395 pkt->unshift_hdr (4);
369 396
370 icmp_header *hdr = (icmp_header *)&((*pkt)[0]); 397 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
371 hdr->type = ::conf.icmp_type; 398 hdr->type = ::conf.icmp_type;
372 hdr->code = 255; 399 hdr->code = 255;
373 hdr->checksum = 0; 400 hdr->checksum = 0;
374 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 401 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
375 402
403 set_tos (icmpv4_fd, icmpv4_tos, tos);
376 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 ());
377 405
378 return true; 406 return true;
379} 407}
380#endif 408#endif
381 409
382bool 410bool
383vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 411vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
384{ 412{
385#if defined(SOL_IP) && defined(IP_TOS) 413 set_tos (udpv4_fd, udpv4_tos, tos);
386 setsockopt (udpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
387#endif
388 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 ());
389 415
390 return true; 416 return true;
391} 417}
392 418
454{ 480{
455 switch (si.prot) 481 switch (si.prot)
456 { 482 {
457 case PROT_IPv4: 483 case PROT_IPv4:
458 return send_ipv4_packet (pkt, si, tos); 484 return send_ipv4_packet (pkt, si, tos);
485
459 case PROT_UDPv4: 486 case PROT_UDPv4:
460 return send_udpv4_packet (pkt, si, tos); 487 return send_udpv4_packet (pkt, si, tos);
488
461#if ENABLE_TCP 489#if ENABLE_TCP
462 case PROT_TCPv4: 490 case PROT_TCPv4:
463 return send_tcpv4_packet (pkt, si, tos); 491 return send_tcpv4_packet (pkt, si, tos);
464#endif 492#endif
465#if ENABLE_ICMP 493#if ENABLE_ICMP
468#endif 496#endif
469#if ENABLE_DNS 497#if ENABLE_DNS
470 case PROT_DNSv4: 498 case PROT_DNSv4:
471 return send_dnsv4_packet (pkt, si, tos); 499 return send_dnsv4_packet (pkt, si, tos);
472#endif 500#endif
473
474 default: 501 default:
475 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);
476 } 503 }
477 504
478 return false; 505 return false;
479} 506}
480 507
481void 508inline void
482vpn::ipv4_ev (io_watcher &w, short revents) 509vpn::ipv4_ev (ev::io &w, int revents)
483{ 510{
484 if (revents & EVENT_READ) 511 if (revents & EV_READ)
485 { 512 {
486 vpn_packet *pkt = new vpn_packet; 513 vpn_packet *pkt = new vpn_packet;
487 struct sockaddr_in sa; 514 struct sockaddr_in sa;
488 socklen_t sa_len = sizeof (sa); 515 socklen_t sa_len = sizeof (sa);
489 int len; 516 int len;
517 exit (EXIT_FAILURE); 544 exit (EXIT_FAILURE);
518 } 545 }
519} 546}
520 547
521#if ENABLE_ICMP 548#if ENABLE_ICMP
522void 549inline void
523vpn::icmpv4_ev (io_watcher &w, short revents) 550vpn::icmpv4_ev (ev::io &w, int revents)
524{ 551{
525 if (revents & EVENT_READ) 552 if (revents & EV_READ)
526 { 553 {
527 vpn_packet *pkt = new vpn_packet; 554 vpn_packet *pkt = new vpn_packet;
528 struct sockaddr_in sa; 555 struct sockaddr_in sa;
529 socklen_t sa_len = sizeof (sa); 556 socklen_t sa_len = sizeof (sa);
530 int len; 557 int len;
565 exit (EXIT_FAILURE); 592 exit (EXIT_FAILURE);
566 } 593 }
567} 594}
568#endif 595#endif
569 596
570void 597inline void
571vpn::udpv4_ev (io_watcher &w, short revents) 598vpn::udpv4_ev (ev::io &w, int revents)
572{ 599{
573 if (revents & EVENT_READ) 600 if (revents & EV_READ)
574 { 601 {
575 vpn_packet *pkt = new vpn_packet; 602 vpn_packet *pkt = new vpn_packet;
576 struct sockaddr_in sa; 603 struct sockaddr_in sa;
577 socklen_t sa_len = sizeof (sa); 604 socklen_t sa_len = sizeof (sa);
578 int len; 605 int len;
602 revents); 629 revents);
603 exit (EXIT_FAILURE); 630 exit (EXIT_FAILURE);
604 } 631 }
605} 632}
606 633
607void 634inline void
608vpn::tap_ev (io_watcher &w, short revents) 635vpn::tap_ev (ev::io &w, int revents)
609{ 636{
610 if (revents & EVENT_READ) 637 if (revents & EV_READ)
611 { 638 {
612 /* process data */ 639 /* process data */
613 tap_packet *pkt; 640 tap_packet *pkt;
614 641
615 pkt = tap->recv (); 642 pkt = tap->recv ();
644 } 671 }
645 else 672 else
646 abort (); 673 abort ();
647} 674}
648 675
649void 676inline void
650vpn::event_cb (time_watcher &w) 677vpn::event_cb (ev::timer &w, int)
651{ 678{
652 if (events) 679 if (events)
653 { 680 {
654 if (events & EVENT_SHUTDOWN) 681 if (events & EVENT_SHUTDOWN)
655 { 682 {
746} 773}
747 774
748void 775void
749vpn::dump_status () 776vpn::dump_status ()
750{ 777{
751 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)NOW); 778 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
752 779
753 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 780 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
754 (*c)->dump_status (); 781 (*c)->dump_status ();
755 782
756 slog (L_NOTICE, _("END status dump")); 783 slog (L_NOTICE, _("END status dump"));
757} 784}
758 785
759vpn::vpn (void) 786vpn::vpn (void)
787{
760: event (this, &vpn::event_cb) 788 event .set<vpn, &vpn::event_cb > (this);
761, udpv4_ev_watcher (this, &vpn::udpv4_ev) 789 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
762, ipv4_ev_watcher (this, &vpn::ipv4_ev) 790 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
763#if ENABLE_TCP 791#if ENABLE_TCP
764, tcpv4_ev_watcher (this, &vpn::tcpv4_ev) 792 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
765#endif 793#endif
766#if ENABLE_ICMP 794#if ENABLE_ICMP
767, icmpv4_ev_watcher(this, &vpn::icmpv4_ev) 795 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
768#endif 796#endif
769#if ENABLE_DNS 797#if ENABLE_DNS
770, dnsv4_ev_watcher (this, &vpn::dnsv4_ev) 798 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
771#endif 799#endif
772, tap_ev_watcher (this, &vpn::tap_ev) 800 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
773{
774} 801}
775 802
776vpn::~vpn () 803vpn::~vpn ()
777{ 804{
778} 805}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines