📄 init.c
字号:
* Remove non-parameter environmental vars except for signal */static voiddo_close_remove_env (struct context *c){ del_env_nonparm (#if defined(USE_CRYPTO) && defined(USE_SSL) get_max_tls_verify_id (c->c2.tls_multi)#else 0#endif );}/* * Close packet-id persistance file */static voiddo_close_packet_id (struct context *c){#ifdef USE_CRYPTO packet_id_free (&c->c2.packet_id); packet_id_persist_save (&c->c1.pid_persist); if (!(c->sig->signal_received == SIGUSR1)) packet_id_persist_close (&c->c1.pid_persist);#endif}static voiddo_close_status_output (struct context *c){ if (!(c->sig->signal_received == SIGUSR1)) { if (c->c1.status_output_owned && c->c1.status_output) status_close (c->c1.status_output); }}/* * Close fragmentation handler. */static voiddo_close_fragment (struct context *c){ if (c->c2.fragment) fragment_free (c->c2.fragment);}static voiddo_close_syslog (struct context *c){ if (!(c->sig->signal_received == SIGUSR1)) close_syslog ();}/* * Open and close our event objects. */static voiddo_event_set_init (struct context *c, bool need_us_timeout){ unsigned int flags = 0; c->c2.event_set_max = 3; flags |= EVENT_METHOD_FAST; if (need_us_timeout) flags |= EVENT_METHOD_US_TIMEOUT; c->c2.event_set = event_set_init (&c->c2.event_set_max, flags); c->c2.event_set_owned = true;}static voiddo_close_event_set (struct context *c){ if (c->c2.event_set_owned) { event_free (c->c2.event_set); }}/* * Initialize a tunnel instance. */voidinit_instance (struct context *c){ const struct options *options = &c->options; const bool child = (c->mode == CM_CHILD_TCP || c->mode == CM_CHILD_UDP); int link_socket_mode = LS_MODE_DEFAULT; /* link_socket_mode allows CM_CHILD_TCP instances to inherit acceptable fds from a top-level parent */ if (c->options.proto == PROTO_TCPv4_SERVER) { if (c->mode == CM_TOP) link_socket_mode = LS_MODE_TCP_LISTEN; else if (c->mode == CM_CHILD_TCP) link_socket_mode = LS_MODE_TCP_ACCEPT_FROM; } /* init garbage collection level */ gc_init (&c->c2.gc); /* signals caught here will abort */ c->sig->signal_received = 0; c->sig->signal_text = NULL; c->sig->hard = false; /* before full initialization, received signals will trigger exit */ if (c->first_time) pre_init_signal_catch (); /* initialize context level 2 --verb/--mute parms */ init_verb_mute (c, IVM_LEVEL_2); /* should we disable paging? */ if (c->first_time && options->mlock) do_mlockall (true); /* possible sleep if restart */ if ((c->mode == CM_P2P || c->mode == CM_TOP) && !c->first_time) socket_restart_pause (options->proto, options->http_proxy_server != NULL, options->socks_proxy_server != NULL); /* reset OCC state */ if (c->mode == CM_P2P || child) c->c2.occ_op = occ_reset_op (); /* our wait-for-i/o objects, different for posix vs. win32 */ if (c->mode == CM_P2P) do_event_set_init (c, SHAPER_DEFINED (&c->options)); else if (c->mode == CM_CHILD_TCP) do_event_set_init (c, false); /* allocate our socket object */ if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP) do_link_socket_new (c); /* initialize internal fragmentation object */ if (options->fragment && (c->mode == CM_P2P || child)) c->c2.fragment = fragment_init (&c->c2.frame); /* init crypto layer */ { unsigned int crypto_flags = 0; if (c->mode == CM_TOP) crypto_flags = CF_INIT_TLS_AUTH_STANDALONE; else if (c->mode == CM_P2P) crypto_flags = CF_LOAD_PERSISTED_PACKET_ID | CF_INIT_TLS_MULTI; else if (child) crypto_flags = CF_INIT_TLS_MULTI; do_init_crypto (c, crypto_flags); }#ifdef USE_LZO /* initialize LZO compression library. */ if (options->comp_lzo && (c->mode == CM_P2P || child)) lzo_compress_init (&c->c2.lzo_compwork, options->comp_lzo_adaptive);#endif /* initialize MTU variables */ do_init_frame (c); /* initialize TLS MTU variables */ do_init_frame_tls (c); /* init workspace buffers whose size is derived from frame size */ if (c->mode == CM_P2P || c->mode == CM_CHILD_TCP) do_init_buffers (c); /* initialize internal fragmentation capability with known frame size */ if (options->fragment && (c->mode == CM_P2P || child)) do_init_fragment (c); /* initialize dynamic MTU variable */ do_init_dynamic_mtu (c); /* bind the TCP/UDP socket */ if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP) do_init_socket_1 (c, link_socket_mode); /* initialize tun/tap device object, open tun/tap device, ifconfig, run up script, etc. */ if (!(options->up_delay || PULL_DEFINED (options)) && (c->mode == CM_P2P || c->mode == CM_TOP)) c->c2.did_open_tun = do_open_tun (c); /* print MTU info */ do_print_data_channel_mtu_parms (c); /* get local and remote options compatibility strings */ if (c->mode == CM_P2P || child) do_compute_occ_strings (c); /* initialize output speed limiter */ if (c->mode == CM_P2P) do_init_traffic_shaper (c); /* do one-time inits, and possibily become a daemon here */ do_init_first_time_1 (c); /* catch signals */ if (c->first_time) post_init_signal_catch (); /* * Do first-time initialization AFTER possible daemonization, * UID/GID downgrade, and chroot. */ do_init_first_time_2 (c); /* finalize the TCP/UDP socket */ if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP) { do_init_socket_2 (c); if (IS_SIG (c)) { c->sig->signal_text = "socket"; close_instance (c); return; } } /* initialize timers */ if (c->mode == CM_P2P || child) do_init_timers (c, false);}/* * Close a tunnel instance. */voidclose_instance (struct context *c){ /* close event objects */ do_close_event_set (c); if (c->mode == CM_P2P || c->mode == CM_CHILD_TCP || c->mode == CM_CHILD_UDP || c->mode == CM_TOP) { /* if xinetd/inetd mode, don't allow restart */ do_close_check_if_restart_permitted (c);#ifdef USE_LZO if (c->options.comp_lzo) lzo_compress_uninit (&c->c2.lzo_compwork);#endif /* remove non-parameter environmental vars except for signal */ if (c->mode == CM_P2P || c->mode == CM_TOP) do_close_remove_env (c); /* free buffers */ do_close_free_buf (c); /* close TLS */ do_close_tls (c); /* free key schedules */ do_close_free_key_schedule (c, (c->mode == CM_P2P || c->mode == CM_TOP)); /* close TCP/UDP connection */ do_close_link_socket (c); /* close TUN/TAP device */ do_close_tuntap (c); /* close packet-id persistance file */ do_close_packet_id (c); /* close --status file */ do_close_status_output (c); /* close fragmentation handler */ do_close_fragment (c); /* close syslog */ if (c->mode == CM_P2P || c->mode == CM_TOP) do_close_syslog (c); /* garbage collect */ gc_free (&c->c2.gc); }}voidinherit_context_child (struct context *dest, const struct context *src){ CLEAR (*dest); switch (src->options.proto) { case PROTO_UDPv4: dest->mode = CM_CHILD_UDP; break; case PROTO_TCPv4_SERVER: dest->mode = CM_CHILD_TCP; break; default: ASSERT (0); } dest->first_time = false; dest->gc = gc_new (); ALLOC_OBJ_CLEAR_GC (dest->sig, struct signal_info, &dest->gc); /* c1 init */ packet_id_persist_init (&dest->c1.pid_persist);#ifdef USE_CRYPTO dest->c1.ks.key_type = src->c1.ks.key_type;#ifdef USE_SSL /* inherit SSL context */ dest->c1.ks.ssl_ctx = src->c1.ks.ssl_ctx; dest->c1.ks.tls_auth_key = src->c1.ks.tls_auth_key;#endif#endif /* options */ dest->options = src->options; options_detach (&dest->options); /* context init */ init_instance (dest); if (IS_SIG (dest)) return; /* inherit tun/tap interface object */ dest->c1.tuntap = src->c1.tuntap; /* UDP inherits some extra things which TCP does not */ if (dest->mode == CM_CHILD_UDP) { /* inherit buffers */ dest->c2.buffers = src->c2.buffers; /* inherit parent link_socket and tuntap */ dest->c2.link_socket = src->c2.link_socket; ALLOC_OBJ_GC (dest->c2.link_socket_info, struct link_socket_info, &dest->gc); *dest->c2.link_socket_info = src->c2.link_socket->info; /* locally override some link_socket_info fields */ dest->c2.link_socket_info->lsa = &dest->c1.link_socket_addr; dest->c2.link_socket_info->connection_established = false; } else if (dest->mode == CM_CHILD_TCP) { /* * The CM_TOP context does the socket listen(), * and the CM_CHILD_TCP context does the accept(). */ dest->c2.accept_from = src->c2.link_socket; }}voidinherit_context_thread (struct context *dest, const struct context *src){ *dest = *src; dest->mode = CM_THREAD; dest->first_time = false; options_detach (&dest->options); gc_detach (&dest->gc); gc_detach (&dest->c2.gc);#if defined(USE_CRYPTO) && defined(USE_SSL) dest->c2.tls_multi = NULL;#endif dest->c1.tuntap_owned = false; dest->c1.status_output_owned = false; dest->c2.link_socket_owned = false; dest->c2.buffers_owned = false; dest->c2.event_set_owned = false; do_event_set_init (dest, false);}voidclose_context (struct context *c, int sig){ if (sig >= 0) c->sig->signal_received = sig; close_instance (c); context_gc_free (c);}#ifdef USE_CRYPTOstatic voidtest_malloc (void){ int i, j; msg (M_INFO, "Multithreaded malloc test..."); for (i = 0; i < 25; ++i) { struct gc_arena gc = gc_new (); const int limit = get_random () & 0x03FF; for (j = 0; j < limit; ++j) { gc_malloc (get_random () & 0x03FF, false, &gc); } gc_free (&gc); }}/* * Do a loopback test * on the crypto subsystem. */static void *test_crypto_thread (void *arg){ struct context *c = (struct context *) arg; const struct options *options = &c->options;#if defined(USE_PTHREAD) struct context *child = NULL; openvpn_thread_t child_id = 0;#endif ASSERT (options->test_crypto); init_verb_mute (c, IVM_LEVEL_1); context_init_1 (c); do_init_crypto_static (c, 0);#if defined(USE_PTHREAD) { if (c->first_time && options->n_threads > 1) { if (options->n_threads > 2) msg (M_FATAL, "ERROR: --test-crypto option only works with --threads set to 1 or 2"); openvpn_thread_init (); ALLOC_OBJ (child, struct context); context_clear (child); child->options = *options; options_detach (&child->options); child->first_time = false; child_id = openvpn_thread_create (test_crypto_thread, (void *) child); } }#endif frame_finalize_options (&c->c2.frame, options);#if defined(USE_PTHREAD) if (options->n_threads == 2) test_malloc ();#endif test_crypto (&c->c2.crypto_options, &c->c2.frame); key_schedule_free (&c->c1.ks, true);#if defined(USE_PTHREAD) if (c->first_time && options->n_threads > 1) openvpn_thread_join (child_id); if (child) free (child);#endif context_gc_free (c); return NULL;}#endifbooldo_test_crypto (const struct options *o){#ifdef USE_CRYPTO if (o->test_crypto) { struct context c; context_clear (&c); c.options = *o; options_detach (&c.options); c.first_time = true; test_crypto_thread ((void *) &c); return true; }#endif return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -