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.9 by pcg, Tue Apr 8 02:00:54 2003 UTC vs.
Revision 1.67 by root, Fri Oct 11 04:07:24 2013 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,2010,2011,2013 Marc Lehmann <gvpe@schmorp.de>
3 4
5 This file is part of GVPE.
6
4 This program is free software; you can redistribute it and/or modify 7 GVPE is free software; you can redistribute it and/or modify it
5 it under the terms of the GNU General Public License as published by 8 under the terms of the GNU General Public License as published by the
6 the Free Software Foundation; either version 2 of the License, or 9 Free Software Foundation; either version 3 of the License, or (at your
7 (at your option) any later version. 10 option) any later version.
8 11
9 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful, but
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 GNU General Public License for more details. 15 Public License for more details.
13 16
14 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 along
15 along with this program; if not, write to the Free Software 18 with this program; if not, see <http://www.gnu.org/licenses/>.
16 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this Program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a modified
24 version of that library), containing parts covered by the terms of the
25 OpenSSL or SSLeay licenses, the licensors of this Program grant you
26 additional permission to convey the resulting work. Corresponding
27 Source for a non-source form of such a combination shall include the
28 source code for the parts of OpenSSL used as well as that of the
29 covered work.
17*/ 30*/
18 31
19#include "config.h" 32#include "config.h"
20 33
21#include <list> 34#include <list>
22 35
36#include <cstdio>
37#include <cstring>
23#include <cstdlib> 38#include <cstdlib>
24#include <cstring>
25#include <cstdio>
26 39
27#include <sys/types.h> 40#include <sys/types.h>
28#include <sys/socket.h> 41#include <sys/socket.h>
29#include <sys/poll.h>
30#include <sys/wait.h> 42#include <sys/wait.h>
43#include <sys/stat.h>
31#include <errno.h> 44#include <errno.h>
32#include <time.h> 45#include <time.h>
33#include <unistd.h> 46#include <unistd.h>
34#include <arpa/inet.h> 47#include <fcntl.h>
35#include <netinet/in.h> 48#include <sys/socket.h>
36#include <netinet/icmp.h> 49
50#include "netcompat.h"
37 51
38#include "pidfile.h" 52#include "pidfile.h"
39 53
40#include "connection.h" 54#include "connection.h"
41#include "util.h" 55#include "util.h"
42#include "vpn.h" 56#include "vpn.h"
43 57
58using namespace std;
59
60vpn network; // THE vpn (bad design...)
61
44///////////////////////////////////////////////////////////////////////////// 62/////////////////////////////////////////////////////////////////////////////
45 63
46const char *vpn::script_if_up () 64static void inline
65set_tos (int fd, int &tos_prev, int tos)
66{
67#if defined(SOL_IP) && defined(IP_TOS)
68 if (tos_prev == tos)
69 return;
70
71 tos_prev = tos;
72 setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos);
73#endif
74}
75
76void
77vpn::script_init_env ()
47{ 78{
48 // the tunnel device mtu should be the physical mtu - overhead 79 // the tunnel device mtu should be the physical mtu - overhead
49 // the tricky part is rounding to the cipher key blocksize 80 // the tricky part is rounding to the cipher key blocksize
50 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; 81 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
51 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion 82 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
52 mtu -= mtu % EVP_CIPHER_block_size (CIPHER); // round 83 mtu -= mtu % BLOCK_SIZE (CIPHER); // round
53 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again 84 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
54 85
55 char *env; 86 char *env;
56 asprintf (&env, "CONFBASE=%s", confbase); 87 asprintf (&env, "CONFBASE=%s", confbase); putenv (env);
57 putenv (env);
58 asprintf (&env, "NODENAME=%s", THISNODE->nodename);
59 putenv (env);
60 asprintf (&env, "NODEID=%d", THISNODE->id);
61 putenv (env);
62 asprintf (&env, "IFNAME=%s", tap->interface ()); 88 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env);
63 putenv (env); 89 asprintf (&env, "IFTYPE=%s", IFTYPE); putenv (env);
90 asprintf (&env, "IFSUBTYPE=%s", IFSUBTYPE); putenv (env);
64 asprintf (&env, "MTU=%d", mtu); 91 asprintf (&env, "MTU=%d", mtu); putenv (env);
65 putenv (env); 92 asprintf (&env, "NODES=%d", conns.size ()); putenv (env);
66 asprintf (&env, "MAC=%02x:%02x:%02x:%02x:%02x:%02x", 93 asprintf (&env, "NODEID=%d", THISNODE->id); putenv (env);
67 0xfe, 0xfd, 0x80, 0x00, THISNODE->id >> 8,
68 THISNODE->id & 0xff);
69 putenv (env);
70 94
71 return ::conf.script_if_up ? ::conf.script_if_up : "if-up"; 95 conns [THISNODE->id - 1]->script_init_env ("");
96
97 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
98 {
99 char ext[16];
100 snprintf (ext, 16, "_%d", (*c)->conf->id);
101 (*c)->script_init_env (ext);
102 }
103}
104
105inline const char *
106vpn::script_if_init ()
107{
108 script_init_env ();
109
110 return tap->if_up ();
111}
112
113inline const char *
114vpn::script_if_up ()
115{
116 script_init_env ();
117
118 return conf.config_filename (::conf.script_if_up, "if-up");
119}
120
121int
122vpn::setup_socket (u8 prot, int family, int type, int proto)
123{
124 int fd = socket (family, type, proto);
125
126 if (fd < 0)
127 {
128 slog (L_ERR, _("unable to create %s socket: %s."), strprotocol (prot), strerror (errno));
129 return fd;
130 }
131
132 fcntl (fd, F_SETFL, O_NONBLOCK);
133 fcntl (fd, F_SETFD, FD_CLOEXEC);
134
135#ifdef SO_MARK
136 if (::conf.nfmark)
137 if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark))
138 slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno));
139#endif
140
141 return fd;
72} 142}
73 143
74int 144int
75vpn::setup () 145vpn::setup ()
76{ 146{
147 int success = 0;
148
149 ipv4_tos = -1;
77 ipv4_fd = -1; 150 ipv4_fd = -1;
78 151
79 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 152 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
80 { 153 {
81 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 154 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
82 155
83 if (ipv4_fd < 0) 156 if (ipv4_fd < 0)
84 return -1; 157 return -1;
85 158
86#ifdef IP_MTU_DISCOVER 159#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
87 // this I really consider a linux bug. I am neither connected 160 // this I really consider a linux bug. I am neither connected
88 // nor do I fragment myself. Linux still sets DF and doesn't 161 // nor do I fragment myself. Linux still sets DF and doesn't
89 // fragment for me sometimes. 162 // fragment for me sometimes.
90 { 163 {
91 int oval = IP_PMTUDISC_DONT; 164 int oval = IP_PMTUDISC_DONT;
95 168
96 sockinfo si (THISNODE, PROT_IPv4); 169 sockinfo si (THISNODE, PROT_IPv4);
97 170
98 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 171 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
99 { 172 {
100 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 173 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
101 exit (1); 174 return -1;
102 } 175 }
103 176
104 ipv4_ev_watcher.start (ipv4_fd, POLLIN); 177 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
178 ++success;
105 } 179 }
180 else
181 THISNODE->protocols &= ~PROT_IPv4;
106 182
183 udpv4_tos = -1;
107 udpv4_fd = -1; 184 udpv4_fd = -1;
108 185
109 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 186 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
110 { 187 {
111 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 188 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
112 189
113 if (udpv4_fd < 0) 190 if (udpv4_fd < 0)
114 return -1; 191 return -1;
115 192
116 // standard daemon practise... 193 // standard daemon practise...
117 { 194 {
118 int oval = 1; 195 int oval = 1;
119 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 196 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
120 } 197 }
121 198
122#ifdef IP_MTU_DISCOVER 199#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
123 // this I really consider a linux bug. I am neither connected 200 // this I really consider a linux bug. I am neither connected
124 // nor do I fragment myself. Linux still sets DF and doesn't 201 // nor do I fragment myself. Linux still sets DF and doesn't
125 // fragment for me sometimes. 202 // fragment for me sometimes.
126 { 203 {
127 int oval = IP_PMTUDISC_DONT; 204 int oval = IP_PMTUDISC_DONT;
131 208
132 sockinfo si (THISNODE, PROT_UDPv4); 209 sockinfo si (THISNODE, PROT_UDPv4);
133 210
134 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 211 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
135 { 212 {
136 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 213 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
137 exit (1); 214 return -1;
138 } 215 }
139 216
140 udpv4_ev_watcher.start (udpv4_fd, POLLIN); 217 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
218 ++success;
141 } 219 }
220 else
221 THISNODE->protocols &= ~PROT_UDPv4;
142 222
223 icmpv4_tos = -1;
143 icmpv4_fd = -1; 224 icmpv4_fd = -1;
144 225
145#if ENABLE_ICMP 226#if ENABLE_ICMP
146 if (THISNODE->protocols & PROT_ICMPv4) 227 if (THISNODE->protocols & PROT_ICMPv4)
147 { 228 {
148 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 229 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
149 230
150 if (icmpv4_fd < 0) 231 if (icmpv4_fd < 0)
151 return -1; 232 return -1;
152 233
153#ifdef ICMP_FILTER 234#ifdef ICMP_FILTER
159 240
160 setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval); 241 setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval);
161 } 242 }
162#endif 243#endif
163 244
164#ifdef IP_MTU_DISCOVER 245#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
165 // this I really consider a linux bug. I am neither connected 246 // this I really consider a linux bug. I am neither connected
166 // nor do I fragment myself. Linux still sets DF and doesn't 247 // nor do I fragment myself. Linux still sets DF and doesn't
167 // fragment for me sometimes. 248 // fragment for me sometimes.
168 { 249 {
169 int oval = IP_PMTUDISC_DONT; 250 int oval = IP_PMTUDISC_DONT;
170 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 251 setsockopt (icmpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
171 } 252 }
172#endif 253#endif
173 254
174 sockinfo si (THISNODE, PROT_ICMPv4); 255 sockinfo si (THISNODE, PROT_ICMPv4);
175 256
176 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 257 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
177 { 258 {
178 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 259 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
179 exit (1); 260 return -1;
180 } 261 }
181 262
182 icmpv4_ev_watcher.start (icmpv4_fd, POLLIN); 263 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
264 ++success;
183 } 265 }
184#endif 266#endif
185 267
186 tcpv4_fd = -1; 268 tcpv4_fd = -1;
187 269
188#if ENABLE_TCP 270#if ENABLE_TCP
189 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 271 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
190 { 272 {
191 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 273 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
192 274
193 if (tcpv4_fd < 0) 275 if (tcpv4_fd < 0)
194 return -1; 276 return -1;
195 277
196 // standard daemon practise... 278 // standard daemon practise...
201 283
202 sockinfo si (THISNODE, PROT_TCPv4); 284 sockinfo si (THISNODE, PROT_TCPv4);
203 285
204 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 286 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
205 { 287 {
206 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 288 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
207 exit (1); 289 return -1;
208 } 290 }
209 291
210 if (listen (tcpv4_fd, 5)) 292 if (listen (tcpv4_fd, 5))
211 { 293 {
212 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 294 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
213 exit (1); 295 return -1;
296 }
297
298 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
299 ++success;
300 }
301 else
302 THISNODE->protocols &= ~PROT_TCPv4;
303#endif
304
305 dnsv4_tos = -1;
306 dnsv4_fd = -1;
307
308#if ENABLE_DNS
309 if (THISNODE->protocols & PROT_DNSv4)
310 {
311 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
312
313 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
314
315 if (dnsv4_fd < 0)
316 return -1;
317
318# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
319 // this I really consider a linux bug. I am neither connected
320 // nor do I fragment myself. Linux still sets DF and doesn't
321 // fragment for me sometimes.
322 {
323 int oval = IP_PMTUDISC_DONT;
324 setsockopt (dnsv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
214 } 325 }
215
216 tcpv4_ev_watcher.start (tcpv4_fd, POLLIN);
217 }
218#endif 326# endif
327
328 // standard daemon practise...
329 {
330 int oval = 1;
331 setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
332 }
333
334 sockinfo si (THISNODE->dns_hostname,
335 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
336 PROT_DNSv4);
337
338 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
339 {
340 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
341 return -1;
342 }
343
344 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
345 ++success;
346 }
347#endif
348
349 /////////////////////////////////////////////////////////////////////////////
350
351 if (!success)
352 {
353 slog (L_ERR, _("no protocols enabled."));
354 return -1;
355 }
356
357 reconnect_all ();
358
359 /////////////////////////////////////////////////////////////////////////////
219 360
220 tap = new tap_device (); 361 tap = new tap_device ();
221 if (!tap) //D this, of course, never catches 362 if (!tap) //D this, of course, never catches
222 { 363 {
223 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 364 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
224 exit (1); 365 return -1;
225 } 366 }
226 367
227 run_script (run_script_cb (this, &vpn::script_if_up), true); 368 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
228 369
370 run_script_cb cb;
371 cb.set<vpn, &vpn::script_if_init> (this);
372
373 if (tap->if_up () &&
374 !run_script (cb, true))
375 {
376 slog (L_ERR, _("interface initialization command '%s' failed."),
377 tap->if_up ());
378 return -1;
379 }
380
381 cb.set<vpn, &vpn::script_if_up> (this);
382 if (!run_script (cb, true))
383 {
384 slog (L_ERR, _("if-up command execution failed."));
385 return -1;
386 }
387
229 tap_ev_watcher.start (tap->fd, POLLIN); 388 tap_ev_watcher.start (tap->fd, EV_READ);
230
231 reconnect_all ();
232 389
233 return 0; 390 return 0;
234} 391}
235 392
236// send a vpn packet out to other hosts
237bool 393bool
238vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 394vpn::drop_privileges ()
239{ 395{
240 switch (si.prot) 396 if (::conf.change_root)
397 {
398 if (!strcmp (::conf.change_root, "/"))
399 {
400 char dir [L_tmpnam];
401 if (!tmpnam (dir))
402 {
403 slog (L_CRIT, _("unable to create anonymous root path."));
404 return false;
405 }
406
407 if (mkdir (dir, 0700))
408 {
409 slog (L_CRIT, _("unable to crate anonymous root directory."));
410 return false;
411 }
412
413 if (chdir (dir))
414 {
415 slog (L_CRIT, _("unable to change to anonymous root directory."));
416 return false;
417 }
418
419 if (rmdir (dir))
420 slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
421 }
422 else
423 {
424 if (chdir (::conf.change_root))
425 {
426 slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
427 return false;
428 }
429 }
430
431 if (chroot ("."))
432 {
433 slog (L_CRIT, _("unable to set new root directory."));
434 return false;
435 }
436
437 if (chdir ("/"))
438 {
439 slog (L_CRIT, _("unable to set cwd to new root directory."));
440 return false;
441 }
442 }
443
444 if (::conf.change_gid)
445 if (setgid (::conf.change_gid))
241 { 446 {
242 case PROT_IPv4: 447 slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
243 return send_ipv4_packet (pkt, si, tos);
244
245 case PROT_UDPv4:
246 return send_udpv4_packet (pkt, si, tos);
247
248#if ENABLE_TCP
249 case PROT_TCPv4:
250 return send_tcpv4_packet (pkt, si, tos);
251#endif
252
253#if ENABLE_ICMP
254 case PROT_ICMPv4:
255 return send_icmpv4_packet (pkt, si, tos);
256#endif
257
258 default:
259 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si);
260 return false; 448 return false;
261 } 449 }
450
451 if (::conf.change_uid)
452 if (setuid (::conf.change_uid))
453 {
454 slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
455 return false;
456 }
457
458 return true;
262} 459}
263 460
264bool 461bool
265vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 462vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
266{ 463{
267 setsockopt (ipv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos); 464 set_tos (ipv4_fd, ipv4_tos, tos);
268 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 465 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
269 466
270 return true; 467 return true;
271} 468}
272 469
291 sum += (sum >> 16); // carry 488 sum += (sum >> 16); // carry
292 489
293 return ~sum; 490 return ~sum;
294} 491}
295 492
493#if ENABLE_ICMP
296bool 494bool
297vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 495vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
298{ 496{
299 setsockopt (icmpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
300
301 pkt->unshift_hdr (4); 497 pkt->unshift_hdr (4);
302 498
303 icmphdr *hdr = (icmphdr *)&((*pkt)[0]); 499 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
304 hdr->type = ::conf.icmp_type; 500 hdr->type = ::conf.icmp_type;
305 hdr->code = 255; 501 hdr->code = 255;
306 hdr->checksum = 0; 502 hdr->checksum = 0;
307 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 503 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
308 504
505 set_tos (icmpv4_fd, icmpv4_tos, tos);
309 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 506 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
310 507
311 return true; 508 return true;
312} 509}
510#endif
313 511
314bool 512bool
315vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 513vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
316{ 514{
317 setsockopt (udpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos); 515 set_tos (udpv4_fd, udpv4_tos, tos);
318 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 516 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
319 517
320 return true; 518 return true;
519}
520
521void
522vpn::inject_data_packet (tap_packet *pkt, int dst)
523{
524 if (dst)
525 {
526 // unicast
527 if (dst != THISNODE->id)
528 conns[dst - 1]->inject_data_packet (pkt);
529 }
530 else
531 {
532 // broadcast, this is ugly, but due to the security policy
533 // we have to connect to all hosts...
534 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
535 if ((*c)->conf != THISNODE)
536 (*c)->inject_data_packet (pkt);
537 }
321} 538}
322 539
323void 540void
324vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 541vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
325{ 542{
326 unsigned int src = pkt->src (); 543 unsigned int src = pkt->src ();
327 unsigned int dst = pkt->dst (); 544 unsigned int dst = pkt->dst ();
328 545
329 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), 546 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d."),
330 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 547 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
331 548
332 if (src == 0 || src > conns.size () 549 if (src == 0 || src > conns.size ()
333 || dst > conns.size () 550 || dst > conns.size ()
334 || pkt->typ () >= vpn_packet::PT_MAX) 551 || pkt->typ () >= vpn_packet::PT_MAX)
335 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 552 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
336 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
337 else if (dst > conns.size ())
338 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"),
339 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 553 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
340 else 554 else
341 { 555 {
342 connection *c = conns[src - 1]; 556 connection *c = conns[src - 1];
343 557
344 if (dst == 0 && !THISNODE->routerprio) 558 if (dst == 0)
345 slog (L_WARN, _("%s(%s): received broadcast, but we are no router"), 559 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
346 c->conf->nodename, (const char *)rsi); 560 c->conf->nodename, (const char *)rsi);
347 else if (dst != 0 && dst != THISNODE->id) 561 else if (dst != THISNODE->id)
348 { 562 {
349 if (THISNODE->routerprio) 563 if (THISNODE->routerprio)
350 // the tos setting gets lost here. who cares. 564 // the tos setting gets lost here. who cares.
351 conns[dst - 1]->inject_vpn_packet (pkt); 565 conns[dst - 1]->inject_vpn_packet (pkt);
352 else 566 else
353 slog (L_WARN, 567 slog (L_WARN,
354 _("%s(%s): forwarding request (=> %s), but we are no router"), 568 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
355 c->conf->nodename, (const char *)rsi, 569 c->conf->nodename, (const char *)rsi,
356 conns[dst - 1]->conf->nodename); 570 conns[dst - 1]->conf->nodename);
357 } 571 }
358 else 572 else
359 c->recv_vpn_packet (pkt, rsi); 573 c->recv_vpn_packet (pkt, rsi);
360 } 574 }
361} 575}
362 576
363void 577bool
578vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
579{
580 switch (si.prot)
581 {
582 case PROT_IPv4:
583 return send_ipv4_packet (pkt, si, tos);
584
585 case PROT_UDPv4:
586 return send_udpv4_packet (pkt, si, tos);
587
588#if ENABLE_TCP
589 case PROT_TCPv4:
590 return send_tcpv4_packet (pkt, si, tos);
591#endif
592#if ENABLE_ICMP
593 case PROT_ICMPv4:
594 return send_icmpv4_packet (pkt, si, tos);
595#endif
596#if ENABLE_DNS
597 case PROT_DNSv4:
598 return send_dnsv4_packet (pkt, si, tos);
599#endif
600 default:
601 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
602 }
603
604 return false;
605}
606
607inline void
364vpn::ipv4_ev (io_watcher &w, short revents) 608vpn::ipv4_ev (ev::io &w, int revents)
365{ 609{
366 if (revents & (POLLIN | POLLERR)) 610 if (revents & EV_READ)
367 { 611 {
368 vpn_packet *pkt = new vpn_packet; 612 vpn_packet *pkt = new vpn_packet;
369 struct sockaddr_in sa; 613 struct sockaddr_in sa;
370 socklen_t sa_len = sizeof (sa); 614 socklen_t sa_len = sizeof (sa);
371 int len; 615 int len;
376 620
377 if (len > 0) 621 if (len > 0)
378 { 622 {
379 pkt->len = len; 623 pkt->len = len;
380 624
381 // raw sockets deliver the ipv4, but don't expect it on sends 625 // raw sockets deliver the ipv4 header, but don't expect it on sends
382 // this is slow, but... 626 pkt->skip_hdr (pkt->ipv4_hdr_len ());
383 pkt->skip_hdr (IP_OVERHEAD);
384 627
385 recv_vpn_packet (pkt, si); 628 recv_vpn_packet (pkt, si);
386 } 629 }
387 else 630 else
388 { 631 {
389 // probably ECONNRESET or somesuch 632 // probably ECONNRESET or somesuch
390 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 633 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
391 } 634 }
392 635
393 delete pkt; 636 delete pkt;
394 } 637 }
395 else if (revents & POLLHUP)
396 {
397 // this cannot ;) happen on udp sockets
398 slog (L_ERR, _("FATAL: POLLHUP on ipv4 fd, terminating."));
399 exit (1);
400 }
401 else 638 else
402 { 639 {
403 slog (L_ERR, 640 slog (L_ERR,
404 _("FATAL: unknown revents %08x in socket, terminating\n"), 641 _("FATAL: unknown revents %08x in socket, exiting.\n"),
405 revents); 642 revents);
406 exit (1); 643 exit (EXIT_FAILURE);
407 } 644 }
408} 645}
409 646
410void 647#if ENABLE_ICMP
648inline void
411vpn::icmpv4_ev (io_watcher &w, short revents) 649vpn::icmpv4_ev (ev::io &w, int revents)
412{ 650{
413 if (revents & (POLLIN | POLLERR)) 651 if (revents & EV_READ)
414 { 652 {
415 vpn_packet *pkt = new vpn_packet; 653 vpn_packet *pkt = new vpn_packet;
416 struct sockaddr_in sa; 654 struct sockaddr_in sa;
417 socklen_t sa_len = sizeof (sa); 655 socklen_t sa_len = sizeof (sa);
418 int len; 656 int len;
423 661
424 if (len > 0) 662 if (len > 0)
425 { 663 {
426 pkt->len = len; 664 pkt->len = len;
427 665
428 icmphdr *hdr = (icmphdr *)&((*pkt)[IP_OVERHEAD]); 666 icmp_header *hdr = (icmp_header *)&((*pkt)[IP_OVERHEAD]);
429 667
430 if (hdr->type == ::conf.icmp_type 668 if (hdr->type == ::conf.icmp_type
431 && hdr->code == 255) 669 && hdr->code == 255)
432 { 670 {
433 // raw sockets deliver the ipv4, but don't expect it on sends 671 // raw sockets deliver the ipv4, but don't expect it on sends
434 // this is slow, but... 672 // this is slow, but...
435 pkt->skip_hdr (ICMP_OVERHEAD); 673 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
436 674
437 recv_vpn_packet (pkt, si); 675 recv_vpn_packet (pkt, si);
438 } 676 }
439 } 677 }
440 else 678 else
441 { 679 {
442 // probably ECONNRESET or somesuch 680 // probably ECONNRESET or somesuch
443 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 681 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
444 } 682 }
445 683
446 delete pkt; 684 delete pkt;
447 } 685 }
448 else if (revents & POLLHUP)
449 {
450 // this cannot ;) happen on udp sockets
451 slog (L_ERR, _("FATAL: POLLHUP on icmpv4 fd, terminating."));
452 exit (1);
453 }
454 else 686 else
455 { 687 {
456 slog (L_ERR, 688 slog (L_ERR,
457 _("FATAL: unknown revents %08x in socket, terminating\n"), 689 _("FATAL: unknown revents %08x in socket, exiting.\n"),
458 revents); 690 revents);
459 exit (1); 691 exit (EXIT_FAILURE);
460 } 692 }
461} 693}
694#endif
462 695
463void 696inline void
464vpn::udpv4_ev (io_watcher &w, short revents) 697vpn::udpv4_ev (ev::io &w, int revents)
465{ 698{
466 if (revents & (POLLIN | POLLERR)) 699 if (revents & EV_READ)
467 { 700 {
468 vpn_packet *pkt = new vpn_packet; 701 vpn_packet *pkt = new vpn_packet;
469 struct sockaddr_in sa; 702 struct sockaddr_in sa;
470 socklen_t sa_len = sizeof (sa); 703 socklen_t sa_len = sizeof (sa);
471 int len; 704 int len;
481 recv_vpn_packet (pkt, si); 714 recv_vpn_packet (pkt, si);
482 } 715 }
483 else 716 else
484 { 717 {
485 // probably ECONNRESET or somesuch 718 // probably ECONNRESET or somesuch
486 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); 719 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
487 } 720 }
488 721
489 delete pkt; 722 delete pkt;
490 } 723 }
491 else if (revents & POLLHUP)
492 {
493 // this cannot ;) happen on udp sockets
494 slog (L_ERR, _("FATAL: POLLHUP on udp v4 fd, terminating."));
495 exit (1);
496 }
497 else 724 else
498 { 725 {
499 slog (L_ERR, 726 slog (L_ERR,
500 _("FATAL: unknown revents %08x in socket, terminating\n"), 727 _("FATAL: unknown revents %08x in socket, exiting.\n"),
501 revents); 728 revents);
502 exit (1); 729 exit (EXIT_FAILURE);
503 } 730 }
504} 731}
505 732
506void 733inline void
507vpn::tap_ev (io_watcher &w, short revents) 734vpn::tap_ev (ev::io &w, int revents)
508{ 735{
509 if (revents & POLLIN) 736 if (revents & EV_READ)
510 { 737 {
511 /* process data */ 738 /* process data */
512 tap_packet *pkt; 739 tap_packet *pkt;
513 740
514 pkt = tap->recv (); 741 pkt = tap->recv ();
515 742
743 if (!pkt)
744 return;
745
746 if (pkt->len > 14)
747 {
516 int dst = mac2id (pkt->dst); 748 int dst = mac2id (pkt->dst);
517 int src = mac2id (pkt->src); 749 int src = mac2id (pkt->src);
518 750
519 if (src != THISNODE->id) 751 if (src != THISNODE->id)
520 {
521 slog (L_ERR, _("FATAL: tap packet not originating on current node received, terminating."));
522 exit (1);
523 }
524
525 if (dst == THISNODE->id)
526 {
527 slog (L_ERR, _("FATAL: tap packet destined for current node received, terminating."));
528 exit (1);
529 }
530
531 if (dst > conns.size ())
532 slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst);
533 else
534 {
535 if (dst)
536 { 752 {
537 // unicast 753 slog (L_ERR, _("FATAL: tap packet not originating on current node received (if-up script not working properly?), exiting."));
538 if (dst != THISNODE->id) 754 exit (EXIT_FAILURE);
539 conns[dst - 1]->inject_data_packet (pkt);
540 } 755 }
756
757 if (dst == THISNODE->id)
758 {
759 slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting."));
760 exit (EXIT_FAILURE);
761 }
762
763 if (dst > conns.size ())
764 slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst);
541 else 765 else
542 {
543 // broadcast, first check router, then self, then english
544 connection *router = find_router ();
545
546 if (router)
547 router->inject_data_packet (pkt, true); 766 inject_data_packet (pkt, dst);
548 else
549 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
550 if ((*c)->conf != THISNODE)
551 (*c)->inject_data_packet (pkt);
552 }
553 } 767 }
554 768
555 delete pkt; 769 delete pkt;
556 }
557 else if (revents & (POLLHUP | POLLERR))
558 {
559 slog (L_ERR, _("FATAL: POLLHUP or POLLERR on network device fd, terminating."));
560 exit (1);
561 } 770 }
562 else 771 else
563 abort (); 772 abort ();
564} 773}
565 774
566void 775inline void
567vpn::event_cb (time_watcher &w) 776vpn::event_cb (ev::timer &w, int)
568{ 777{
569 if (events) 778 if (events)
570 { 779 {
571 if (events & EVENT_SHUTDOWN) 780 if (events & EVENT_SHUTDOWN)
572 { 781 {
573 slog (L_INFO, _("preparing shutdown...")); 782 slog (L_INFO, _("preparing shutdown..."));
574 783
575 shutdown_all (); 784 shutdown_all ();
576
577 remove_pid (pidfilename); 785 remove_pid (conf.pidfilename);
578
579 slog (L_INFO, _("terminating")); 786 slog (L_INFO, _("exiting."));
580 787 exit (EXIT_SUCCESS);
581 exit (0);
582 } 788 }
583 789
584 if (events & EVENT_RECONNECT) 790 if (events & EVENT_RECONNECT)
585 { 791 {
586 slog (L_INFO, _("forced reconnect")); 792 slog (L_INFO, _("forced reconnect."));
587 793
588 reconnect_all (); 794 reconnect_all ();
589 } 795 }
590 796
591 events = 0; 797 events = 0;
592 } 798 }
593
594 w.at = TSTAMP_CANCEL;
595} 799}
596 800
597void 801void
598vpn::shutdown_all () 802vpn::shutdown_all ()
599{ 803{
609 813
610 conns.clear (); 814 conns.clear ();
611 815
612 connection_init (); 816 connection_init ();
613 817
614 for (configuration::node_vector::iterator i = conf.nodes.begin (); 818 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
615 i != conf.nodes.end (); ++i) 819 conns.push_back (new connection (this, *i));
616 {
617 connection *conn = new connection (this);
618 820
619 conn->conf = *i; 821 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
620 conns.push_back (conn);
621
622 conn->establish_connection (); 822 (*c)->establish_connection ();
623 }
624} 823}
625 824
626connection *vpn::find_router () 825bool
826vpn::can_direct (conf_node *src, conf_node *dst) const
627{ 827{
628 u32 prio = 0; 828 return src != dst
829 && src->may_direct (dst)
830 && dst->may_direct (src)
831 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
832 || (src->protocols & dst->connectable_protocols ()));
833}
834
835// only works for indirect and routed connections: find a router
836// from THISNODE to dst
837connection *
838vpn::find_router_for (const connection *dst)
839{
629 connection *router = 0; 840 connection *router = 0;
630 841
842 // first try to find a router with a direct connection, route there
843 // regardless of any other considerations.
844 {
845 u32 prio = 1;
846
847 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
848 {
849 connection *c = *i;
850
851 if (c->conf->routerprio > prio
852 && c->conf != THISNODE
853 && can_direct (c->conf, dst->conf)
854 && c->ictx && c->octx)
855 {
856 prio = c->conf->routerprio;
857 router = c;
858 }
859 }
860 }
861
862 if (router)
863 return router;
864
865 // second try find the router with the highest priority, higher than ours
866 {
867 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
868
869 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
870 {
871 connection *c = *i;
872
873 if (c->conf->routerprio > prio
874 && c != dst
875 && c->conf != THISNODE
876 && c->ictx && c->octx)
877 {
878 prio = c->conf->routerprio;
879 router = c;
880 }
881 }
882 }
883
884 return router;
885}
886
887void
888vpn::connection_established (connection *c)
889{
631 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 890 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
632 { 891 {
633 connection *c = *i; 892 connection *o = *i;
634 893
635 if (c->conf->routerprio > prio 894 if (o->si.valid ()
636 && c->connectmode == conf_node::C_ALWAYS 895 && c->si != o->si
637 && c->conf != THISNODE 896 && c == find_router_for (o)
638 && c->ictx && c->octx) 897 && !can_direct (THISNODE, o->conf))
639 {
640 prio = c->conf->routerprio;
641 router = c;
642 } 898 {
899 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
900 o->conf->nodename, c->conf->nodename);
901 o->rekey ();
902 }
643 } 903 }
644
645 return router;
646} 904}
647 905
906void
648void vpn::send_connect_request (int id) 907vpn::send_connect_request (connection *c)
649{ 908{
650 connection *c = find_router (); 909 connection *r = find_router_for (c);
651 910
652 if (c) 911 if (r)
912 {
913 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
914 c->conf->nodename, r->conf->nodename);
653 c->send_connect_request (id); 915 r->send_connect_request (c->conf->id);
916 }
654 else 917 else
655 // no router found, aggressively connect to all routers 918 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
656 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 919 c->conf->nodename);
657 if ((*i)->conf->routerprio)
658 (*i)->establish_connection ();
659} 920}
660 921
661void 922void
662connection::dump_status () 923connection::dump_status ()
663{ 924{
664 slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id); 925 slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id);
665 slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"), 926 slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"),
666 connectmode, conf->connectmode, (const char *)si, (int)prot_minor); 927 connectmode, conf->connectmode, (const char *)si, (int)prot_minor);
667 slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"), 928 slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"),
668 (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt); 929 (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt);
669 slog (L_NOTICE, _(" establish_conn %ld / rekey %ld / keepalive %ld"),
670 (long)(establish_connection.at), (long)(rekey.at), (long)(keepalive.at));
671} 930}
672 931
673void 932void
674vpn::dump_status () 933vpn::dump_status ()
675{ 934{
676 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)NOW); 935 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
677 936
678 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 937 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
679 (*c)->dump_status (); 938 (*c)->dump_status ();
680 939
681 slog (L_NOTICE, _("END status dump")); 940 slog (L_NOTICE, _("END status dump"));
682} 941}
683 942
684vpn::vpn (void) 943vpn::vpn (void)
944{
685: event (this, &vpn::event_cb) 945 event .set<vpn, &vpn::event_cb > (this);
686, udpv4_ev_watcher (this, &vpn::udpv4_ev) 946 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
687, ipv4_ev_watcher (this, &vpn::ipv4_ev) 947 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
688#if ENABLE_TCP 948#if ENABLE_TCP
689, tcpv4_ev_watcher (this, &vpn::tcpv4_ev) 949 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
690#endif 950#endif
691#if ENABLE_ICMP 951#if ENABLE_ICMP
692, icmpv4_ev_watcher(this, &vpn::icmpv4_ev) 952 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
693#endif 953#endif
694, tap_ev_watcher (this, &vpn::tap_ev) 954#if ENABLE_DNS
695{ 955 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
956#endif
957 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
696} 958}
697 959
698vpn::~vpn () 960vpn::~vpn ()
699{ 961{
700} 962}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines