ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpe.C
Revision: 1.19
Committed: Tue Feb 15 13:31:23 2011 UTC (13 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.18: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 gvpe.C -- the main file for gvpe
3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 2003-2011 Marc Lehmann <gvpe@schmorp.de>
6
7 This file is part of GVPE.
8
9 GVPE is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 Public License for more details.
18
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, see <http://www.gnu.org/licenses/>.
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.
32 */
33
34 #include "config.h"
35
36 #include <cstdio>
37 #include <cstring>
38 #include <cstdlib>
39
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <getopt.h>
43 #include <signal.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46 #include <signal.h>
47 #include <termios.h>
48
49 #if HAVE_SYS_MMAN_H
50 # include <sys/mman.h>
51 #endif
52
53 #include <openssl/err.h>
54 #include <openssl/rand.h>
55
56 #include "gettext.h"
57 #include "pidfile.h"
58
59 #include "conf.h"
60 #include "slog.h"
61 #include "util.h"
62 #include "vpn.h"
63 #include "ev_cpp.h"
64
65 static loglevel llevel = L_NONE;
66
67 /* If nonzero, display usage information and exit. */
68 static int show_help;
69
70 /* If nonzero, print the version on standard output and exit. */
71 static int show_version;
72
73 /* If nonzero, disable swapping for this process. */
74 static int do_mlock = 0;
75
76 /* If zero, don't detach from the terminal. */
77 static int do_detach = 1;
78
79 static struct option const long_options[] =
80 {
81 {"config", required_argument, NULL, 'c'},
82 {"help", no_argument, &show_help, 1},
83 {"version", no_argument, &show_version, 1},
84 {"no-detach", no_argument, &do_detach, 0},
85 {"log-level", required_argument, NULL, 'l'},
86 {"mlock", no_argument, &do_mlock, 1},
87 {NULL, 0, NULL, 0}
88 };
89
90 static void
91 usage (int status)
92 {
93 if (status != 0)
94 fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ());
95 else
96 {
97 printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ());
98 printf (_
99 (" -c, --config=DIR Read configuration options from DIR.\n"
100 " -D, --no-detach Don't fork and detach.\n"
101 " -l, --log-level=LEVEL Set logging level (info, notice, warn are common).\n"
102 " -L, --mlock Lock gvpe into main memory.\n"
103 " --help Display this help and exit.\n"
104 " --version Output version information and exit.\n\n"));
105 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
106 }
107
108 exit (status);
109 }
110
111 static void
112 parse_options (int argc, char **argv, char **envp)
113 {
114 int r;
115 int option_index = 0;
116
117 while ((r = getopt_long (argc, argv, "c:DLl:", long_options, &option_index)) != EOF)
118 {
119 switch (r)
120 {
121 case 0: /* long option */
122 break;
123
124 case 'c': /* config file */
125 confbase = strdup (optarg);
126 break;
127
128 case 'D': /* no detach */
129 do_detach = 0;
130 break;
131
132 case 'L': /* lock into memory */
133 do_mlock = 1;
134 break;
135
136 case 'l': /* inc debug level */
137 {
138 llevel = string_to_loglevel (optarg);
139
140 if (llevel == L_NONE)
141 slog (L_WARN, "'%s': %s", optarg, UNKNOWN_LOGLEVEL);
142 }
143 break;
144
145 case '?':
146 usage (1);
147
148 default:
149 break;
150 }
151 }
152 }
153
154 // close network connections, and terminate neatly
155 static void
156 cleanup_and_exit (int c)
157 {
158 network.shutdown_all ();
159
160 if (conf.pidfilename)
161 remove_pid (conf.pidfilename);
162
163 slog (L_INFO, _("terminating with exit code %d"), c);
164
165 exit (c);
166 }
167
168 // signal handlers
169 static RETSIGTYPE
170 sigterm_handler (int a)
171 {
172 network.events |= vpn::EVENT_SHUTDOWN;
173 network.event.start ();
174 }
175
176 static RETSIGTYPE
177 sighup_handler (int a)
178 {
179 network.events |= vpn::EVENT_RECONNECT;
180 network.event.start ();
181 }
182
183 static RETSIGTYPE
184 sigusr1_handler (int a)
185 {
186 network.dump_status ();
187 }
188
189 static RETSIGTYPE
190 sigusr2_handler (int a)
191 {
192 }
193
194 static void
195 setup_signals (void)
196 {
197 struct sigaction act;
198
199 sigfillset (&act.sa_mask);
200 act.sa_flags = 0;
201
202 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL);
203 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL);
204 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL);
205 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL);
206 act.sa_flags = SA_RESETHAND;
207 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL);
208 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL);
209 }
210
211 int
212 main (int argc, char **argv, char **envp)
213 {
214 ERR_load_crypto_strings (); // we have the RAM
215
216 set_loglevel (L_INFO);
217 set_identity (argv[0]);
218 log_to (LOGTO_SYSLOG | LOGTO_STDERR);
219
220 setlocale (LC_ALL, "");
221 bindtextdomain (PACKAGE, LOCALEDIR);
222 textdomain (PACKAGE);
223
224 parse_options (argc, argv, envp);
225
226 argc -= optind;
227 argv += optind;
228
229 if (show_version)
230 {
231 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
232 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
233 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
234 printf (_
235 ("Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> and others.\n"
236 "See the AUTHORS file for a complete list.\n\n"
237 "GVPE comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
238 "and you are welcome to redistribute it under certain conditions;\n"
239 "see the file COPYING for details.\n"));
240
241 return 0;
242 }
243
244 if (show_help)
245 usage (0);
246
247 log_to (LOGTO_SYSLOG | LOGTO_STDERR);
248
249 /* Lock all pages into memory if requested */
250
251 #if HAVE_MLOCKALL && HAVE_SYS_MMAN_H && _POSIX_MEMLOCK
252 if (do_mlock)
253 if (mlockall (MCL_CURRENT | MCL_FUTURE))
254 slog (L_ERR, _("system call `%s' failed: %s"), "mlockall", strerror (errno));
255 #endif
256
257 if (argc >= 1)
258 {
259 thisnode = *argv++;
260 argc--;
261 }
262
263 if (!ev_default_loop (0))
264 {
265 slog (L_ERR, _("unable to initialise the event loop (bad $LIBEV_METHODS?)"));
266 exit (EXIT_FAILURE);
267 }
268
269 {
270 configuration_parser (conf, true, argc, argv);
271 }
272
273 set_loglevel (llevel != L_NONE ? llevel : conf.llevel);
274
275 RAND_load_file ("/dev/urandom", 1024);
276
277 if (!THISNODE)
278 {
279 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."),
280 thisnode ? thisnode : "<unset>");
281 exit (EXIT_FAILURE);
282 }
283
284 if (detach (do_detach))
285 exit (EXIT_SUCCESS);
286
287 setup_signals ();
288
289 if (!network.setup ())
290 {
291 ev_loop (EV_DEFAULT_ 0);
292 cleanup_and_exit (EXIT_FAILURE);
293 }
294
295 slog (L_ERR, _("unrecoverable error while setting up network, exiting."));
296 cleanup_and_exit (EXIT_FAILURE);
297 }
298