ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpe.C
Revision: 1.14
Committed: Thu Aug 7 19:07:03 2008 UTC (15 years, 9 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_2, rel-2_21
Changes since 1.13: +0 -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-2008 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 tinc 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 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 /*
155 Close network connections, and terminate neatly
156 */
157 void cleanup_and_exit(int c)
158 {
159 network.shutdown_all ();
160
161 if (conf.pidfilename)
162 remove_pid (conf.pidfilename);
163
164 slog (L_INFO, _("terminating with exit code %d"), c);
165
166 exit (c);
167 }
168
169 /*
170 Signal handlers.
171 */
172 RETSIGTYPE
173 sigterm_handler (int a)
174 {
175 network.events |= vpn::EVENT_SHUTDOWN;
176 network.event.start ();
177 }
178
179 RETSIGTYPE
180 sighup_handler (int a)
181 {
182 network.events |= vpn::EVENT_RECONNECT;
183 network.event.start ();
184 }
185
186 RETSIGTYPE
187 sigusr1_handler (int a)
188 {
189 network.dump_status ();
190 }
191
192 RETSIGTYPE
193 sigusr2_handler (int a)
194 {
195 }
196
197 void
198 setup_signals (void)
199 {
200 struct sigaction act;
201
202 sigfillset (&act.sa_mask);
203 act.sa_flags = 0;
204
205 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL);
206 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL);
207 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL);
208 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL);
209 act.sa_flags = SA_RESETHAND;
210 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL);
211 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL);
212 }
213
214 int
215 main (int argc, char **argv, char **envp)
216 {
217 ERR_load_crypto_strings (); // we have the RAM
218
219 set_loglevel (L_INFO);
220 set_identity (argv[0]);
221 log_to (LOGTO_SYSLOG | LOGTO_STDERR);
222
223 setlocale (LC_ALL, "");
224 bindtextdomain (PACKAGE, LOCALEDIR);
225 textdomain (PACKAGE);
226
227 parse_options (argc, argv, envp);
228
229 argc -= optind;
230 argv += optind;
231
232 if (show_version)
233 {
234 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
235 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
236 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
237 printf (_
238 ("Copyright (C) 2003 Marc Lehmann <gvpe@schmorp.de> and others.\n"
239 "See the AUTHORS file for a complete list.\n\n"
240 "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
241 "and you are welcome to redistribute it under certain conditions;\n"
242 "see the file COPYING for details.\n"));
243
244 return 0;
245 }
246
247 if (show_help)
248 usage (0);
249
250 log_to (LOGTO_SYSLOG | LOGTO_STDERR);
251
252 /* Lock all pages into memory if requested */
253
254 #if HAVE_MLOCKALL && HAVE_SYS_MMAN_H && _POSIX_MEMLOCK
255 if (do_mlock)
256 if (mlockall (MCL_CURRENT | MCL_FUTURE))
257 slog (L_ERR, _("system call `%s' failed: %s"), "mlockall", strerror (errno));
258 #endif
259
260 if (argc >= 1)
261 {
262 thisnode = *argv++;
263 argc--;
264 }
265
266 if (!ev_default_loop (0))
267 {
268 slog (L_ERR, _("unable to initialise the event loop (bad $LIBEV_METHODS?)"));
269 exit (EXIT_FAILURE);
270 }
271
272 {
273 configuration_parser (conf, true, argc, argv);
274 }
275
276 set_loglevel (llevel != L_NONE ? llevel : conf.llevel);
277
278 RAND_load_file ("/dev/urandom", 1024);
279
280 if (!THISNODE)
281 {
282 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."),
283 thisnode ? thisnode : "<unset>");
284 exit (EXIT_FAILURE);
285 }
286
287 if (detach (do_detach))
288 exit (EXIT_SUCCESS);
289
290 setup_signals ();
291
292 if (!network.setup ())
293 {
294 ev_loop (EV_DEFAULT_ 0);
295 cleanup_and_exit (EXIT_FAILURE);
296 }
297
298 slog (L_ERR, _("unable to setup network, unrecoverable error, exiting."));
299 cleanup_and_exit (EXIT_FAILURE);
300 }
301