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

Comparing gvpe/src/gvpe.C (file contents):
Revision 1.1 by pcg, Fri Mar 18 01:53:05 2005 UTC vs.
Revision 1.24 by root, Sat Jul 13 04:10:29 2013 UTC

1/* 1/*
2 vped.C -- the main file for gvpe 2 gvpe.C -- the main file for gvpe
3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl> 3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org> 4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 2003-2005 Marc Lehmann <gvpe@schmorp.de> 5 2003-2013 Marc Lehmann <gvpe@schmorp.de>
6 6
7 This file is part of GVPE. 7 This file is part of GVPE.
8 8
9 GVPE is free software; you can redistribute it and/or modify 9 GVPE is free software; you can redistribute it and/or modify it
10 it under the terms of the GNU General Public License as published by 10 under the terms of the GNU General Public License as published by the
11 the Free Software Foundation; either version 2 of the License, or 11 Free Software Foundation; either version 3 of the License, or (at your
12 (at your option) any later version. 12 option) any later version.
13 13
14 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful, but
15 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 GNU General Public License for more details. 17 Public License for more details.
18 18
19 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License along
20 along with gvpe; if not, write to the Free Software 20 with this program; if not, see <http://www.gnu.org/licenses/>.
21 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21
22 Additional permission under GNU GPL version 3 section 7
23
24 If you modify this Program, or any covered work, by linking or
25 combining it with the OpenSSL project's OpenSSL library (or a modified
26 version of that library), containing parts covered by the terms of the
27 OpenSSL or SSLeay licenses, the licensors of this Program grant you
28 additional permission to convey the resulting work. Corresponding
29 Source for a non-source form of such a combination shall include the
30 source code for the parts of OpenSSL used as well as that of the
31 covered work.
22*/ 32*/
23 33
24#include "config.h" 34#include "config.h"
25 35
26#include <cstdio> 36#include <cstdio>
30#include <errno.h> 40#include <errno.h>
31#include <fcntl.h> 41#include <fcntl.h>
32#include <getopt.h> 42#include <getopt.h>
33#include <signal.h> 43#include <signal.h>
34#include <sys/types.h> 44#include <sys/types.h>
45#include <sys/stat.h>
35#include <unistd.h> 46#include <unistd.h>
36#include <signal.h> 47#include <signal.h>
37#include <termios.h> 48#include <termios.h>
38 49
39#if HAVE_SYS_MMAN_H 50#if HAVE_SYS_MMAN_H
41#endif 52#endif
42 53
43#include <openssl/err.h> 54#include <openssl/err.h>
44#include <openssl/rand.h> 55#include <openssl/rand.h>
45 56
57#include "gettext.h"
46#include "pidfile.h" 58#include "pidfile.h"
47 59
48#include "conf.h" 60#include "conf.h"
49#include "slog.h" 61#include "slog.h"
50#include "util.h" 62#include "util.h"
51#include "vpn.h" 63#include "vpn.h"
52#include "iom.h" 64#include "ev_cpp.h"
53 65
54static loglevel llevel = L_NONE; 66static loglevel llevel = L_NONE;
55 67
56/* If nonzero, display usage information and exit. */ 68/* If nonzero, display usage information and exit. */
57static int show_help; 69static int show_help;
64 76
65/* If zero, don't detach from the terminal. */ 77/* If zero, don't detach from the terminal. */
66static int do_detach = 1; 78static int do_detach = 1;
67 79
68static struct option const long_options[] = 80static struct option const long_options[] =
69 { 81{
70 {"config", required_argument, NULL, 'c'}, 82 {"config", required_argument, NULL, 'c'},
71 {"help", no_argument, &show_help, 1}, 83 {"help", no_argument, &show_help, 1},
72 {"version", no_argument, &show_version, 1}, 84 {"version", no_argument, &show_version, 1},
73 {"no-detach", no_argument, &do_detach, 0}, 85 {"no-detach", no_argument, &do_detach, 0},
74 {"log-level", required_argument, NULL, 'l'}, 86 {"log-level", required_argument, NULL, 'l'},
75 {"mlock", no_argument, &do_mlock, 1}, 87 {"mlock", no_argument, &do_mlock, 1},
76 {NULL, 0, NULL, 0} 88 {NULL, 0, NULL, 0}
77 }; 89};
78 90
79static void 91static void
80usage (int status) 92usage (int status)
81{ 93{
82 if (status != 0) 94 if (status != 0)
86 printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ()); 98 printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ());
87 printf (_ 99 printf (_
88 (" -c, --config=DIR Read configuration options from DIR.\n" 100 (" -c, --config=DIR Read configuration options from DIR.\n"
89 " -D, --no-detach Don't fork and detach.\n" 101 " -D, --no-detach Don't fork and detach.\n"
90 " -l, --log-level=LEVEL Set logging level (info, notice, warn are common).\n" 102 " -l, --log-level=LEVEL Set logging level (info, notice, warn are common).\n"
91 " -L, --mlock Lock tinc into main memory.\n" 103 " -L, --mlock Lock gvpe into main memory.\n"
92 " --help Display this help and exit.\n" 104 " --help Display this help and exit.\n"
93 " --version Output version information and exit.\n\n")); 105 " --version Output version information and exit.\n\n"));
94 printf (_("Report bugs to <vpe@plan9.de>.\n")); 106 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
95 } 107 }
96 108
97 exit (status); 109 exit (status);
98} 110}
99 111
100void 112static void
101parse_options (int argc, char **argv, char **envp) 113parse_options (int argc, char **argv, char **envp)
102{ 114{
103 int r; 115 int r;
104 int option_index = 0; 116 int option_index = 0;
105 117
106 while ((r = getopt_long (argc, argv, "-c:DLl:", long_options, &option_index)) != EOF) 118 while ((r = getopt_long (argc, argv, "c:DLl:", long_options, &option_index)) != EOF)
107 { 119 {
108 switch (r) 120 switch (r)
109 { 121 {
110 case 0: /* long option */ 122 case 0: /* long option */
111 break; 123 break;
112 124
113 case 1: /* this node name */
114 thisnode = strdup (optarg);
115 break;
116
117 case 'c': /* config file */ 125 case 'c': /* config file */
118 confbase = strdup (optarg); 126 confbase = strdup (optarg);
119 break; 127 break;
120 128
121 case 'D': /* no detach */ 129 case 'D': /* no detach */
142 break; 150 break;
143 } 151 }
144 } 152 }
145} 153}
146 154
147/*
148 Close network connections, and terminate neatly 155// close network connections, and terminate neatly
149*/ 156static void
150void cleanup_and_exit(int c) 157cleanup_and_exit (int c)
151{ 158{
152 network.shutdown_all (); 159 network.shutdown_all ();
153 160
154 if (conf.pidfilename) 161 if (conf.pidfilename)
155 remove_pid (conf.pidfilename); 162 remove_pid (conf.pidfilename);
157 slog (L_INFO, _("terminating with exit code %d"), c); 164 slog (L_INFO, _("terminating with exit code %d"), c);
158 165
159 exit (c); 166 exit (c);
160} 167}
161 168
162/*
163 Signal handlers. 169// signal handlers
164*/ 170static RETSIGTYPE
165RETSIGTYPE
166sigterm_handler (int a) 171sigterm_handler (int a)
167{ 172{
168 network.events |= vpn::EVENT_SHUTDOWN; 173 network.events |= vpn::EVENT_SHUTDOWN;
169 network.event.start (0); 174 network.event.start ();
170} 175}
171 176
172RETSIGTYPE 177static RETSIGTYPE
173sighup_handler (int a) 178sighup_handler (int a)
174{ 179{
175 network.events |= vpn::EVENT_RECONNECT; 180 network.events |= vpn::EVENT_RECONNECT;
176 network.event.start (0); 181 network.event.start ();
177} 182}
178 183
179RETSIGTYPE 184static RETSIGTYPE
180sigusr1_handler (int a) 185sigusr1_handler (int a)
181{ 186{
182 network.dump_status (); 187 network.dump_status ();
183} 188}
184 189
185RETSIGTYPE 190static RETSIGTYPE
186sigusr2_handler (int a) 191sigusr2_handler (int a)
187{ 192{
188} 193}
189 194
190void 195static void
191setup_signals (void) 196setup_signals (void)
192{ 197{
193 struct sigaction act; 198 struct sigaction act;
194 199
195 sigfillset (&act.sa_mask); 200 sigfillset (&act.sa_mask);
196 act.sa_flags = 0; 201 act.sa_flags = 0;
197 202
198 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL); 203 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL);
199 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL); 204 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL);
200 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL); 205 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL);
201 act.sa_handler = SIG_IGN; sigaction (SIGCHLD, &act, NULL);
202 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL); 206 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL);
203 act.sa_flags = SA_RESETHAND; 207 act.sa_flags = SA_RESETHAND;
204 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL); 208 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL);
205 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL); 209 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL);
206} 210}
207 211
212static int rand_fd;
213
214// antique C++ requires external linkage :/
215void
216reseed_rng (ev::timer &w, int revents)
217{
218 char buf [SEED_SIZE];
219 int n = read (rand_fd, buf, sizeof (buf));
220
221 if (n > 0)
222 RAND_seed (buf, n);
223}
224
225static void
226setup_rng (void)
227{
228 if (!*conf.seed_dev)
229 return;
230
231#ifndef O_BINARY
232# define O_BINARY 0
233#endif
234#ifndef O_NONBLOCK
235# define O_NONBLOCK 0
236#endif
237
238 rand_fd = open (conf.seed_dev, O_RDONLY | O_NONBLOCK | O_BINARY);
239
240 if (rand_fd < 0)
241 {
242 slog (L_ERR, _("unable to open seed device '%s': %s, exiting."), conf.seed_dev, strerror (errno));
243 exit (EXIT_FAILURE);
244 }
245
246 static ev::timer reseed_timer;
247
248 if (conf.reseed)
249 {
250 reseed_timer.set<reseed_rng> ();
251 reseed_timer.set (conf.reseed, conf.reseed);
252 reseed_timer.start (EV_DEFAULT);
253 }
254
255 reseed_rng (reseed_timer, 0);
256}
257
208int 258int
209main (int argc, char **argv, char **envp) 259main (int argc, char **argv, char **envp)
210{ 260{
211 ERR_load_crypto_strings (); // we have the RAM 261 ERR_load_crypto_strings (); // we have the RAM
212 262
218 bindtextdomain (PACKAGE, LOCALEDIR); 268 bindtextdomain (PACKAGE, LOCALEDIR);
219 textdomain (PACKAGE); 269 textdomain (PACKAGE);
220 270
221 parse_options (argc, argv, envp); 271 parse_options (argc, argv, envp);
222 272
273 argc -= optind;
274 argv += optind;
275
223 if (show_version) 276 if (show_version)
224 { 277 {
225 printf (_("%s version %s (built %s %s, protocol %d.%d)\n"), get_identity (), 278 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
226 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); 279 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
227 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); 280 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
228 printf (_ 281 printf (_
229 ("Copyright (C) 2003 Marc Lehmann <vpe@plan9.de> and others.\n" 282 ("Copyright (C) 2003-2011 Marc Lehmann <gvpe@schmorp.de> and others.\n"
230 "See the AUTHORS file for a complete list.\n\n" 283 "See the AUTHORS file for a complete list.\n\n"
231 "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" 284 "GVPE comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
232 "and you are welcome to redistribute it under certain conditions;\n" 285 "and you are welcome to redistribute it under certain conditions;\n"
233 "see the file COPYING for details.\n")); 286 "see the file COPYING for details.\n"));
234 287
235 return 0; 288 return 0;
236 } 289 }
246 if (do_mlock) 299 if (do_mlock)
247 if (mlockall (MCL_CURRENT | MCL_FUTURE)) 300 if (mlockall (MCL_CURRENT | MCL_FUTURE))
248 slog (L_ERR, _("system call `%s' failed: %s"), "mlockall", strerror (errno)); 301 slog (L_ERR, _("system call `%s' failed: %s"), "mlockall", strerror (errno));
249#endif 302#endif
250 303
251 conf.read_config (true); 304 if (argc >= 1)
305 {
306 thisnode = *argv++;
307 argc--;
308 }
309
310 if (!ev_default_loop (0))
311 {
312 slog (L_ERR, _("unable to initialise the event loop (bad $LIBEV_METHODS?)"));
313 exit (EXIT_FAILURE);
314 }
315
316 {
317 configuration_parser (conf, true, argc, argv);
318 }
252 319
253 set_loglevel (llevel != L_NONE ? llevel : conf.llevel); 320 set_loglevel (llevel != L_NONE ? llevel : conf.llevel);
254 321
255 RAND_load_file ("/dev/urandom", 1024); 322 setup_rng ();
256 323
257 if (!THISNODE) 324 if (!THISNODE)
258 { 325 {
259 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting vped."), 326 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."),
260 thisnode ? thisnode : "<unset>"); 327 thisnode ? thisnode : "<unset>");
261 exit (EXIT_FAILURE); 328 exit (EXIT_FAILURE);
262 } 329 }
263 330
264 if (detach (do_detach)) 331 if (detach (do_detach))
265 exit (EXIT_SUCCESS); 332 exit (EXIT_SUCCESS);
266 333
267 setup_signals (); 334 setup_signals ();
268 335
269 if (!network.setup ()) 336 if (!network.setup ())
337 if (network.drop_privileges ())
270 { 338 {
271 io_manager::loop (); 339 ev_run (EV_DEFAULT_ 0);
272 cleanup_and_exit (EXIT_FAILURE); 340 cleanup_and_exit (EXIT_FAILURE);
273 } 341 }
274 342
275 slog (L_ERR, _("unable to setup network, unrecoverable error, exiting.")); 343 slog (L_CRIT, _("unrecoverable error while setting up network, exiting."));
276 cleanup_and_exit (EXIT_FAILURE); 344 cleanup_and_exit (EXIT_FAILURE);
277} 345}
278 346

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines