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

# 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 pcg 1.13 2003-2008 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     {
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 pcg 1.9 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
106 pcg 1.1 }
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 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     /*
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 pcg 1.10 network.event.start ();
177 pcg 1.1 }
178    
179     RETSIGTYPE
180     sighup_handler (int a)
181     {
182     network.events |= vpn::EVENT_RECONNECT;
183 pcg 1.10 network.event.start ();
184 pcg 1.1 }
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 pcg 1.6 argc -= optind;
230     argv += optind;
231    
232 pcg 1.1 if (show_version)
233     {
234 pcg 1.9 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
235 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
236     printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
237     printf (_
238 pcg 1.9 ("Copyright (C) 2003 Marc Lehmann <gvpe@schmorp.de> and others.\n"
239 pcg 1.1 "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 pcg 1.6 if (argc >= 1)
261     {
262     thisnode = *argv++;
263     argc--;
264     }
265    
266 pcg 1.12 if (!ev_default_loop (0))
267 pcg 1.10 {
268     slog (L_ERR, _("unable to initialise the event loop (bad $LIBEV_METHODS?)"));
269     exit (EXIT_FAILURE);
270     }
271    
272 pcg 1.6 {
273     configuration_parser (conf, true, argc, argv);
274     }
275 pcg 1.1
276     set_loglevel (llevel != L_NONE ? llevel : conf.llevel);
277    
278     RAND_load_file ("/dev/urandom", 1024);
279    
280     if (!THISNODE)
281     {
282 pcg 1.3 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."),
283 pcg 1.1 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 pcg 1.12 ev_loop (EV_DEFAULT_ 0);
295 pcg 1.1 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