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.45 by pcg, Fri Aug 8 16:48:00 2008 UTC vs.
Revision 1.56 by root, Sun Mar 6 21:01:36 2011 UTC

1/* 1/*
2 conf.c -- configuration code 2 conf.C -- configuration code
3 Copyright (C) 2003-2008 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 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
57char *thisnode; 57char *thisnode;
58char *identname; 58char *identname;
59 59
60struct configuration conf; 60struct configuration conf;
61 61
62u8
62u8 best_protocol (u8 protset) 63best_protocol (u8 protset)
63{ 64{
64 if (protset & PROT_IPv4 ) return PROT_IPv4; 65 if (protset & PROT_IPv4 ) return PROT_IPv4;
65 if (protset & PROT_ICMPv4) return PROT_ICMPv4; 66 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
66 if (protset & PROT_UDPv4 ) return PROT_UDPv4; 67 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
67 if (protset & PROT_TCPv4 ) return PROT_TCPv4; 68 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
68 if (protset & PROT_DNSv4 ) return PROT_DNSv4; 69 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
69 70
70 return 0; 71 return 0;
71} 72}
72 73
74const char *
73const char *strprotocol (u8 protocol) 75strprotocol (u8 protocol)
74{ 76{
75 if (protocol & PROT_IPv4 ) return "rawip"; 77 if (protocol & PROT_IPv4 ) return "rawip";
76 if (protocol & PROT_ICMPv4) return "icmp"; 78 if (protocol & PROT_ICMPv4) return "icmp";
77 if (protocol & PROT_UDPv4 ) return "udp"; 79 if (protocol & PROT_UDPv4 ) return "udp";
78 if (protocol & PROT_TCPv4 ) return "tcp"; 80 if (protocol & PROT_TCPv4 ) return "tcp";
92 94
93 return false; 95 return false;
94} 96}
95 97
96bool 98bool
97conf_node::can_direct (struct conf_node *other) 99conf_node::may_direct (struct conf_node *other)
98{ 100{
99 if (match_list (allow_direct, other->nodename)) 101 if (match_list (allow_direct, other->nodename))
100 return true; 102 return true;
101 103
102 if (match_list (deny_direct, other->nodename)) 104 if (match_list (deny_direct, other->nodename))
103 return false; 105 return false;
104 106
105 return true; 107 return true;
106}
107
108void
109conf_node::print ()
110{
111 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
112 id,
113 id >> 8, id & 0xff,
114 compress ? 'Y' : 'N',
115 connectmode == C_ONDEMAND ? "ondemand" :
116 connectmode == C_NEVER ? "never" :
117 connectmode == C_ALWAYS ? "always" : "",
118 nodename,
119 hostname ? hostname : "",
120 hostname ? ":" : "",
121 hostname ? udp_port : 0
122 );
123} 108}
124 109
125conf_node::~conf_node () 110conf_node::~conf_node ()
126{ 111{
127#if 0 112#if 0
138 free (dns_hostname); 123 free (dns_hostname);
139#endif 124#endif
140#endif 125#endif
141} 126}
142 127
128void
143void configuration::init () 129configuration::init ()
144{ 130{
145 memset (this, 0, sizeof (*this)); 131 memset (this, 0, sizeof (*this));
146 132
147 mtu = DEFAULT_MTU; 133 mtu = DEFAULT_MTU;
134 nfmark = 0;
148 rekey = DEFAULT_REKEY; 135 rekey = DEFAULT_REKEY;
149 keepalive = DEFAULT_KEEPALIVE; 136 keepalive = DEFAULT_KEEPALIVE;
150 llevel = L_INFO; 137 llevel = L_INFO;
151 ip_proto = IPPROTO_GRE; 138 ip_proto = IPPROTO_GRE;
152#if ENABLE_ICMP 139#if ENABLE_ICMP
164 default_node.if_up_data = strdup (""); 151 default_node.if_up_data = strdup ("");
165 152
166#if ENABLE_DNS 153#if ENABLE_DNS
167 default_node.dns_port = 0; // default is 0 == client 154 default_node.dns_port = 0; // default is 0 == client
168 155
156 dns_case_preserving = true;
169 dns_forw_host = strdup ("127.0.0.1"); 157 dns_forw_host = strdup ("127.0.0.1");
170 dns_forw_port = 53; 158 dns_forw_port = 53;
171 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; 159 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
172 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 160 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
173 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 161 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
175#endif 163#endif
176 164
177 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 165 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
178} 166}
179 167
168void
180void configuration::cleanup() 169configuration::cleanup ()
181{ 170{
182 if (rsa_key) 171 if (rsa_key)
183 RSA_free (rsa_key); 172 RSA_free (rsa_key);
184 173
185 rsa_key = 0; 174 rsa_key = 0;
186 175
187 free (pidfilename); pidfilename = 0; 176 free (pidfilename); pidfilename = 0;
188 free (ifname); ifname = 0; 177 free (ifname); ifname = 0;
189#if ENABLE_HTTP_PROXY 178#if ENABLE_HTTP_PROXY
190 free (proxy_host); proxy_host = 0; 179 free (proxy_host); proxy_host = 0;
191 free (proxy_auth); proxy_auth = 0; 180 free (proxy_auth); proxy_auth = 0;
192#endif 181#endif
193#if ENABLE_DNS 182#if ENABLE_DNS
194 free (dns_forw_host); dns_forw_host = 0; 183 free (dns_forw_host); dns_forw_host = 0;
195#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;
196} 189}
197 190
198void 191void
199configuration::clear () 192configuration::clear ()
200{ 193{
204 nodes.clear (); 197 nodes.clear ();
205 198
206 cleanup (); 199 cleanup ();
207 init (); 200 init ();
208} 201}
202
203//static bool
204//is_true (const char *name)
205//{
206 //re
207//}
209 208
210#define parse_bool(target,name,trueval,falseval) do { \ 209#define parse_bool(target,name,trueval,falseval) do { \
211 if (!strcmp (val, "yes")) target = trueval; \ 210 if (!strcmp (val, "yes")) target = trueval; \
212 else if (!strcmp (val, "no")) target = falseval; \ 211 else if (!strcmp (val, "no")) target = falseval; \
213 else if (!strcmp (val, "true")) target = trueval; \ 212 else if (!strcmp (val, "true")) target = trueval; \
214 else if (!strcmp (val, "false")) target = falseval; \ 213 else if (!strcmp (val, "false")) target = falseval; \
215 else if (!strcmp (val, "on")) target = trueval; \ 214 else if (!strcmp (val, "on")) target = trueval; \
216 else if (!strcmp (val, "off")) target = falseval; \ 215 else if (!strcmp (val, "off")) target = falseval; \
217 else \ 216 else \
218 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \ 217 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed, ignored"); \
219} while (0) 218} while (0)
220 219
221const char * 220const char *
222configuration_parser::parse_line (char *line) 221configuration_parser::parse_line (char *line)
223{ 222{
241 return 0; /* comment: ignore */ 240 return 0; /* comment: ignore */
242 241
243 char *val = strtok (NULL, "\t\n\r ="); 242 char *val = strtok (NULL, "\t\n\r =");
244 243
245 if (!val || val[0] == '#') 244 if (!val || val[0] == '#')
246 return _("no value given for variable. (ignored)"); 245 return _("no value given for variable, ignored");
247 246
248 if (!strcmp (var, "on")) 247 else if (!strcmp (var, "on"))
249 { 248 {
250 if (!::thisnode 249 if (::thisnode
251 || (val[0] == '!' && strcmp (val + 1, ::thisnode)) 250 && ((val[0] == '!' && strcmp (val + 1, ::thisnode))
252 || !strcmp (val, ::thisnode)) 251 || !strcmp (val, ::thisnode)))
253 return parse_line (strtok (NULL, "\n\r")); 252 return parse_line (strtok (NULL, "\n\r"));
254 else 253 }
255 return 0; 254
255 else if (!strcmp (var, "include"))
256 {
257 char *fname = conf.config_filename (val);
258 parse_file (fname);
259 free (fname);
256 } 260 }
257 261
258 // truly global 262 // truly global
259 if (!strcmp (var, "loglevel")) 263 else if (!strcmp (var, "loglevel"))
260 { 264 {
261 loglevel l = string_to_loglevel (val); 265 loglevel l = string_to_loglevel (val);
262 266
263 if (l == L_NONE) 267 if (l == L_NONE)
264 return _("unknown loglevel. (skipping)"); 268 return _("unknown loglevel, ignored");
265 } 269 }
266 else if (!strcmp (var, "ip-proto")) 270 else if (!strcmp (var, "ip-proto"))
267 conf.ip_proto = atoi (val); 271 conf.ip_proto = atoi (val);
268 else if (!strcmp (var, "icmp-type")) 272 else if (!strcmp (var, "icmp-type"))
269 { 273 {
328 conf.rekey = atoi (val); 332 conf.rekey = atoi (val);
329 else if (!strcmp (var, "keepalive")) 333 else if (!strcmp (var, "keepalive"))
330 conf.keepalive = atoi (val); 334 conf.keepalive = atoi (val);
331 else if (!strcmp (var, "mtu")) 335 else if (!strcmp (var, "mtu"))
332 conf.mtu = atoi (val); 336 conf.mtu = atoi (val);
337 else if (!strcmp (var, "nfmark"))
338 conf.nfmark = atoi (val);
333 else if (!strcmp (var, "if-up")) 339 else if (!strcmp (var, "if-up"))
334 free (conf.script_if_up), conf.script_if_up = strdup (val); 340 free (conf.script_if_up), conf.script_if_up = strdup (val);
335 else if (!strcmp (var, "node-up")) 341 else if (!strcmp (var, "node-up"))
336 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);
337 else if (!strcmp (var, "node-down")) 345 else if (!strcmp (var, "node-down"))
338 free (conf.script_node_down), conf.script_node_down = strdup (val); 346 free (conf.script_node_down), conf.script_node_down = strdup (val);
339 else if (!strcmp (var, "pid-file")) 347 else if (!strcmp (var, "pid-file"))
340 free (conf.pidfilename), conf.pidfilename = strdup (val); 348 free (conf.pidfilename), conf.pidfilename = strdup (val);
341 else if (!strcmp (var, "dns-forw-host")) 349 else if (!strcmp (var, "dns-forw-host"))
370 } 378 }
371 else if (!strcmp (var, "dns-max-outstanding")) 379 else if (!strcmp (var, "dns-max-outstanding"))
372 { 380 {
373#if ENABLE_DNS 381#if ENABLE_DNS
374 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);
375#endif 389#endif
376 } 390 }
377 else if (!strcmp (var, "http-proxy-host")) 391 else if (!strcmp (var, "http-proxy-host"))
378 { 392 {
379#if ENABLE_HTTP_PROXY 393#if ENABLE_HTTP_PROXY
435 else if (!strcmp (val, "always")) 449 else if (!strcmp (val, "always"))
436 node->connectmode = conf_node::C_ALWAYS; 450 node->connectmode = conf_node::C_ALWAYS;
437 else if (!strcmp (val, "disabled")) 451 else if (!strcmp (val, "disabled"))
438 node->connectmode = conf_node::C_DISABLED; 452 node->connectmode = conf_node::C_DISABLED;
439 else 453 else
440 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)"); 454 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', ignored");
441 } 455 }
442 else if (!strcmp (var, "inherit-tos")) 456 else if (!strcmp (var, "inherit-tos"))
443 parse_bool (node->inherit_tos, "inherit-tos", true, false); 457 parse_bool (node->inherit_tos, "inherit-tos", true, false);
444 else if (!strcmp (var, "compress")) 458 else if (!strcmp (var, "compress"))
445 parse_bool (node->compress, "compress", true, false); 459 parse_bool (node->compress, "compress", true, false);
475 else if (!strcmp (var, "deny-direct")) 489 else if (!strcmp (var, "deny-direct"))
476 node->deny_direct.push_back (strdup (val)); 490 node->deny_direct.push_back (strdup (val));
477 else if (!strcmp (var, "max-ttl")) 491 else if (!strcmp (var, "max-ttl"))
478 node->max_ttl = atof (val); 492 node->max_ttl = atof (val);
479 else if (!strcmp (var, "max-queue")) 493 else if (!strcmp (var, "max-queue"))
480 {
481 node->max_queue = atoi (val); 494 node->max_queue = atoi (val);
482
483 if (node->max_queue < 1)
484 node->max_queue = 1;
485 }
486 495
487 // unknown or misplaced 496 // unknown or misplaced
488 else 497 else
489 return _("unknown configuration directive. (ignored)"); 498 return _("unknown configuration directive - ignored");
490 499
491 return 0; 500 return 0;
492} 501}
493 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
494void configuration_parser::parse_argv () 520configuration_parser::parse_argv ()
495{ 521{
496 for (int i = 0; i < argc; ++i) 522 for (int i = 0; i < argc; ++i)
497 { 523 {
498 char *v = argv [i]; 524 char *v = argv [i];
499 525
520 if (warn) 546 if (warn)
521 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);
522 548
523 *v = 0; 549 *v = 0;
524 } 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
562 while (fgets (line, sizeof (line), f))
563 {
564 lineno++;
565
566 const char *warn = parse_line (line);
567
568 if (warn)
569 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
570 }
571
572 fclose (f);
573
574 parse_argv ();
575 }
576 else
577 {
578 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
579 exit (EXIT_FAILURE);
525 } 580 }
526} 581}
527 582
528configuration_parser::configuration_parser (configuration &conf, 583configuration_parser::configuration_parser (configuration &conf,
529 bool need_keys, 584 bool need_keys,
530 int argc, 585 int argc,
531 char **argv) 586 char **argv)
532: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 587: conf (conf),need_keys (need_keys), argc (argc), argv (argv)
533{ 588{
534 char *fname; 589 char *fname;
535 FILE *f;
536 590
537 conf.clear (); 591 conf.clear ();
592 node = &conf.default_node;
538 593
539 asprintf (&fname, "%s/gvpe.conf", confbase); 594 asprintf (&fname, "%s/gvpe.conf", confbase);
540 f = fopen (fname, "r"); 595 parse_file (fname);
541
542 if (f)
543 {
544 char line[16384];
545 int lineno = 0;
546 node = &conf.default_node;
547
548 while (fgets (line, sizeof (line), f))
549 {
550 lineno++;
551
552 const char *warn = parse_line (line);
553
554 if (warn)
555 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
556 }
557
558 fclose (f);
559
560 parse_argv ();
561 }
562 else
563 {
564 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
565 exit (EXIT_FAILURE);
566 }
567
568 free (fname); 596 free (fname);
569 597
570 fname = conf.config_filename (conf.prikeyfile, "hostkey"); 598 fname = conf.config_filename (conf.prikeyfile, "hostkey");
571 599
572 f = fopen (fname, "r"); 600 if (FILE *f = fopen (fname, "r"))
573 if (f)
574 { 601 {
575 conf.rsa_key = RSA_new (); 602 conf.rsa_key = RSA_new ();
576 603
577 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) 604 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
578 { 605 {
590 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));
591 618
592 if (need_keys) 619 if (need_keys)
593 exit (EXIT_FAILURE); 620 exit (EXIT_FAILURE);
594 } 621 }
622
623 free (fname);
595 624
596 if (need_keys && ::thisnode 625 if (need_keys && ::thisnode
597 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) 626 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
598 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
599 || 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)
600 { 629 {
601 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);
602 exit (EXIT_FAILURE); 631 exit (EXIT_FAILURE);
603 } 632 }
604 633
605 free (fname); 634 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
635 (*i)->finalise ();
606} 636}
607 637
638char *
608char *configuration::config_filename (const char *name, const char *dflt) 639configuration::config_filename (const char *name, const char *dflt)
609{ 640{
610 char *fname; 641 char *fname;
611 642
612 asprintf (&fname, name ? name : dflt, ::thisnode); 643 asprintf (&fname, name ? name : dflt, ::thisnode);
613 644
617 asprintf (&fname, "%s/%s", confbase, rname); 648 asprintf (&fname, "%s/%s", confbase, rname);
618 free (rname); 649 free (rname);
619 } 650 }
620 651
621 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 );
622} 673}
623 674
624void 675void
625configuration::print () 676configuration::print ()
626{ 677{
633 printf (_("interface: %s\n"), ifname); 684 printf (_("interface: %s\n"), ifname);
634 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 685 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
635 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);
636 printf ("\n"); 687 printf ("\n");
637 688
638 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 689 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
639 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 690 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
640 691
641 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 692 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
642 (*i)->print (); 693 (*i)->print ();
643 694
644 printf ("\n"); 695 printf ("\n");
654configuration::~configuration () 705configuration::~configuration ()
655{ 706{
656 cleanup (); 707 cleanup ();
657} 708}
658 709
659

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines