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.51 by pcg, Sun Aug 10 14:48:57 2008 UTC vs.
Revision 1.62 by root, Sat Dec 17 22:05:34 2011 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-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2010,2011 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 it 7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
120 120
121 return filename; 121 return filename;
122} 122}
123 123
124int 124int
125vpn::setup_socket (u8 prot, int family, int type, int proto)
126{
127 int fd = socket (family, type, proto);
128
129 if (fd < 0)
130 {
131 slog (L_ERR, _("unable to create %s socket: %s."), strprotocol (prot), strerror (errno));
132 return fd;
133 }
134
135 fcntl (fd, F_SETFL, O_NONBLOCK);
136 fcntl (fd, F_SETFD, FD_CLOEXEC);
137
138#ifdef SO_MARK
139 if (::conf.nfmark)
140 if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark))
141 slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno));
142#endif
143
144 return fd;
145}
146
147int
125vpn::setup () 148vpn::setup ()
126{ 149{
127 int success = 0; 150 int success = 0;
128 151
152#if 1//D2
129 ipv4_tos = -1; 153 ipv42_tos = -1;
130 ipv4_fd = -1; 154 ipv42_fd = -1;
131 155
132 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 156 if (THISNODE->protocols & PROT_IPv42 && ::conf.ip_proto)
133 { 157 {
134 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 158 ipv42_fd = setup_socket (PROT_IPv42, PF_INET, SOCK_RAW, ::conf.ip2_proto);
135 159
136 if (ipv4_fd < 0) 160 if (ipv42_fd < 0)
137 return -1; 161 return -1;
138
139 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
140 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
141 162
142#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 163#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
143 // this I really consider a linux bug. I am neither connected 164 // this I really consider a linux bug. I am neither connected
144 // nor do I fragment myself. Linux still sets DF and doesn't 165 // nor do I fragment myself. Linux still sets DF and doesn't
145 // fragment for me sometimes. 166 // fragment for me sometimes.
146 { 167 {
147 int oval = IP_PMTUDISC_DONT; 168 int oval = IP_PMTUDISC_DONT;
148 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 169 setsockopt (ipv42_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
149 } 170 }
150#endif 171#endif
151 172
152 sockinfo si (THISNODE, PROT_IPv4); 173 sockinfo si (THISNODE, PROT_IPv42);
153 174
154 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 175 if (bind (ipv42_fd, si.sav4 (), si.salenv4 ()))
155 { 176 {
156 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno)); 177 slog (L_ERR, _("can't bind ipv42 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
157 exit (EXIT_FAILURE); 178 return -1;
158 } 179 }
159 180
160 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 181 ipv42_ev_watcher.start (ipv42_fd, EV_READ);
161 ++success; 182 ++success;
162 } 183 }
163 else 184 else
164 THISNODE->protocols &= ~PROT_IPv4; 185 THISNODE->protocols &= ~PROT_IPv42;
186#endif
165 187
166 udpv4_tos = -1; 188 ipv4_tos = -1;
167 udpv4_fd = -1; 189 ipv4_fd = -1;
168 190
169 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 191 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
170 { 192 {
171 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 193 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
172 194
173 if (udpv4_fd < 0) 195 if (ipv4_fd < 0)
174 return -1; 196 return -1;
175
176 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
177 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
178
179 // standard daemon practise...
180 {
181 int oval = 1;
182 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
183 }
184 197
185#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 198#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
186 // this I really consider a linux bug. I am neither connected 199 // this I really consider a linux bug. I am neither connected
187 // nor do I fragment myself. Linux still sets DF and doesn't 200 // nor do I fragment myself. Linux still sets DF and doesn't
188 // fragment for me sometimes. 201 // fragment for me sometimes.
189 { 202 {
190 int oval = IP_PMTUDISC_DONT; 203 int oval = IP_PMTUDISC_DONT;
204 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
205 }
206#endif
207
208 sockinfo si (THISNODE, PROT_IPv4);
209
210 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
211 {
212 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
213 return -1;
214 }
215
216 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
217 ++success;
218 }
219 else
220 THISNODE->protocols &= ~PROT_IPv4;
221
222 udpv4_tos = -1;
223 udpv4_fd = -1;
224
225 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
226 {
227 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
228
229 if (udpv4_fd < 0)
230 return -1;
231
232 // standard daemon practise...
233 {
234 int oval = 1;
235 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
236 }
237
238#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
239 // this I really consider a linux bug. I am neither connected
240 // nor do I fragment myself. Linux still sets DF and doesn't
241 // fragment for me sometimes.
242 {
243 int oval = IP_PMTUDISC_DONT;
191 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 244 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
192 } 245 }
193#endif 246#endif
194 247
195 sockinfo si (THISNODE, PROT_UDPv4); 248 sockinfo si (THISNODE, PROT_UDPv4);
196 249
197 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 250 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
198 { 251 {
199 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 252 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
200 exit (EXIT_FAILURE); 253 return -1;
201 } 254 }
202 255
203 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 256 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
204 ++success; 257 ++success;
205 } 258 }
210 icmpv4_fd = -1; 263 icmpv4_fd = -1;
211 264
212#if ENABLE_ICMP 265#if ENABLE_ICMP
213 if (THISNODE->protocols & PROT_ICMPv4) 266 if (THISNODE->protocols & PROT_ICMPv4)
214 { 267 {
215 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 268 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
216 269
217 if (icmpv4_fd < 0) 270 if (icmpv4_fd < 0)
218 return -1; 271 return -1;
219
220 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
221 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
222 272
223#ifdef ICMP_FILTER 273#ifdef ICMP_FILTER
224 { 274 {
225 icmp_filter oval; 275 icmp_filter oval;
226 oval.data = 0xffffffff; 276 oval.data = 0xffffffff;
244 sockinfo si (THISNODE, PROT_ICMPv4); 294 sockinfo si (THISNODE, PROT_ICMPv4);
245 295
246 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 296 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
247 { 297 {
248 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 298 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
249 exit (EXIT_FAILURE); 299 return -1;
250 } 300 }
251 301
252 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 302 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
253 ++success; 303 ++success;
254 } 304 }
257 tcpv4_fd = -1; 307 tcpv4_fd = -1;
258 308
259#if ENABLE_TCP 309#if ENABLE_TCP
260 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 310 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
261 { 311 {
262 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 312 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
263 313
264 if (tcpv4_fd < 0) 314 if (tcpv4_fd < 0)
265 return -1; 315 return -1;
266 316
267 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
268 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
269
270 // standard daemon practise... 317 // standard daemon practise...
271 { 318 {
272 int oval = 1; 319 int oval = 1;
273 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 320 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
274 } 321 }
276 sockinfo si (THISNODE, PROT_TCPv4); 323 sockinfo si (THISNODE, PROT_TCPv4);
277 324
278 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 325 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
279 { 326 {
280 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 327 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
281 exit (EXIT_FAILURE); 328 return -1;
282 } 329 }
283 330
284 if (listen (tcpv4_fd, 5)) 331 if (listen (tcpv4_fd, 5))
285 { 332 {
286 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 333 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
287 exit (EXIT_FAILURE); 334 return -1;
288 } 335 }
289 336
290 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 337 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
291 ++success; 338 ++success;
292 } 339 }
300#if ENABLE_DNS 347#if ENABLE_DNS
301 if (THISNODE->protocols & PROT_DNSv4) 348 if (THISNODE->protocols & PROT_DNSv4)
302 { 349 {
303 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 350 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
304 351
305 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 352 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
306 353
307 if (dnsv4_fd < 0) 354 if (dnsv4_fd < 0)
308 return -1; 355 return -1;
309
310 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
311 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
312 356
313# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 357# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
314 // this I really consider a linux bug. I am neither connected 358 // this I really consider a linux bug. I am neither connected
315 // nor do I fragment myself. Linux still sets DF and doesn't 359 // nor do I fragment myself. Linux still sets DF and doesn't
316 // fragment for me sometimes. 360 // fragment for me sometimes.
331 PROT_DNSv4); 375 PROT_DNSv4);
332 376
333 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 377 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
334 { 378 {
335 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 379 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
336 exit (EXIT_FAILURE); 380 return -1;
337 } 381 }
338 382
339 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 383 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
340 ++success; 384 ++success;
341 } 385 }
343 387
344 ///////////////////////////////////////////////////////////////////////////// 388 /////////////////////////////////////////////////////////////////////////////
345 389
346 if (!success) 390 if (!success)
347 { 391 {
348 slog (L_ERR, _("no protocols enabled, exiting.")); 392 slog (L_ERR, _("no protocols enabled."));
349 exit (EXIT_FAILURE); 393 return -1;
350 } 394 }
351 395
352 reconnect_all (); 396 reconnect_all ();
353 397
354 ///////////////////////////////////////////////////////////////////////////// 398 /////////////////////////////////////////////////////////////////////////////
355 399
356 tap = new tap_device (); 400 tap = new tap_device ();
357 if (!tap) //D this, of course, never catches 401 if (!tap) //D this, of course, never catches
358 { 402 {
359 slog (L_ERR, _("cannot create network interface '%s', exiting."), conf.ifname); 403 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
360 exit (EXIT_FAILURE); 404 return -1;
361 } 405 }
362 406
363 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 407 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
364 408
365 run_script_cb cb; 409 run_script_cb cb;
366 cb.set<vpn, &vpn::script_if_init> (this); 410 cb.set<vpn, &vpn::script_if_init> (this);
367 411
368 if (tap->if_up () && 412 if (tap->if_up () &&
369 !run_script (cb, true)) 413 !run_script (cb, true))
370 { 414 {
371 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 415 slog (L_ERR, _("interface initialization command '%s' failed."),
372 tap->if_up ()); 416 tap->if_up ());
373 exit (EXIT_FAILURE); 417 return -1;
374 } 418 }
375 419
376 cb.set<vpn, &vpn::script_if_up> (this); 420 cb.set<vpn, &vpn::script_if_up> (this);
377 if (!run_script (cb, true)) 421 if (!run_script (cb, true))
378 { 422 {
379 slog (L_ERR, _("if-up command execution failed, exiting.")); 423 slog (L_ERR, _("if-up command execution failed."));
380 exit (EXIT_FAILURE); 424 return -1;
381 } 425 }
382 426
383 tap_ev_watcher.start (tap->fd, EV_READ); 427 tap_ev_watcher.start (tap->fd, EV_READ);
384 428
385 return 0; 429 return 0;
391 set_tos (ipv4_fd, ipv4_tos, tos); 435 set_tos (ipv4_fd, ipv4_tos, tos);
392 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 436 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
393 437
394 return true; 438 return true;
395} 439}
440
441#if 1 //D
442bool
443vpn::send_ipv42_packet (vpn_packet *pkt, const sockinfo &si, int tos)
444{
445 set_tos (ipv42_fd, ipv42_tos, tos);
446 sendto (ipv42_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
447
448 return true;
449}
450#endif
396 451
397static u16 452static u16
398ipv4_checksum (u16 *data, unsigned int len) 453ipv4_checksum (u16 *data, unsigned int len)
399{ 454{
400 // use 32 bit accumulator and fold back carry bits at the end 455 // use 32 bit accumulator and fold back carry bits at the end
474 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 529 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
475 530
476 if (src == 0 || src > conns.size () 531 if (src == 0 || src > conns.size ()
477 || dst > conns.size () 532 || dst > conns.size ()
478 || pkt->typ () >= vpn_packet::PT_MAX) 533 || pkt->typ () >= vpn_packet::PT_MAX)
479 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
480 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
481 else if (dst > conns.size ())
482 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), 534 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
483 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 535 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
484 else 536 else
485 { 537 {
486 connection *c = conns[src - 1]; 538 connection *c = conns[src - 1];
507bool 559bool
508vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 560vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
509{ 561{
510 switch (si.prot) 562 switch (si.prot)
511 { 563 {
564#if 1//D2
565 case PROT_IPv42:
566 return send_ipv42_packet (pkt, si, tos);
567#endif
568
512 case PROT_IPv4: 569 case PROT_IPv4:
513 return send_ipv4_packet (pkt, si, tos); 570 return send_ipv4_packet (pkt, si, tos);
514 571
515 case PROT_UDPv4: 572 case PROT_UDPv4:
516 return send_udpv4_packet (pkt, si, tos); 573 return send_udpv4_packet (pkt, si, tos);
517 574
518#if ENABLE_TCP 575#if ENABLE_TCP
519 case PROT_TCPv4: 576 case PROT_TCPv4:
520 return send_tcpv4_packet (pkt, si, tos); 577 return send_tcpv4_packet (pkt, si, tos);
521#endif 578#endif
522#if ENABLE_ICMP 579#if ENABLE_ICMP
523 case PROT_ICMPv4: 580 case PROT_ICMPv4:
532 } 589 }
533 590
534 return false; 591 return false;
535} 592}
536 593
594#if 1//D2
537inline void 595inline void
538vpn::ipv4_ev (ev::io &w, int revents) 596vpn::ipv42_ev (ev::io &w, int revents)
539{ 597{
540 if (revents & EV_READ) 598 if (revents & EV_READ)
541 { 599 {
542 vpn_packet *pkt = new vpn_packet; 600 vpn_packet *pkt = new vpn_packet;
543 struct sockaddr_in sa; 601 struct sockaddr_in sa;
544 socklen_t sa_len = sizeof (sa); 602 socklen_t sa_len = sizeof (sa);
545 int len; 603 int len;
546 604
547 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 605 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
548 606
607 sockinfo si(sa, PROT_IPv42);
608
609 if (len > 0)
610 {
611 pkt->len = len;
612
613 // raw sockets deliver the ipv4 header, but don't expect it on sends
614 pkt->skip_hdr (pkt->ipv4_hdr_len ());
615
616 recv_vpn_packet (pkt, si);
617 }
618 else
619 {
620 // probably ECONNRESET or somesuch
621 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
622 }
623
624 delete pkt;
625 }
626 else
627 {
628 slog (L_ERR,
629 _("FATAL: unknown revents %08x in socket, exiting.\n"),
630 revents);
631 exit (EXIT_FAILURE);
632 }
633}
634#endif
635
636inline void
637vpn::ipv4_ev (ev::io &w, int revents)
638{
639 if (revents & EV_READ)
640 {
641 vpn_packet *pkt = new vpn_packet;
642 struct sockaddr_in sa;
643 socklen_t sa_len = sizeof (sa);
644 int len;
645
646 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
647
549 sockinfo si(sa, PROT_IPv4); 648 sockinfo si(sa, PROT_IPv4);
550 649
551 if (len > 0) 650 if (len > 0)
552 { 651 {
553 pkt->len = len; 652 pkt->len = len;
554 653
555 // raw sockets deliver the ipv4 header, but don't expect it on sends 654 // raw sockets deliver the ipv4 header, but don't expect it on sends
556 pkt->skip_hdr (IP_OVERHEAD); 655 pkt->skip_hdr (pkt->ipv4_hdr_len ());
557 656
558 recv_vpn_packet (pkt, si); 657 recv_vpn_packet (pkt, si);
559 } 658 }
560 else 659 else
561 { 660 {
598 if (hdr->type == ::conf.icmp_type 697 if (hdr->type == ::conf.icmp_type
599 && hdr->code == 255) 698 && hdr->code == 255)
600 { 699 {
601 // raw sockets deliver the ipv4, but don't expect it on sends 700 // raw sockets deliver the ipv4, but don't expect it on sends
602 // this is slow, but... 701 // this is slow, but...
603 pkt->skip_hdr (ICMP_OVERHEAD); 702 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
604 703
605 recv_vpn_packet (pkt, si); 704 recv_vpn_packet (pkt, si);
606 } 705 }
607 } 706 }
608 else 707 else
750 849
751 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 850 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
752 (*c)->establish_connection (); 851 (*c)->establish_connection ();
753} 852}
754 853
854bool
755bool vpn::can_direct (conf_node *src, conf_node *dst) const 855vpn::can_direct (conf_node *src, conf_node *dst) const
756{ 856{
757 return src != dst 857 return src != dst
758 && src->may_direct (dst) 858 && src->may_direct (dst)
759 && dst->may_direct (src) 859 && dst->may_direct (src)
760 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS) 860 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
761 || (src->protocols & dst->connectable_protocols ())); 861 || (src->protocols & dst->connectable_protocols ()));
762} 862}
763 863
764// only works for indirect and routed connections: find a router 864// only works for indirect and routed connections: find a router
765// from THISNODE to dst 865// from THISNODE to dst
866connection *
766connection *vpn::find_router_for (const connection *dst) 867vpn::find_router_for (const connection *dst)
767{ 868{
768 connection *router = 0; 869 connection *router = 0;
769 870
770 // first try to find a router with a direct connection 871 // first try to find a router with a direct connection, route there
872 // regardless of any other considerations.
771 { 873 {
772 u32 prio = 1; 874 u32 prio = 1;
773 875
774 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 876 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
775 { 877 {
776 connection *c = *i; 878 connection *c = *i;
777 879
778 if (c->conf->routerprio > prio 880 if (c->conf->routerprio > prio
779 && c->conf != THISNODE 881 && c->conf != THISNODE
780 && c != dst
781 && can_direct (c->conf, dst->conf)) 882 && can_direct (c->conf, dst->conf)
883 && c->ictx && c->octx)
782 { 884 {
783 if (c->ictx && c->octx)
784 {
785 prio = c->conf->routerprio; 885 prio = c->conf->routerprio;
786 router = c; 886 router = c;
787 }
788 else
789 c->establish_connection ();
790 } 887 }
791 } 888 }
792 } 889 }
793 890
794 if (router) 891 if (router)
795 return router; 892 return router;
796 893
797 // second try find the router with the highest priority higher than ours 894 // second try find the router with the highest priority, higher than ours
798 { 895 {
799 u32 prio = 1; 896 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
800 897
801 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 898 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
802 { 899 {
803 connection *c = *i; 900 connection *c = *i;
804 901
805 if (c->conf->routerprio > prio 902 if (c->conf->routerprio > prio
806 && c->conf->routerprio > THISNODE->routerprio
807 && c != dst 903 && c != dst
808 && c->conf != THISNODE) 904 && c->conf != THISNODE
905 && c->ictx && c->octx)
809 { 906 {
810 if (c->ictx && c->octx)
811 {
812 prio = c->conf->routerprio; 907 prio = c->conf->routerprio;
813 router = c; 908 router = c;
814 }
815 else
816 c->establish_connection ();
817 } 909 }
818 } 910 }
819 } 911 }
912
820 return router; 913 return router;
821} 914}
822 915
916void
823void vpn::connection_established (connection *c) 917vpn::connection_established (connection *c)
824{ 918{
825 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 919 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
826 { 920 {
827 connection *o = *i; 921 connection *o = *i;
828 922
836 o->rekey (); 930 o->rekey ();
837 } 931 }
838 } 932 }
839} 933}
840 934
935void
841void vpn::send_connect_request (connection *c) 936vpn::send_connect_request (connection *c)
842{ 937{
843 connection *r = find_router_for (c); 938 connection *r = find_router_for (c);
844 939
845 if (r) 940 if (r)
846 { 941 {
847 slog (L_TRACE, _("%s: no way to connect, sending mediated connection request via %s."), 942 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
848 c->conf->nodename, r->conf->nodename); 943 c->conf->nodename, r->conf->nodename);
849 r->send_connect_request (c->conf->id); 944 r->send_connect_request (c->conf->id);
850 } 945 }
851 else 946 else
852 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect."), 947 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
853 c->conf->nodename); 948 c->conf->nodename);
854} 949}
855 950
856void 951void
857connection::dump_status () 952connection::dump_status ()
877vpn::vpn (void) 972vpn::vpn (void)
878{ 973{
879 event .set<vpn, &vpn::event_cb > (this); 974 event .set<vpn, &vpn::event_cb > (this);
880 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this); 975 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
881 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this); 976 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
977#if 1//D2
978 ipv42_ev_watcher .set<vpn, &vpn::ipv42_ev > (this);
979#endif
882#if ENABLE_TCP 980#if ENABLE_TCP
883 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this); 981 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
884#endif 982#endif
885#if ENABLE_ICMP 983#if ENABLE_ICMP
886 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this); 984 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines