ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpe.C
Revision: 1.23
Committed: Fri Jul 5 10:04:22 2013 UTC (10 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.22: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2 pcg 1.4 gvpe.C -- the main file for gvpe
3 pcg 1.1 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4     2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 root 1.19 2003-2011 Marc Lehmann <gvpe@schmorp.de>
6 pcg 1.1
7     This file is part of GVPE.
8    
9 pcg 1.13 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 pcg 1.1 */
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 pcg 1.2 #include "gettext.h"
57 pcg 1.1 #include "pidfile.h"
58    
59     #include "conf.h"
60     #include "slog.h"
61     #include "util.h"
62     #include "vpn.h"
63 pcg 1.10 #include "ev_cpp.h"
64 pcg 1.1
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 root 1.18 {
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 pcg 1.1
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 pcg 1.16 " -L, --mlock Lock gvpe into main memory.\n"
103 pcg 1.1 " --help Display this help and exit.\n"
104     " --version Output version information and exit.\n\n"));
105 pcg 1.9 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
106 pcg 1.1 }
107    
108     exit (status);
109     }
110    
111 root 1.18 static void
112 pcg 1.1 parse_options (int argc, char **argv, char **envp)
113     {
114     int r;
115     int option_index = 0;
116    
117 pcg 1.6 while ((r = getopt_long (argc, argv, "c:DLl:", long_options, &option_index)) != EOF)
118 pcg 1.1 {
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 root 1.18 // close network connections, and terminate neatly
155     static void
156     cleanup_and_exit (int c)
157 pcg 1.1 {
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 root 1.18 // signal handlers
169     static RETSIGTYPE
170 pcg 1.1 sigterm_handler (int a)
171     {
172     network.events |= vpn::EVENT_SHUTDOWN;
173 pcg 1.10 network.event.start ();
174 pcg 1.1 }
175    
176 root 1.18 static RETSIGTYPE
177 pcg 1.1 sighup_handler (int a)
178     {
179     network.events |= vpn::EVENT_RECONNECT;
180 pcg 1.10 network.event.start ();
181 pcg 1.1 }
182    
183 root 1.18 static RETSIGTYPE
184 pcg 1.1 sigusr1_handler (int a)
185     {
186     network.dump_status ();
187     }
188    
189 root 1.18 static RETSIGTYPE
190 pcg 1.1 sigusr2_handler (int a)
191     {
192     }
193    
194 root 1.18 static void
195 pcg 1.1 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 pcg 1.6 argc -= optind;
227     argv += optind;
228    
229 pcg 1.1 if (show_version)
230     {
231 pcg 1.9 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
232 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
233     printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
234     printf (_
235 root 1.23 ("Copyright (C) 2003-2011 Marc Lehmann <gvpe@schmorp.de> and others.\n"
236 pcg 1.1 "See the AUTHORS file for a complete list.\n\n"
237 pcg 1.16 "GVPE comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
238 pcg 1.1 "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 pcg 1.6 if (argc >= 1)
258     {
259     thisnode = *argv++;
260     argc--;
261     }
262    
263 pcg 1.12 if (!ev_default_loop (0))
264 pcg 1.10 {
265     slog (L_ERR, _("unable to initialise the event loop (bad $LIBEV_METHODS?)"));
266     exit (EXIT_FAILURE);
267     }
268    
269 pcg 1.6 {
270     configuration_parser (conf, true, argc, argv);
271     }
272 pcg 1.1
273     set_loglevel (llevel != L_NONE ? llevel : conf.llevel);
274    
275     RAND_load_file ("/dev/urandom", 1024);
276    
277     if (!THISNODE)
278     {
279 pcg 1.3 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."),
280 pcg 1.1 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 root 1.22 if (network.drop_privileges ())
291     {
292     ev_run (EV_DEFAULT_ 0);
293     cleanup_and_exit (EXIT_FAILURE);
294     }
295 pcg 1.1
296 root 1.22 slog (L_CRIT, _("unrecoverable error while setting up network, exiting."));
297 pcg 1.1 cleanup_and_exit (EXIT_FAILURE);
298     }
299