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

Comparing gvpe/src/conf.C (file contents):
Revision 1.42 by pcg, Mon Dec 5 12:58:08 2005 UTC vs.
Revision 1.55 by root, Sun Mar 6 19:40:28 2011 UTC

1/* 1/*
2 conf.c -- configuration code 2 conf.C -- configuration code
3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,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 7 GVPE is free software; you can redistribute it and/or modify it
8 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
9 the Free Software Foundation; either version 2 of the License, or 9 Free Software Foundation; either version 3 of the License, or (at your
10 (at your option) any later version. 10 option) any later version.
11 11
12 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
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 GNU General Public License for more details. 15 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 along
18 along with gvpe; if not, write to the Free Software 18 with this program; if not, see <http://www.gnu.org/licenses/>.
19 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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.
20*/ 30*/
21 31
22#include "config.h" 32#include "config.h"
23 33
24#include <cstdio> 34#include <cstdio>
47char *thisnode; 57char *thisnode;
48char *identname; 58char *identname;
49 59
50struct configuration conf; 60struct configuration conf;
51 61
62u8
52u8 best_protocol (u8 protset) 63best_protocol (u8 protset)
53{ 64{
54 if (protset & PROT_IPv4 ) return PROT_IPv4; 65 if (protset & PROT_IPv4 ) return PROT_IPv4;
55 if (protset & PROT_ICMPv4) return PROT_ICMPv4; 66 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
56 if (protset & PROT_UDPv4 ) return PROT_UDPv4; 67 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
57 if (protset & PROT_TCPv4 ) return PROT_TCPv4; 68 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
58 if (protset & PROT_DNSv4 ) return PROT_DNSv4; 69 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
59 70
60 return 0; 71 return 0;
61} 72}
62 73
74const char *
63const char *strprotocol (u8 protocol) 75strprotocol (u8 protocol)
64{ 76{
65 if (protocol & PROT_IPv4 ) return "rawip"; 77 if (protocol & PROT_IPv4 ) return "rawip";
66 if (protocol & PROT_ICMPv4) return "icmp"; 78 if (protocol & PROT_ICMPv4) return "icmp";
67 if (protocol & PROT_UDPv4 ) return "udp"; 79 if (protocol & PROT_UDPv4 ) return "udp";
68 if (protocol & PROT_TCPv4 ) return "tcp"; 80 if (protocol & PROT_TCPv4 ) return "tcp";
82 94
83 return false; 95 return false;
84} 96}
85 97
86bool 98bool
87conf_node::can_direct (struct conf_node *other) 99conf_node::may_direct (struct conf_node *other)
88{ 100{
89 if (match_list (allow_direct, other->nodename)) 101 if (match_list (allow_direct, other->nodename))
90 return true; 102 return true;
91 103
92 if (match_list (deny_direct, other->nodename)) 104 if (match_list (deny_direct, other->nodename))
93 return false; 105 return false;
94 106
95 return true; 107 return true;
96}
97
98void
99conf_node::print ()
100{
101 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
102 id,
103 id >> 8, id & 0xff,
104 compress ? 'Y' : 'N',
105 connectmode == C_ONDEMAND ? "ondemand" :
106 connectmode == C_NEVER ? "never" :
107 connectmode == C_ALWAYS ? "always" : "",
108 nodename,
109 hostname ? hostname : "",
110 hostname ? ":" : "",
111 hostname ? udp_port : 0
112 );
113} 108}
114 109
115conf_node::~conf_node () 110conf_node::~conf_node ()
116{ 111{
117#if 0 112#if 0
128 free (dns_hostname); 123 free (dns_hostname);
129#endif 124#endif
130#endif 125#endif
131} 126}
132 127
128void
133void configuration::init () 129configuration::init ()
134{ 130{
135 memset (this, 0, sizeof (*this)); 131 memset (this, 0, sizeof (*this));
136 132
137 mtu = DEFAULT_MTU; 133 mtu = DEFAULT_MTU;
134 nfmark = 0;
138 rekey = DEFAULT_REKEY; 135 rekey = DEFAULT_REKEY;
139 keepalive = DEFAULT_KEEPALIVE; 136 keepalive = DEFAULT_KEEPALIVE;
140 llevel = L_INFO; 137 llevel = L_INFO;
141 ip_proto = IPPROTO_GRE; 138 ip_proto = IPPROTO_GRE;
142#if ENABLE_ICMP 139#if ENABLE_ICMP
147 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm 144 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm
148 default_node.connectmode = conf_node::C_ALWAYS; 145 default_node.connectmode = conf_node::C_ALWAYS;
149 default_node.compress = true; 146 default_node.compress = true;
150 default_node.protocols = 0; 147 default_node.protocols = 0;
151 default_node.max_retry = DEFAULT_MAX_RETRY; 148 default_node.max_retry = DEFAULT_MAX_RETRY;
149 default_node.max_ttl = DEFAULT_MAX_TTL;
150 default_node.max_queue = DEFAULT_MAX_QUEUE;
152 default_node.if_up_data = strdup (""); 151 default_node.if_up_data = strdup ("");
153 152
154#if ENABLE_DNS 153#if ENABLE_DNS
155 default_node.dns_port = 0; // default is 0 == client 154 default_node.dns_port = 0; // default is 0 == client
156 155
156 dns_case_preserving = true;
157 dns_forw_host = strdup ("127.0.0.1"); 157 dns_forw_host = strdup ("127.0.0.1");
158 dns_forw_port = 53; 158 dns_forw_port = 53;
159 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; 159 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
160 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 160 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
161 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 161 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
163#endif 163#endif
164 164
165 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 165 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
166} 166}
167 167
168void
168void configuration::cleanup() 169configuration::cleanup ()
169{ 170{
170 if (rsa_key) 171 if (rsa_key)
171 RSA_free (rsa_key); 172 RSA_free (rsa_key);
172 173
173 rsa_key = 0; 174 rsa_key = 0;
174 175
175 free (pidfilename); pidfilename = 0; 176 free (pidfilename); pidfilename = 0;
176 free (ifname); ifname = 0; 177 free (ifname); ifname = 0;
177#if ENABLE_HTTP_PROXY 178#if ENABLE_HTTP_PROXY
178 free (proxy_host); proxy_host = 0; 179 free (proxy_host); proxy_host = 0;
179 free (proxy_auth); proxy_auth = 0; 180 free (proxy_auth); proxy_auth = 0;
180#endif 181#endif
181#if ENABLE_DNS 182#if ENABLE_DNS
182 free (dns_forw_host); dns_forw_host = 0; 183 free (dns_forw_host); dns_forw_host = 0;
183#endif 184#endif
185 free (script_if_up); script_if_up = 0;
186 free (script_node_up); script_node_up = 0;
187 free (script_node_change); script_node_change = 0;
188 free (script_node_down); script_node_down = 0;
184} 189}
185 190
186void 191void
187configuration::clear () 192configuration::clear ()
188{ 193{
192 nodes.clear (); 197 nodes.clear ();
193 198
194 cleanup (); 199 cleanup ();
195 init (); 200 init ();
196} 201}
202
203//static bool
204//is_true (const char *name)
205//{
206 //re
207//}
197 208
198#define parse_bool(target,name,trueval,falseval) do { \ 209#define parse_bool(target,name,trueval,falseval) do { \
199 if (!strcmp (val, "yes")) target = trueval; \ 210 if (!strcmp (val, "yes")) target = trueval; \
200 else if (!strcmp (val, "no")) target = falseval; \ 211 else if (!strcmp (val, "no")) target = falseval; \
201 else if (!strcmp (val, "true")) target = trueval; \ 212 else if (!strcmp (val, "true")) target = trueval; \
231 char *val = strtok (NULL, "\t\n\r ="); 242 char *val = strtok (NULL, "\t\n\r =");
232 243
233 if (!val || val[0] == '#') 244 if (!val || val[0] == '#')
234 return _("no value given for variable. (ignored)"); 245 return _("no value given for variable. (ignored)");
235 246
236 if (!strcmp (var, "on")) 247 else if (!strcmp (var, "on"))
237 { 248 {
238 if (!::thisnode 249 if (!::thisnode
239 || (val[0] == '!' && strcmp (val + 1, ::thisnode)) 250 || (val[0] == '!' && strcmp (val + 1, ::thisnode))
240 || !strcmp (val, ::thisnode)) 251 || !strcmp (val, ::thisnode))
241 return parse_line (strtok (NULL, "\n\r")); 252 return parse_line (strtok (NULL, "\n\r"));
242 else 253 }
243 return 0; 254
255 else if (!strcmp (var, "include"))
256 {
257 char *fname = conf.config_filename (val);
258 parse_file (fname);
259 free (fname);
244 } 260 }
245 261
246 // truly global 262 // truly global
247 if (!strcmp (var, "loglevel")) 263 else if (!strcmp (var, "loglevel"))
248 { 264 {
249 loglevel l = string_to_loglevel (val); 265 loglevel l = string_to_loglevel (val);
250 266
251 if (l == L_NONE) 267 if (l == L_NONE)
252 return _("unknown loglevel. (skipping)"); 268 return _("unknown loglevel. (skipping)");
316 conf.rekey = atoi (val); 332 conf.rekey = atoi (val);
317 else if (!strcmp (var, "keepalive")) 333 else if (!strcmp (var, "keepalive"))
318 conf.keepalive = atoi (val); 334 conf.keepalive = atoi (val);
319 else if (!strcmp (var, "mtu")) 335 else if (!strcmp (var, "mtu"))
320 conf.mtu = atoi (val); 336 conf.mtu = atoi (val);
337 else if (!strcmp (var, "nfmark"))
338 conf.nfmark = atoi (val);
321 else if (!strcmp (var, "if-up")) 339 else if (!strcmp (var, "if-up"))
322 free (conf.script_if_up), conf.script_if_up = strdup (val); 340 free (conf.script_if_up), conf.script_if_up = strdup (val);
323 else if (!strcmp (var, "node-up")) 341 else if (!strcmp (var, "node-up"))
324 free (conf.script_node_up), conf.script_node_up = strdup (val); 342 free (conf.script_node_up), conf.script_node_up = strdup (val);
343 else if (!strcmp (var, "node-change"))
344 free (conf.script_node_change), conf.script_node_change = strdup (val);
325 else if (!strcmp (var, "node-down")) 345 else if (!strcmp (var, "node-down"))
326 free (conf.script_node_down), conf.script_node_down = strdup (val); 346 free (conf.script_node_down), conf.script_node_down = strdup (val);
327 else if (!strcmp (var, "pid-file")) 347 else if (!strcmp (var, "pid-file"))
328 free (conf.pidfilename), conf.pidfilename = strdup (val); 348 free (conf.pidfilename), conf.pidfilename = strdup (val);
329 else if (!strcmp (var, "dns-forw-host")) 349 else if (!strcmp (var, "dns-forw-host"))
358 } 378 }
359 else if (!strcmp (var, "dns-max-outstanding")) 379 else if (!strcmp (var, "dns-max-outstanding"))
360 { 380 {
361#if ENABLE_DNS 381#if ENABLE_DNS
362 conf.dns_max_outstanding = atoi (val); 382 conf.dns_max_outstanding = atoi (val);
383#endif
384 }
385 else if (!strcmp (var, "dns-case-preserving"))
386 {
387#if ENABLE_DNS
388 parse_bool (conf.dns_case_preserving, "dns-case-preserving", true, false);
363#endif 389#endif
364 } 390 }
365 else if (!strcmp (var, "http-proxy-host")) 391 else if (!strcmp (var, "http-proxy-host"))
366 { 392 {
367#if ENABLE_HTTP_PROXY 393#if ENABLE_HTTP_PROXY
460 } 486 }
461 else if (!strcmp (var, "allow-direct")) 487 else if (!strcmp (var, "allow-direct"))
462 node->allow_direct.push_back (strdup (val)); 488 node->allow_direct.push_back (strdup (val));
463 else if (!strcmp (var, "deny-direct")) 489 else if (!strcmp (var, "deny-direct"))
464 node->deny_direct.push_back (strdup (val)); 490 node->deny_direct.push_back (strdup (val));
491 else if (!strcmp (var, "max-ttl"))
492 node->max_ttl = atof (val);
493 else if (!strcmp (var, "max-queue"))
494 node->max_queue = atoi (val);
465 495
466 // unknown or misplaced 496 // unknown or misplaced
467 else 497 else
468 return _("unknown configuration directive. (ignored)"); 498 return _("unknown configuration directive - ignored");
469 499
470 return 0; 500 return 0;
471} 501}
472 502
503void
504conf_node::finalise ()
505{
506 if (max_queue < 1)
507 {
508 slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename);
509 max_queue = 1;
510 }
511
512 if (routerprio > 1 && (connectmode != C_ALWAYS && connectmode != C_DISABLED))
513 {
514 //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename);
515 connectmode = C_ALWAYS;
516 }
517}
518
519void
473void configuration_parser::parse_argv () 520configuration_parser::parse_argv ()
474{ 521{
475 for (int i = 0; i < argc; ++i) 522 for (int i = 0; i < argc; ++i)
476 { 523 {
477 char *v = argv [i]; 524 char *v = argv [i];
478 525
499 if (warn) 546 if (warn)
500 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); 547 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
501 548
502 *v = 0; 549 *v = 0;
503 } 550 }
551 }
552}
553
554void
555configuration_parser::parse_file (const char *fname)
556{
557 if (FILE *f = fopen (fname, "r"))
558 {
559 char line [2048];
560 int lineno = 0;
561 node = &conf.default_node;
562
563 while (fgets (line, sizeof (line), f))
564 {
565 lineno++;
566
567 const char *warn = parse_line (line);
568
569 if (warn)
570 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
571 }
572
573 fclose (f);
574
575 parse_argv ();
576 }
577 else
578 {
579 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
580 exit (EXIT_FAILURE);
504 } 581 }
505} 582}
506 583
507configuration_parser::configuration_parser (configuration &conf, 584configuration_parser::configuration_parser (configuration &conf,
508 bool need_keys, 585 bool need_keys,
509 int argc, 586 int argc,
510 char **argv) 587 char **argv)
511: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 588: conf (conf),need_keys (need_keys), argc (argc), argv (argv)
512{ 589{
513 char *fname; 590 char *fname;
514 FILE *f;
515 591
516 conf.clear (); 592 conf.clear ();
517 593
518 asprintf (&fname, "%s/gvpe.conf", confbase); 594 asprintf (&fname, "%s/gvpe.conf", confbase);
519 f = fopen (fname, "r"); 595 parse_file (fname);
520
521 if (f)
522 {
523 char line[16384];
524 int lineno = 0;
525 node = &conf.default_node;
526
527 while (fgets (line, sizeof (line), f))
528 {
529 lineno++;
530
531 const char *warn = parse_line (line);
532
533 if (warn)
534 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
535 }
536
537 fclose (f);
538
539 parse_argv ();
540 }
541 else
542 {
543 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
544 exit (EXIT_FAILURE);
545 }
546
547 free (fname); 596 free (fname);
548 597
549 fname = conf.config_filename (conf.prikeyfile, "hostkey"); 598 fname = conf.config_filename (conf.prikeyfile, "hostkey");
550 599
551 f = fopen (fname, "r"); 600 if (FILE *f = fopen (fname, "r"))
552 if (f)
553 { 601 {
554 conf.rsa_key = RSA_new (); 602 conf.rsa_key = RSA_new ();
555 603
556 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) 604 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
557 { 605 {
569 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); 617 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
570 618
571 if (need_keys) 619 if (need_keys)
572 exit (EXIT_FAILURE); 620 exit (EXIT_FAILURE);
573 } 621 }
622
623 free (fname);
574 624
575 if (need_keys && ::thisnode 625 if (need_keys && ::thisnode
576 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) 626 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
577 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0 627 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
578 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0) 628 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
579 { 629 {
580 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode); 630 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
581 exit (EXIT_FAILURE); 631 exit (EXIT_FAILURE);
582 } 632 }
583 633
584 free (fname); 634 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
635 (*i)->finalise ();
585} 636}
586 637
638char *
587char *configuration::config_filename (const char *name, const char *dflt) 639configuration::config_filename (const char *name, const char *dflt)
588{ 640{
589 char *fname; 641 char *fname;
590 642
591 asprintf (&fname, name ? name : dflt, ::thisnode); 643 asprintf (&fname, name ? name : dflt, ::thisnode);
592 644
596 asprintf (&fname, "%s/%s", confbase, rname); 648 asprintf (&fname, "%s/%s", confbase, rname);
597 free (rname); 649 free (rname);
598 } 650 }
599 651
600 return fname; 652 return fname;
653}
654
655void
656conf_node::print ()
657{
658 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %02x %s%s%d\n",
659 id,
660 id >> 8, id & 0xff,
661 compress ? 'Y' : 'N',
662 connectmode == C_ONDEMAND ? "ondemand"
663 : connectmode == C_NEVER ? "never"
664 : connectmode == C_ALWAYS ? "always"
665 : connectmode == C_DISABLED ? "disabled"
666 : "",
667 nodename,
668 protocols,
669 hostname ? hostname : "",
670 hostname ? ":" : "",
671 hostname ? udp_port : 0
672 );
601} 673}
602 674
603void 675void
604configuration::print () 676configuration::print ()
605{ 677{
612 printf (_("interface: %s\n"), ifname); 684 printf (_("interface: %s\n"), ifname);
613 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 685 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
614 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1); 686 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
615 printf ("\n"); 687 printf ("\n");
616 688
617 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 689 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
618 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 690 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
619 691
620 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 692 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
621 (*i)->print (); 693 (*i)->print ();
622 694
623 printf ("\n"); 695 printf ("\n");
633configuration::~configuration () 705configuration::~configuration ()
634{ 706{
635 cleanup (); 707 cleanup ();
636} 708}
637 709
638

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines