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.48 by pcg, Sat Aug 9 18:30:55 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{
150 int success = 0;
151
152#if 1//D2
127 ipv4_tos = -1; 153 ipv42_tos = -1;
128 ipv4_fd = -1; 154 ipv42_fd = -1;
129 155
130 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 156 if (THISNODE->protocols & PROT_IPv42 && ::conf.ip_proto)
131 { 157 {
132 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 158 ipv42_fd = setup_socket (PROT_IPv42, PF_INET, SOCK_RAW, ::conf.ip2_proto);
133 159
134 if (ipv4_fd < 0) 160 if (ipv42_fd < 0)
135 return -1; 161 return -1;
136
137 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
138 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
139 162
140#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 163#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
141 // this I really consider a linux bug. I am neither connected 164 // this I really consider a linux bug. I am neither connected
142 // 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
143 // fragment for me sometimes. 166 // fragment for me sometimes.
144 { 167 {
145 int oval = IP_PMTUDISC_DONT; 168 int oval = IP_PMTUDISC_DONT;
146 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 169 setsockopt (ipv42_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
147 } 170 }
148#endif 171#endif
149 172
150 sockinfo si (THISNODE, PROT_IPv4); 173 sockinfo si (THISNODE, PROT_IPv42);
151 174
152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 175 if (bind (ipv42_fd, si.sav4 (), si.salenv4 ()))
153 { 176 {
154 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 177 slog (L_ERR, _("can't bind ipv42 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
155 exit (EXIT_FAILURE); 178 return -1;
156 } 179 }
157 180
158 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 181 ipv42_ev_watcher.start (ipv42_fd, EV_READ);
182 ++success;
159 } 183 }
184 else
185 THISNODE->protocols &= ~PROT_IPv42;
186#endif
160 187
161 udpv4_tos = -1; 188 ipv4_tos = -1;
162 udpv4_fd = -1; 189 ipv4_fd = -1;
163 190
164 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 191 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
165 { 192 {
166 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 193 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
167 194
168 if (udpv4_fd < 0) 195 if (ipv4_fd < 0)
169 return -1; 196 return -1;
170
171 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
172 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
173
174 // standard daemon practise...
175 {
176 int oval = 1;
177 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
178 }
179 197
180#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 198#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
181 // this I really consider a linux bug. I am neither connected 199 // this I really consider a linux bug. I am neither connected
182 // 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
183 // fragment for me sometimes. 201 // fragment for me sometimes.
184 { 202 {
185 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;
186 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 244 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
187 } 245 }
188#endif 246#endif
189 247
190 sockinfo si (THISNODE, PROT_UDPv4); 248 sockinfo si (THISNODE, PROT_UDPv4);
191 249
192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 250 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
193 { 251 {
194 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 252 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
195 exit (EXIT_FAILURE); 253 return -1;
196 } 254 }
197 255
198 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 256 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
257 ++success;
199 } 258 }
259 else
260 THISNODE->protocols &= ~PROT_UDPv4;
200 261
201 icmpv4_tos = -1; 262 icmpv4_tos = -1;
202 icmpv4_fd = -1; 263 icmpv4_fd = -1;
203 264
204#if ENABLE_ICMP 265#if ENABLE_ICMP
205 if (THISNODE->protocols & PROT_ICMPv4) 266 if (THISNODE->protocols & PROT_ICMPv4)
206 { 267 {
207 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 268 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
208 269
209 if (icmpv4_fd < 0) 270 if (icmpv4_fd < 0)
210 return -1; 271 return -1;
211
212 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
213 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
214 272
215#ifdef ICMP_FILTER 273#ifdef ICMP_FILTER
216 { 274 {
217 icmp_filter oval; 275 icmp_filter oval;
218 oval.data = 0xffffffff; 276 oval.data = 0xffffffff;
235 293
236 sockinfo si (THISNODE, PROT_ICMPv4); 294 sockinfo si (THISNODE, PROT_ICMPv4);
237 295
238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 296 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
239 { 297 {
240 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 298 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
241 exit (EXIT_FAILURE); 299 return -1;
242 } 300 }
243 301
244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 302 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
303 ++success;
245 } 304 }
246#endif 305#endif
247 306
248 tcpv4_fd = -1; 307 tcpv4_fd = -1;
249 308
250#if ENABLE_TCP 309#if ENABLE_TCP
251 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 310 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
252 { 311 {
253 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 312 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
254 313
255 if (tcpv4_fd < 0) 314 if (tcpv4_fd < 0)
256 return -1; 315 return -1;
257 316
258 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
259 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
260
261 // standard daemon practise... 317 // standard daemon practise...
262 { 318 {
263 int oval = 1; 319 int oval = 1;
264 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 320 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
265 } 321 }
266 322
267 sockinfo si (THISNODE, PROT_TCPv4); 323 sockinfo si (THISNODE, PROT_TCPv4);
268 324
269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 325 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
270 { 326 {
271 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 327 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
272 exit (EXIT_FAILURE); 328 return -1;
273 } 329 }
274 330
275 if (listen (tcpv4_fd, 5)) 331 if (listen (tcpv4_fd, 5))
276 { 332 {
277 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 333 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
278 exit (EXIT_FAILURE); 334 return -1;
279 } 335 }
280 336
281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 337 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
338 ++success;
282 } 339 }
340 else
341 THISNODE->protocols &= ~PROT_TCPv4;
283#endif 342#endif
284 343
285 dnsv4_tos = -1; 344 dnsv4_tos = -1;
286 dnsv4_fd = -1; 345 dnsv4_fd = -1;
287 346
288#if ENABLE_DNS 347#if ENABLE_DNS
289 if (THISNODE->protocols & PROT_DNSv4) 348 if (THISNODE->protocols & PROT_DNSv4)
290 { 349 {
291 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);
292 351
293 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 352 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
294 353
295 if (dnsv4_fd < 0) 354 if (dnsv4_fd < 0)
296 return -1; 355 return -1;
297
298 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
299 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
300 356
301# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 357# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
302 // this I really consider a linux bug. I am neither connected 358 // this I really consider a linux bug. I am neither connected
303 // 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
304 // fragment for me sometimes. 360 // fragment for me sometimes.
318 THISNODE->dns_hostname ? THISNODE->dns_port : 0, 374 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
319 PROT_DNSv4); 375 PROT_DNSv4);
320 376
321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 377 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
322 { 378 {
323 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno)); 379 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
324 exit (EXIT_FAILURE); 380 return -1;
325 } 381 }
326 382
327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 383 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
384 ++success;
328 } 385 }
329#endif 386#endif
330 387
331 ///////////////////////////////////////////////////////////////////////////// 388 /////////////////////////////////////////////////////////////////////////////
389
390 if (!success)
391 {
392 slog (L_ERR, _("no protocols enabled."));
393 return -1;
394 }
332 395
333 reconnect_all (); 396 reconnect_all ();
334 397
335 ///////////////////////////////////////////////////////////////////////////// 398 /////////////////////////////////////////////////////////////////////////////
336 399
337 tap = new tap_device (); 400 tap = new tap_device ();
338 if (!tap) //D this, of course, never catches 401 if (!tap) //D this, of course, never catches
339 { 402 {
340 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 403 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
341 exit (EXIT_FAILURE); 404 return -1;
342 } 405 }
343 406
344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 407 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
345 408
346 run_script_cb cb; 409 run_script_cb cb;
347 cb.set<vpn, &vpn::script_if_init> (this); 410 cb.set<vpn, &vpn::script_if_init> (this);
348 411
349 if (tap->if_up () && 412 if (tap->if_up () &&
350 !run_script (cb, true)) 413 !run_script (cb, true))
351 { 414 {
352 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 415 slog (L_ERR, _("interface initialization command '%s' failed."),
353 tap->if_up ()); 416 tap->if_up ());
354 exit (EXIT_FAILURE); 417 return -1;
355 } 418 }
356 419
357 cb.set<vpn, &vpn::script_if_up> (this); 420 cb.set<vpn, &vpn::script_if_up> (this);
358 if (!run_script (cb, true)) 421 if (!run_script (cb, true))
359 { 422 {
360 slog (L_ERR, _("if-up command execution failed, exiting.")); 423 slog (L_ERR, _("if-up command execution failed."));
361 exit (EXIT_FAILURE); 424 return -1;
362 } 425 }
363 426
364 tap_ev_watcher.start (tap->fd, EV_READ); 427 tap_ev_watcher.start (tap->fd, EV_READ);
365 428
366 return 0; 429 return 0;
372 set_tos (ipv4_fd, ipv4_tos, tos); 435 set_tos (ipv4_fd, ipv4_tos, tos);
373 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 ());
374 437
375 return true; 438 return true;
376} 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
377 451
378static u16 452static u16
379ipv4_checksum (u16 *data, unsigned int len) 453ipv4_checksum (u16 *data, unsigned int len)
380{ 454{
381 // 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
449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 523vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
450{ 524{
451 unsigned int src = pkt->src (); 525 unsigned int src = pkt->src ();
452 unsigned int dst = pkt->dst (); 526 unsigned int dst = pkt->dst ();
453 527
454 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), 528 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d."),
455 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 529 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
456 530
457 if (src == 0 || src > conns.size () 531 if (src == 0 || src > conns.size ()
458 || dst > conns.size () 532 || dst > conns.size ()
459 || pkt->typ () >= vpn_packet::PT_MAX) 533 || pkt->typ () >= vpn_packet::PT_MAX)
460 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)."),
461 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 535 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
462 else if (dst > conns.size ())
463 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"),
464 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
465 else 536 else
466 { 537 {
467 connection *c = conns[src - 1]; 538 connection *c = conns[src - 1];
468 539
469 if (dst == 0) 540 if (dst == 0)
470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), 541 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
471 c->conf->nodename, (const char *)rsi); 542 c->conf->nodename, (const char *)rsi);
472 else if (dst != THISNODE->id) 543 else if (dst != THISNODE->id)
473 { 544 {
474 if (THISNODE->routerprio) 545 if (THISNODE->routerprio)
475 // the tos setting gets lost here. who cares. 546 // the tos setting gets lost here. who cares.
476 conns[dst - 1]->inject_vpn_packet (pkt); 547 conns[dst - 1]->inject_vpn_packet (pkt);
477 else 548 else
478 slog (L_WARN, 549 slog (L_WARN,
479 _("%s(%s): forwarding request (=> %s), but we are no router"), 550 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
480 c->conf->nodename, (const char *)rsi, 551 c->conf->nodename, (const char *)rsi,
481 conns[dst - 1]->conf->nodename); 552 conns[dst - 1]->conf->nodename);
482 } 553 }
483 else 554 else
484 c->recv_vpn_packet (pkt, rsi); 555 c->recv_vpn_packet (pkt, rsi);
488bool 559bool
489vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 560vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
490{ 561{
491 switch (si.prot) 562 switch (si.prot)
492 { 563 {
564#if 1//D2
565 case PROT_IPv42:
566 return send_ipv42_packet (pkt, si, tos);
567#endif
568
493 case PROT_IPv4: 569 case PROT_IPv4:
494 return send_ipv4_packet (pkt, si, tos); 570 return send_ipv4_packet (pkt, si, tos);
495 571
496 case PROT_UDPv4: 572 case PROT_UDPv4:
497 return send_udpv4_packet (pkt, si, tos); 573 return send_udpv4_packet (pkt, si, tos);
498 574
499#if ENABLE_TCP 575#if ENABLE_TCP
500 case PROT_TCPv4: 576 case PROT_TCPv4:
501 return send_tcpv4_packet (pkt, si, tos); 577 return send_tcpv4_packet (pkt, si, tos);
502#endif 578#endif
503#if ENABLE_ICMP 579#if ENABLE_ICMP
504 case PROT_ICMPv4: 580 case PROT_ICMPv4:
507#if ENABLE_DNS 583#if ENABLE_DNS
508 case PROT_DNSv4: 584 case PROT_DNSv4:
509 return send_dnsv4_packet (pkt, si, tos); 585 return send_dnsv4_packet (pkt, si, tos);
510#endif 586#endif
511 default: 587 default:
512 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); 588 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
513 } 589 }
514 590
515 return false; 591 return false;
516} 592}
517 593
594#if 1//D2
518inline void 595inline void
519vpn::ipv4_ev (ev::io &w, int revents) 596vpn::ipv42_ev (ev::io &w, int revents)
520{ 597{
521 if (revents & EV_READ) 598 if (revents & EV_READ)
522 { 599 {
523 vpn_packet *pkt = new vpn_packet; 600 vpn_packet *pkt = new vpn_packet;
524 struct sockaddr_in sa; 601 struct sockaddr_in sa;
525 socklen_t sa_len = sizeof (sa); 602 socklen_t sa_len = sizeof (sa);
526 int len; 603 int len;
527 604
528 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);
529 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
530 sockinfo si(sa, PROT_IPv4); 648 sockinfo si(sa, PROT_IPv4);
531 649
532 if (len > 0) 650 if (len > 0)
533 { 651 {
534 pkt->len = len; 652 pkt->len = len;
535 653
536 // 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
537 pkt->skip_hdr (IP_OVERHEAD); 655 pkt->skip_hdr (pkt->ipv4_hdr_len ());
538 656
539 recv_vpn_packet (pkt, si); 657 recv_vpn_packet (pkt, si);
540 } 658 }
541 else 659 else
542 { 660 {
543 // probably ECONNRESET or somesuch 661 // probably ECONNRESET or somesuch
544 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 662 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
545 } 663 }
546 664
547 delete pkt; 665 delete pkt;
548 } 666 }
549 else 667 else
550 { 668 {
551 slog (L_ERR, 669 slog (L_ERR,
552 _("FATAL: unknown revents %08x in socket, terminating\n"), 670 _("FATAL: unknown revents %08x in socket, exiting.\n"),
553 revents); 671 revents);
554 exit (EXIT_FAILURE); 672 exit (EXIT_FAILURE);
555 } 673 }
556} 674}
557 675
579 if (hdr->type == ::conf.icmp_type 697 if (hdr->type == ::conf.icmp_type
580 && hdr->code == 255) 698 && hdr->code == 255)
581 { 699 {
582 // 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
583 // this is slow, but... 701 // this is slow, but...
584 pkt->skip_hdr (ICMP_OVERHEAD); 702 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
585 703
586 recv_vpn_packet (pkt, si); 704 recv_vpn_packet (pkt, si);
587 } 705 }
588 } 706 }
589 else 707 else
590 { 708 {
591 // probably ECONNRESET or somesuch 709 // probably ECONNRESET or somesuch
592 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 710 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
593 } 711 }
594 712
595 delete pkt; 713 delete pkt;
596 } 714 }
597 else 715 else
598 { 716 {
599 slog (L_ERR, 717 slog (L_ERR,
600 _("FATAL: unknown revents %08x in socket, terminating\n"), 718 _("FATAL: unknown revents %08x in socket, exiting.\n"),
601 revents); 719 revents);
602 exit (EXIT_FAILURE); 720 exit (EXIT_FAILURE);
603 } 721 }
604} 722}
605#endif 723#endif
625 recv_vpn_packet (pkt, si); 743 recv_vpn_packet (pkt, si);
626 } 744 }
627 else 745 else
628 { 746 {
629 // probably ECONNRESET or somesuch 747 // probably ECONNRESET or somesuch
630 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); 748 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
631 } 749 }
632 750
633 delete pkt; 751 delete pkt;
634 } 752 }
635 else 753 else
636 { 754 {
637 slog (L_ERR, 755 slog (L_ERR,
638 _("FATAL: unknown revents %08x in socket, terminating\n"), 756 _("FATAL: unknown revents %08x in socket, exiting.\n"),
639 revents); 757 revents);
640 exit (EXIT_FAILURE); 758 exit (EXIT_FAILURE);
641 } 759 }
642} 760}
643 761
692 { 810 {
693 slog (L_INFO, _("preparing shutdown...")); 811 slog (L_INFO, _("preparing shutdown..."));
694 812
695 shutdown_all (); 813 shutdown_all ();
696 remove_pid (conf.pidfilename); 814 remove_pid (conf.pidfilename);
697 slog (L_INFO, _("terminating")); 815 slog (L_INFO, _("exiting."));
698 exit (EXIT_SUCCESS); 816 exit (EXIT_SUCCESS);
699 } 817 }
700 818
701 if (events & EVENT_RECONNECT) 819 if (events & EVENT_RECONNECT)
702 { 820 {
703 slog (L_INFO, _("forced reconnect")); 821 slog (L_INFO, _("forced reconnect."));
704 822
705 reconnect_all (); 823 reconnect_all ();
706 } 824 }
707 825
708 events = 0; 826 events = 0;
724 842
725 conns.clear (); 843 conns.clear ();
726 844
727 connection_init (); 845 connection_init ();
728 846
729 for (configuration::node_vector::iterator i = conf.nodes.begin (); 847 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
730 i != conf.nodes.end (); ++i) 848 conns.push_back (new connection (this, *i));
731 { 849
732 connection *conn = new connection (this, *i); 850 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
733 conns.push_back (conn);
734 conn->establish_connection (); 851 (*c)->establish_connection ();
735 }
736} 852}
737 853
738connection *vpn::find_router () 854bool
855vpn::can_direct (conf_node *src, conf_node *dst) const
739{ 856{
740 u32 prio = 1; 857 return src != dst
858 && src->may_direct (dst)
859 && dst->may_direct (src)
860 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
861 || (src->protocols & dst->connectable_protocols ()));
862}
863
864// only works for indirect and routed connections: find a router
865// from THISNODE to dst
866connection *
867vpn::find_router_for (const connection *dst)
868{
741 connection *router = 0; 869 connection *router = 0;
742 870
871 // first try to find a router with a direct connection, route there
872 // regardless of any other considerations.
873 {
874 u32 prio = 1;
875
876 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
877 {
878 connection *c = *i;
879
880 if (c->conf->routerprio > prio
881 && c->conf != THISNODE
882 && can_direct (c->conf, dst->conf)
883 && c->ictx && c->octx)
884 {
885 prio = c->conf->routerprio;
886 router = c;
887 }
888 }
889 }
890
891 if (router)
892 return router;
893
894 // second try find the router with the highest priority, higher than ours
895 {
896 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
897
898 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
899 {
900 connection *c = *i;
901
902 if (c->conf->routerprio > prio
903 && c != dst
904 && c->conf != THISNODE
905 && c->ictx && c->octx)
906 {
907 prio = c->conf->routerprio;
908 router = c;
909 }
910 }
911 }
912
913 return router;
914}
915
916void
917vpn::connection_established (connection *c)
918{
743 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 919 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
744 { 920 {
745 connection *c = *i; 921 connection *o = *i;
746 922
747 if (c->conf->routerprio > prio 923 if (!o->is_direct
748 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use 924 && o->si.valid ()
749 && c->ictx && c->octx 925 && c->si != o->si
750 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode 926 && c == find_router_for (o))
751 {
752 prio = c->conf->routerprio;
753 router = c;
754 } 927 {
928 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
929 o->conf->nodename, c->conf->nodename);
930 o->rekey ();
931 }
755 } 932 }
756
757 return router;
758} 933}
759 934
935void
760void vpn::send_connect_request (int id) 936vpn::send_connect_request (connection *c)
761{ 937{
762 connection *c = find_router (); 938 connection *r = find_router_for (c);
763 939
764 if (c) 940 if (r)
941 {
942 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
943 c->conf->nodename, r->conf->nodename);
765 c->send_connect_request (id); 944 r->send_connect_request (c->conf->id);
945 }
766 else 946 else
767 // no router found, aggressively connect to all routers 947 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
768 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 948 c->conf->nodename);
769 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
770 (*i)->establish_connection ();
771} 949}
772 950
773void 951void
774connection::dump_status () 952connection::dump_status ()
775{ 953{
794vpn::vpn (void) 972vpn::vpn (void)
795{ 973{
796 event .set<vpn, &vpn::event_cb > (this); 974 event .set<vpn, &vpn::event_cb > (this);
797 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this); 975 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
798 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
799#if ENABLE_TCP 980#if ENABLE_TCP
800 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this); 981 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
801#endif 982#endif
802#if ENABLE_ICMP 983#if ENABLE_ICMP
803 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