cosmetics
[tomato.git] / release / src / router / openvpn / openvpn.c
blob451fbe41597adc90f5dd7e7115d18d4b45605ac5
1 /*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "syshead.h"
27 #include "init.h"
28 #include "forward.h"
29 #include "multi.h"
30 #include "win32.h"
32 #include "memdbg.h"
34 #include "forward-inline.h"
36 #define P2P_CHECK_SIG() EVENT_LOOP_CHECK_SIGNAL (c, process_signal_p2p, c);
38 static bool
39 process_signal_p2p (struct context *c)
41 remap_signal (c);
42 return process_signal (c);
45 static void
46 tunnel_point_to_point (struct context *c)
48 context_clear_2 (c);
50 /* set point-to-point mode */
51 c->mode = CM_P2P;
53 /* initialize tunnel instance */
54 init_instance_handle_signals (c, c->es, CC_HARD_USR1_TO_HUP);
55 if (IS_SIG (c))
56 return;
58 init_management_callback_p2p (c);
60 /* main event loop */
61 while (true)
63 perf_push (PERF_EVENT_LOOP);
65 /* process timers, TLS, etc. */
66 pre_select (c);
67 P2P_CHECK_SIG();
69 /* set up and do the I/O wait */
70 io_wait (c, p2p_iow_flags (c));
71 P2P_CHECK_SIG();
73 /* timeout? */
74 if (c->c2.event_set_status == ES_TIMEOUT)
76 perf_pop ();
77 continue;
80 /* process the I/O which triggered select */
81 process_io (c);
82 P2P_CHECK_SIG();
84 perf_pop ();
87 uninit_management_callback ();
89 /* tear down tunnel instance (unless --persist-tun) */
90 close_instance (c);
93 #undef PROCESS_SIGNAL_P2P
95 int
96 main (int argc, char *argv[])
98 struct context c;
100 #if PEDANTIC
101 fprintf (stderr, "Sorry, I was built with --enable-pedantic and I am incapable of doing any real work!\n");
102 return 1;
103 #endif
105 CLEAR (c);
107 /* signify first time for components which can
108 only be initialized once per program instantiation. */
109 c.first_time = true;
111 /* initialize program-wide statics */
112 if (init_static ())
115 * This loop is initially executed on startup and then
116 * once per SIGHUP.
120 /* enter pre-initialization mode with regard to signal handling */
121 pre_init_signal_catch ();
123 /* zero context struct but leave first_time member alone */
124 context_clear_all_except_first_time (&c);
126 /* static signal info object */
127 CLEAR (siginfo_static);
128 c.sig = &siginfo_static;
130 /* initialize garbage collector scoped to context object */
131 gc_init (&c.gc);
133 /* initialize environmental variable store */
134 c.es = env_set_create (NULL);
135 #ifdef WIN32
136 env_set_add_win32 (c.es);
137 #endif
139 #ifdef ENABLE_MANAGEMENT
140 /* initialize management subsystem */
141 init_management (&c);
142 #endif
144 /* initialize options to default state */
145 init_options (&c.options, true);
147 /* parse command line options, and read configuration file */
148 parse_argv (&c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, c.es);
150 #ifdef ENABLE_PLUGIN
151 /* plugins may contribute options configuration */
152 init_verb_mute (&c, IVM_LEVEL_1);
153 init_plugins (&c);
154 open_plugins (&c, true, OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE);
155 #endif
157 /* init verbosity and mute levels */
158 init_verb_mute (&c, IVM_LEVEL_1);
160 /* set dev options */
161 init_options_dev (&c.options);
163 /* openssl print info? */
164 if (print_openssl_info (&c.options))
165 break;
167 /* --genkey mode? */
168 if (do_genkey (&c.options))
169 break;
171 /* tun/tap persist command? */
172 if (do_persist_tuntap (&c.options))
173 break;
175 /* sanity check on options */
176 options_postprocess (&c.options);
178 /* show all option settings */
179 show_settings (&c.options);
181 /* print version number */
182 msg (M_INFO, "%s", title_string);
184 /* misc stuff */
185 pre_setup (&c.options);
187 /* test crypto? */
188 if (do_test_crypto (&c.options))
189 break;
191 #ifdef ENABLE_MANAGEMENT
192 /* open management subsystem */
193 if (!open_management (&c))
194 break;
195 #endif
197 /* set certain options as environmental variables */
198 setenv_settings (c.es, &c.options);
200 /* finish context init */
201 context_init_1 (&c);
205 /* run tunnel depending on mode */
206 switch (c.options.mode)
208 case MODE_POINT_TO_POINT:
209 tunnel_point_to_point (&c);
210 break;
211 #if P2MP_SERVER
212 case MODE_SERVER:
213 tunnel_server (&c);
214 break;
215 #endif
216 default:
217 ASSERT (0);
220 /* indicates first iteration -- has program-wide scope */
221 c.first_time = false;
223 /* any signals received? */
224 if (IS_SIG (&c))
225 print_signal (c.sig, NULL, M_INFO);
227 /* pass restart status to management subsystem */
228 signal_restart_status (c.sig);
230 while (c.sig->signal_received == SIGUSR1);
232 uninit_options (&c.options);
233 gc_reset (&c.gc);
235 while (c.sig->signal_received == SIGHUP);
238 context_gc_free (&c);
240 env_set_destroy (c.es);
242 #ifdef ENABLE_MANAGEMENT
243 /* close management interface */
244 close_management ();
245 #endif
247 /* uninitialize program-wide statics */
248 uninit_static ();
250 openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
251 return 0; /* NOTREACHED */