📄 init.c
字号:
/* * OpenVPN -- An application to securely tunnel IP networks * over a single TCP/UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002-2004 James Yonan <jim@yonan.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING included with this * distribution); if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#ifdef WIN32#include "config-win32.h"#else#include "config.h"#endif#include "syshead.h"#include "win32.h"#include "init.h"#include "sig.h"#include "occ.h"#include "list.h"#include "otime.h"#include "pool.h"#include "memdbg.h"#include "occ-inline.h"/* * Crypto initialization flags */#define CF_LOAD_PERSISTED_PACKET_ID (1<<0)#define CF_INIT_TLS_MULTI (1<<1)#define CF_INIT_TLS_AUTH_STANDALONE (1<<2)voidcontext_clear (struct context *c){ CLEAR (*c);}voidcontext_clear_1 (struct context *c){ CLEAR (c->c1);}voidcontext_clear_2 (struct context *c){ CLEAR (c->c2);}voidcontext_clear_all_except_first_time (struct context *c){ const bool first_time_save = c->first_time; context_clear (c); c->first_time = first_time_save;}/* * Initialize and possibly randomize remote list. */static voidinit_remote_list (struct context *c){ c->c1.remote_list = NULL; if (c->options.remote_list) { struct remote_list *l; ALLOC_OBJ_GC (c->c1.remote_list, struct remote_list, &c->gc); l = c->c1.remote_list; *l = *c->options.remote_list; l->current = -1; if (c->options.remote_random) remote_list_randomize (l); }}voidcontext_init_1 (struct context *c){ CLEAR (c->c1.link_socket_addr); CLEAR (c->c1.ks); packet_id_persist_init (&c->c1.pid_persist); c->c1.tuntap = NULL; c->c1.tuntap_owned = false; c->c1.route_list = NULL; c->c1.http_proxy = NULL; c->c1.socks_proxy = NULL; init_remote_list (c); c->c1.status_output = status_open (c->options.status_file, c->options.status_file_update_freq, -1); c->c1.status_output_owned = true; if (c->options.http_proxy_server) { c->c1.http_proxy = new_http_proxy (c->options.http_proxy_server, c->options.http_proxy_port, c->options.http_proxy_retry, c->options.http_proxy_auth_method, c->options.http_proxy_auth_file, &c->gc); } if (c->options.socks_proxy_server) { c->c1.socks_proxy = new_socks_proxy (c->options.socks_proxy_server, c->options.socks_proxy_port, c->options.socks_proxy_retry, &c->gc); }}voidcontext_gc_free (struct context *c){ gc_free (&c->c2.gc); gc_free (&c->options.gc); gc_free (&c->gc);}boolinit_static (void){ init_random_seed (); /* init random() function, only used as source for weak random numbers */ error_reset (); /* initialize error.c */ reset_check_status (); /* initialize status check code in socket.c */#ifdef WIN32 init_win32 ();#endif#ifdef OPENVPN_DEBUG_COMMAND_LINE { int i; for (i = 0; i < argc; ++i) msg (M_INFO, "argv[%d] = '%s'", i, argv[i]); }#endif update_time (); del_env_nonparm (0);#ifdef USE_CRYPTO init_ssl_lib (); /* init PRNG used for IV generation */ /* When forking, copy this to more places in the code to avoid fork random-state predictability */ prng_init ();#endif#ifdef PID_TEST packet_id_interactive_test (); /* test the sequence number code */ return false;#endif#ifdef SCHEDULE_TEST schedule_test (); return false;#endif#ifdef LIST_TEST list_test (); return false;#endif#ifdef IFCONFIG_POOL_TEST ifconfig_pool_test (0x0A010004, 0x0A0100FF); return false;#endif return true;}voiduninit_static (void){ openvpn_thread_cleanup ();#ifdef USE_CRYPTO free_ssl_lib ();#endif#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(USE_CRYPTO) && defined(USE_SSL) show_tls_performance_stats ();#endif}voidinit_verb_mute (struct context *c, unsigned int flags){ if (flags & IVM_LEVEL_1) { /* set verbosity and mute levels */ set_check_status (D_LINK_ERRORS, D_READ_WRITE); set_debug_level (c->options.verbosity); set_mute_cutoff (c->options.mute); } /* special D_LOG_RW mode */ if (flags & IVM_LEVEL_2) c->c2.log_rw = (check_debug_level (D_LOG_RW) && !check_debug_level (D_LOG_RW + 1));}/* * Possibly set --dev based on --dev-node. * For example, if --dev-node /tmp/foo/tun, and --dev undefined, * set --dev to tun. */voidinit_options_dev (struct options *options){ if (!options->dev) options->dev = dev_component_in_dev_node (options->dev_node);}boolprint_openssl_info (const struct options *options){ /* * OpenSSL info print mode? */#ifdef USE_CRYPTO if (options->show_ciphers || options->show_digests#ifdef USE_SSL || options->show_tls_ciphers#endif ) { if (options->show_ciphers) show_available_ciphers (); if (options->show_digests) show_available_digests ();#ifdef USE_SSL if (options->show_tls_ciphers) show_available_tls_ciphers ();#endif return true; }#endif return false;}/* * Static pre-shared key generation mode? */booldo_genkey (const struct options * options){#ifdef USE_CRYPTO if (options->genkey) { int nbits_written; notnull (options->shared_secret_file, "shared secret output file (--secret)"); if (options->mlock) /* should we disable paging? */ do_mlockall (true); nbits_written = write_key_file (2, options->shared_secret_file); msg (D_GENKEY | M_NOPREFIX, "Randomly generated %d bit key written to %s", nbits_written, options->shared_secret_file); return true; }#endif return false;}/* * Persistent TUN/TAP device management mode? */booldo_persist_tuntap (const struct options *options){#ifdef TUNSETPERSIST if (options->persist_config) { /* sanity check on options for --mktun or --rmtun */ notnull (options->dev, "TUN/TAP device (--dev)"); if (options->remote_list || options->ifconfig_local || options->ifconfig_remote_netmask#ifdef USE_CRYPTO || options->shared_secret_file#ifdef USE_SSL || options->tls_server || options->tls_client#endif#endif ) msg (M_FATAL, "Options error: options --mktun or --rmtun should only be used together with --dev"); tuncfg (options->dev, options->dev_type, options->dev_node, options->tun_ipv6, options->persist_mode); return true; }#endif return false;}/* * Should we become a daemon? * Return true if we did it. */static boolpossibly_become_daemon (const struct options *options, const bool first_time){ bool ret = false; if (first_time && options->daemon) { ASSERT (!options->inetd); if (daemon (options->cd_dir != NULL, options->log) < 0) msg (M_ERR, "daemon() failed"); ret = true; } return ret;}/* * Return common name in a way that is formatted for * prepending to msg() output. */const char *format_common_name (struct context *c, struct gc_arena *gc){ struct buffer out = alloc_buf_gc (256, gc);#if defined(USE_CRYPTO) && defined(USE_SSL) if (c->c2.tls_multi) { buf_printf (&out, "[%s] ", tls_common_name (c->c2.tls_multi, false)); }#endif return BSTR (&out);}voidpre_setup (const struct options *options){ /* show all option settings */ show_settings (options); /* set certain options as environmental variables */ setenv_settings (options); /* print version number */ msg (M_INFO, "%s", title_string);#ifdef WIN32 if (options->exit_event_name) { win32_signal_open (&win32_signal, WSO_FORCE_SERVICE, options->exit_event_name, options->exit_event_initial_state); } else { win32_signal_open (&win32_signal, WSO_FORCE_CONSOLE, NULL, false); /* put a title on the top window bar */ if (win32_signal.mode == WSO_MODE_CONSOLE) { window_title_save (&window_title); window_title_generate (options->config); } }#endif}voidreset_coarse_timers (struct context *c){ c->c2.coarse_timer_wakeup = 0;}/* * Initialize timers */static voiddo_init_timers (struct context *c, bool deferred){ update_time (); reset_coarse_timers (c); /* initialize inactivity timeout */ if (c->options.inactivity_timeout) event_timeout_init (&c->c2.inactivity_interval, c->options.inactivity_timeout, now); /* initialize pings */ if (c->options.ping_send_timeout) event_timeout_init (&c->c2.ping_send_interval, c->options.ping_send_timeout, 0); if (c->options.ping_rec_timeout) event_timeout_init (&c->c2.ping_rec_interval, c->options.ping_rec_timeout, now); if (!deferred) { /* initialize connection establishment timer */ event_timeout_init (&c->c2.wait_for_connect, 2, now); /* initialize occ timers */ if (c->options.occ && !TLS_MODE && c->c2.options_string_local && c->c2.options_string_remote) event_timeout_init (&c->c2.occ_interval, OCC_INTERVAL_SECONDS, now); if (c->options.mtu_test) event_timeout_init (&c->c2.occ_mtu_load_test_interval, OCC_MTU_LOAD_INTERVAL_SECONDS, now); /* initialize packet_id persistence timer */#ifdef USE_CRYPTO if (c->options.packet_id_file) event_timeout_init (&c->c2.packet_id_persist_interval, 60, now);#endif#if defined(USE_CRYPTO) && defined(USE_SSL) /* initialize tmp_int optimization that limits the number of times we call tls_multi_process in the main event loop */ interval_init (&c->c2.tmp_int, TLS_MULTI_HORIZON, TLS_MULTI_REFRESH);#endif }}/* * Initialize traffic shaper. */static voiddo_init_traffic_shaper (struct context *c){#ifdef HAVE_GETTIMEOFDAY /* initialize traffic shaper (i.e. transmit bandwidth limiter) */ if (c->options.shaper) { shaper_init (&c->c2.shaper, c->options.shaper); shaper_msg (&c->c2.shaper); }#endif}/* * Allocate a route list structure if at least one * --route option was specified. */static voiddo_alloc_route_list (struct context *c){ if (c->options.routes) c->c1.route_list = new_route_list (&c->gc);}/* * Initialize the route list, resolving any DNS names in route * options and saving routes in the environment. */static voiddo_init_route_list (const struct options *options, struct route_list *route_list, const struct link_socket_info *link_socket_info, bool fatal){ const char *gw = NULL; int dev = dev_type_enum (options->dev, options->dev_type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -