📄 init.c
字号:
static voiddo_init_finalize_tls_frame (struct context *c){ if (c->c2.tls_multi) { tls_multi_init_finalize (c->c2.tls_multi, &c->c2.frame); ASSERT (EXPANDED_SIZE (&c->c2.tls_multi->opt.frame) <= EXPANDED_SIZE (&c->c2.frame)); frame_print (&c->c2.tls_multi->opt.frame, D_MTU_INFO, "Control Channel MTU parms"); } if (c->c2.tls_auth_standalone) { tls_auth_standalone_finalize (c->c2.tls_auth_standalone, &c->c2.frame); frame_print (&c->c2.tls_auth_standalone->frame, D_MTU_INFO, "TLS-Auth MTU parms"); }}#endif /* USE_SSL */#endif /* USE_CRYPTO */#ifdef USE_CRYPTO/* * No encryption or authentication. */static voiddo_init_crypto_none (const struct context *c){ ASSERT (!c->options.test_crypto); msg (M_WARN, "******* WARNING *******: all encryption and authentication features disabled -- all data will be tunnelled as cleartext");}#endifstatic voiddo_init_crypto (struct context *c, const unsigned int flags){#ifdef USE_CRYPTO if (c->options.shared_secret_file) do_init_crypto_static (c, flags);#ifdef USE_SSL else if (c->options.tls_server || c->options.tls_client) do_init_crypto_tls (c, flags);#endif else /* no encryption or authentication. */ do_init_crypto_none (c);#else /* USE_CRYPTO */ msg (M_WARN, "******* WARNING *******: " PACKAGE_NAME " built without OpenSSL -- encryption and authentication features disabled -- all data will be tunnelled as cleartext");#endif /* USE_CRYPTO */}static voiddo_init_frame (struct context *c){#ifdef USE_LZO /* * Initialize LZO compression library. */ if (c->options.comp_lzo) { lzo_adjust_frame_parameters (&c->c2.frame); lzo_adjust_frame_parameters (&c->c2.frame_fragment_omit); /* omit LZO frame delta from final frame_fragment */ }#endif /* * Adjust frame size for UDP Socks support. */ if (c->options.socks_proxy_server) socks_adjust_frame_parameters (&c->c2.frame, c->options.proto); /* * Adjust frame size based on the --tun-mtu-extra parameter. */ if (c->options.tun_mtu_extra_defined) tun_adjust_frame_parameters (&c->c2.frame, c->options.tun_mtu_extra); /* * Adjust frame size based on link socket parameters. * (Since TCP is a stream protocol, we need to insert * a packet length uint16_t in the buffer.) */ socket_adjust_frame_parameters (&c->c2.frame, c->options.proto); /* * Fill in the blanks in the frame parameters structure, * make sure values are rational, etc. */ frame_finalize_options (&c->c2.frame, &c->options); /* * Set frame parameter for fragment code. This is necessary because * the fragmentation code deals with payloads which have already been * passed through the compression code. */ c->c2.frame_fragment = c->c2.frame; frame_subtract_extra (&c->c2.frame_fragment, &c->c2.frame_fragment_omit); /* * MTU advisories */ if (c->options.fragment && c->options.mtu_test) msg (M_WARN, "WARNING: using --fragment and --mtu-test together may produce an inaccurate MTU test result"); if ((c->options.mssfix || c->options.fragment) && TUN_MTU_SIZE (&c->c2.frame_fragment) != ETHERNET_MTU) msg (M_WARN, "WARNING: normally if you use --mssfix and/or --fragment, you should also set --tun-mtu %d (currently it is %d)", ETHERNET_MTU, TUN_MTU_SIZE (&c->c2.frame_fragment));}static voiddo_init_frame_tls (struct context *c){#if defined(USE_CRYPTO) && defined(USE_SSL) do_init_finalize_tls_frame (c);#endif}struct context_buffers *init_context_buffers (const struct frame *frame){ struct context_buffers *b; ALLOC_OBJ_CLEAR (b, struct context_buffers); b->read_link_buf = alloc_buf (BUF_SIZE (frame)); b->read_tun_buf = alloc_buf (BUF_SIZE (frame)); b->aux_buf = alloc_buf (BUF_SIZE (frame));#ifdef USE_CRYPTO b->encrypt_buf = alloc_buf (BUF_SIZE (frame)); b->decrypt_buf = alloc_buf (BUF_SIZE (frame));#endif#ifdef USE_LZO b->lzo_compress_buf = alloc_buf (BUF_SIZE (frame)); b->lzo_decompress_buf = alloc_buf (BUF_SIZE (frame));#endif return b;}voidfree_context_buffers (struct context_buffers *b){ if (b) { free_buf (&b->read_link_buf); free_buf (&b->read_tun_buf); free_buf (&b->aux_buf);#ifdef USE_LZO free_buf (&b->lzo_compress_buf); free_buf (&b->lzo_decompress_buf);#endif#ifdef USE_CRYPTO free_buf (&b->encrypt_buf); free_buf (&b->decrypt_buf);#endif free (b); }}/* * Now that we know all frame parameters, initialize * our buffers. */static voiddo_init_buffers (struct context *c){ c->c2.buffers = init_context_buffers (&c->c2.frame); c->c2.buffers_owned = true;}/* * Fragmenting code has buffers to initialize * once frame parameters are known. */static voiddo_init_fragment (struct context *c){ ASSERT (c->options.fragment); frame_set_mtu_dynamic (&c->c2.frame_fragment, c->options.fragment, SET_MTU_UPPER_BOUND); fragment_frame_init (c->c2.fragment, &c->c2.frame_fragment);}/* * Set the dynamic MTU parameter, used by the --mssfix * option. */static voiddo_init_dynamic_mtu (struct context *c){ if (c->options.mssfix) { frame_set_mtu_dynamic (&c->c2.frame, c->options.mssfix, SET_MTU_UPPER_BOUND); }}/* * Allocate our socket object. */static voiddo_link_socket_new (struct context *c){ ASSERT (!c->c2.link_socket); c->c2.link_socket = link_socket_new (); c->c2.link_socket_owned = true;}/* * bind the TCP/UDP socket */static voiddo_init_socket_1 (struct context *c, int mode){ link_socket_init_phase1 (c->c2.link_socket, c->options.local, c->c1.remote_list, c->options.local_port, c->options.proto, mode, c->c2.accept_from, c->c1.http_proxy, c->c1.socks_proxy, c->options.bind_local, c->options.remote_float, c->options.inetd, &c->c1.link_socket_addr, c->options.ipchange, c->options.resolve_retry_seconds, c->options.connect_retry_seconds, c->options.mtu_discover_type, c->options.rcvbuf, c->options.sndbuf);}/* * finalize the TCP/UDP socket */static voiddo_init_socket_2 (struct context *c){ link_socket_init_phase2 (c->c2.link_socket, &c->c2.frame, &c->sig->signal_received);}/* * Print MTU INFO */static voiddo_print_data_channel_mtu_parms (struct context *c){ frame_print (&c->c2.frame, D_MTU_INFO, "Data Channel MTU parms"); if (c->c2.fragment) frame_print (&c->c2.frame_fragment, D_MTU_INFO, "Fragmentation MTU parms");}/* * Get local and remote options compatibility strings. */static voiddo_compute_occ_strings (struct context *c){ struct gc_arena gc = gc_new (); c->c2.options_string_local = options_string (&c->options, &c->c2.frame, c->c1.tuntap, false, &gc); c->c2.options_string_remote = options_string (&c->options, &c->c2.frame, c->c1.tuntap, true, &gc); msg (D_SHOW_OCC, "Local Options String: '%s'", c->c2.options_string_local); msg (D_SHOW_OCC, "Expected Remote Options String: '%s'", c->c2.options_string_remote);#ifdef USE_CRYPTO msg (D_SHOW_OCC_HASH, "Local Options hash (VER=%s): '%s'", options_string_version (c->c2.options_string_local, &gc), md5sum (c->c2.options_string_local, strlen (c->c2.options_string_local), 9, &gc)); msg (D_SHOW_OCC_HASH, "Expected Remote Options hash (VER=%s): '%s'", options_string_version (c->c2.options_string_remote, &gc), md5sum (c->c2.options_string_remote, strlen (c->c2.options_string_remote), 9, &gc));#endif#if defined(USE_CRYPTO) && defined(USE_SSL) if (c->c2.tls_multi) tls_multi_init_set_options (c->c2.tls_multi, c->c2.options_string_local, c->c2.options_string_remote);#endif gc_free (&gc);}/* * These things can only be executed once per program instantiation. */static voiddo_init_first_time_1 (struct context *c){ if (c->first_time) { /* get user and/or group that we want to setuid/setgid to */ get_group (c->options.groupname, &c->c2.group_state); get_user (c->options.username, &c->c2.user_state); /* get --writepid file descriptor */ get_pid_file (c->options.writepid, &c->c2.pid_state); /* chroot if requested */ if (c->options.chroot_dir) do_chroot (c->options.chroot_dir); } /* become a daemon if --daemon */ c->c2.did_we_daemonize = possibly_become_daemon (&c->options, c->first_time);}/* * Do first-time initialization AFTER possible daemonization, * UID/GID downgrade, and chroot. */static voiddo_init_first_time_2 (struct context *c){ if (c->first_time) { /* should we disable paging? */ if (c->options.mlock && c->c2.did_we_daemonize) do_mlockall (true); /* call again in case we daemonized */ /* should we change scheduling priority? */ set_nice (c->options.nice); /* set user and/or group that we want to setuid/setgid to */ set_group (&c->c2.group_state); set_user (&c->c2.user_state); /* save process ID in a file */ write_pid (&c->c2.pid_state); }}/* * If xinetd/inetd mode, don't allow restart. */static voiddo_close_check_if_restart_permitted (struct context *c){ if (c->options.inetd && (c->sig->signal_received == SIGHUP || c->sig->signal_received == SIGUSR1)) { c->sig->signal_received = SIGTERM; msg (M_INFO, PACKAGE_NAME " started by inetd/xinetd cannot restart... Exiting."); }}/* * free buffers */static voiddo_close_free_buf (struct context *c){ if (c->c2.buffers_owned) { free_context_buffers (c->c2.buffers); c->c2.buffers = NULL; }}/* * close TLS */static voiddo_close_tls (struct context *c){#if defined(USE_CRYPTO) && defined(USE_SSL) if (c->c2.tls_multi) { tls_multi_free (c->c2.tls_multi, true); c->c2.tls_multi = NULL; } /* free options compatibility strings */ if (c->c2.options_string_local) free (c->c2.options_string_local); if (c->c2.options_string_remote) free (c->c2.options_string_remote);#endif}/* * Free key schedules */static voiddo_close_free_key_schedule (struct context *c, bool free_ssl_ctx){ if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_key)) key_schedule_free (&c->c1.ks, free_ssl_ctx);}/* * Close TCP/UDP connection */static voiddo_close_link_socket (struct context *c){ if (c->c2.link_socket && c->c2.link_socket_owned) link_socket_close (c->c2.link_socket); c->c2.link_socket = NULL; if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_remote_ip)) { CLEAR (c->c1.link_socket_addr.remote); CLEAR (c->c1.link_socket_addr.actual); } if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip)) CLEAR (c->c1.link_socket_addr.local);}/* * Close TUN/TAP device */static voiddo_close_tuntap (struct context *c){ struct gc_arena gc = gc_new (); if (c->c1.tuntap && c->c1.tuntap_owned) { const char *tuntap_actual = string_alloc (c->c1.tuntap->actual_name, &gc); const in_addr_t local = c->c1.tuntap->local; const in_addr_t remote_netmask = c->c1.tuntap->remote_netmask; if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_tun)) { /* delete any routes we added */ if (c->c1.route_list) delete_routes (c->c1.route_list); msg (D_CLOSE, "Closing TUN/TAP interface"); close_tun (c->c1.tuntap); c->c1.tuntap = NULL; /* Run the down script -- note that it will run at reduced privilege if, for example, "--user nobody" was used. */ run_script (c->options.down_script, tuntap_actual, TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (local, true, &gc), print_in_addr_t (remote_netmask, true, &gc), "init", signal_description (c->sig->signal_received, c->sig->signal_text), "down"); } else { /* run the down script on this restart if --up-restart was specified */ if (c->options.up_restart) run_script (c->options.down_script, tuntap_actual, TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (local, true, &gc), print_in_addr_t (remote_netmask, true, &gc), "restart", signal_description (c->sig->signal_received, c->sig->signal_text), "down"); } } gc_free (&gc);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -