⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openvpn.c

📁 OpenVPN -- A Secure tunneling daemon
💻 C
📖 第 1 页 / 共 4 页
字号:
		   * Setup for call to sendto() which will send		   * packet to remote over the UDP port.		   */		  int size;		  ASSERT (addr_defined (&to_udp_addr));		  /* In gremlin-test mode, we may choose to drop this packet */		  if (!options->gremlin || ask_gremlin())		    {		      /*		       * Let the traffic shaper know how many bytes		       * we wrote.		       */#ifdef HAVE_GETTIMEOFDAY		      if (options->shaper)			shaper_wrote_bytes (&shaper, BLEN (&to_udp)					    + datagram_overhead (ipv6_udp_transport));#endif#ifdef FRAGMENT_ENABLE		      if (fragment)			fragment_post_send (fragment, BLEN (&to_udp)					    + datagram_overhead (ipv6_udp_transport));#endif		      /*		       * Let the pinger know that we sent a packet.		       */		      if (options->ping_send_timeout)			event_timeout_reset (&ping_send_interval, current);#if PASSTOS_CAPABILITY		      /* Set TOS */		      if (ptos_defined)			setsockopt(udp_socket.sd, IPPROTO_IP, IP_TOS, &ptos, sizeof(ptos));#endif		      /* Send packet */		      size = sendto (udp_socket.sd, BPTR (&to_udp), BLEN (&to_udp), 0,				     (struct sockaddr *) &to_udp_addr,				     (socklen_t) sizeof (to_udp_addr));		      if (size > 0)			udp_write_bytes += size;		    }		  else		    size = 0;		  /* Check sendto() return status */		  check_status (size, "write to UDP", &udp_socket);		  if (size > 0)		    {		      /* Did we write a different size packet than we intended? */		      if (size != BLEN (&to_udp))			msg (D_LINK_ERRORS,			     "UDP packet was truncated/expanded on write to %s (tried=%d,actual=%d)",			     print_sockaddr (&to_udp_addr),			     BLEN (&to_udp),			     size);		    }		  /* Log packet send */#ifdef LOG_RW		  if (check_debug_level (D_LOG_RW) && !check_debug_level (D_LOG_RW + 1))		    fprintf (stderr, "W");#endif		  msg (D_UDP_RW, "UDP WRITE [%d] to %s: %s",		       BLEN (&to_udp), print_sockaddr (&to_udp_addr), PROTO_DUMP (&to_udp));		}	      else		{		  msg (D_LINK_ERRORS, "UDP packet too large on write to %s (tried=%d,max=%d)",		       print_sockaddr (&to_udp_addr),		       to_udp.len,		       max_rw_size_udp);		}	      /*	       * The free_to_udp flag means that we should free the packet buffer	       * after send.  This flag is usually set when the TLS background	       * thread generated the packet buffer.	       */	      if (free_to_udp)		{		  free_to_udp = false;		  free_buf (&to_udp);		}	      to_udp = nullbuf;	    }	}    }  /*   *  Do Cleanup   */  if (free_to_udp)    free_buf (&to_udp);    #if defined(USE_CRYPTO) && defined(USE_SSL) && defined(USE_PTHREAD)  if (tls_multi)    tls_thread_close (&thread_parms);#endif  free_buf (&read_udp_buf);  free_buf (&read_tun_buf);  free_buf (&ping_buf);#ifdef USE_LZO  if (options->comp_lzo)    {      lzo_compress_uninit (&lzo_compwork);      free_buf (&lzo_compress_buf);      free_buf (&lzo_decompress_buf);    }#endif#ifdef USE_CRYPTO  free_buf (&encrypt_buf);  free_buf (&decrypt_buf);#ifdef USE_SSL  if (tls_multi)    tls_multi_free (tls_multi, true);  if (data_channel_options)    free (data_channel_options);#endif#endif /* USE_CRYPTO */  /*   * Free key schedules   */  if ( !(signal_received == SIGUSR1 && options->persist_key) )    key_schedule_free (ks);  /*   * Close UDP connection   */  udp_socket_close (&udp_socket);  if ( !(signal_received == SIGUSR1 && options->persist_remote_ip) )    {      CLEAR (udp_socket_addr->remote);      CLEAR (udp_socket_addr->actual);    }  if ( !(signal_received == SIGUSR1 && options->persist_local_ip) )    CLEAR (udp_socket_addr->local);  /*   * Close TUN/TAP device   */  if ( !(signal_received == SIGUSR1 && options->persist_tun) )    {      char* tuntap_actual = (char *) gc_malloc (sizeof (tuntap->actual));      strcpy (tuntap_actual, tuntap->actual);      msg (M_INFO, "Closing TUN/TAP device");      close_tun (tuntap);      /* Run the down script -- note that it will run at reduced	 privilege if, for example, "--user nobody" was used. */      run_script (options->down_script, tuntap_actual, TUN_MTU_SIZE (&frame),		  max_rw_size_udp, options->ifconfig_local, options->ifconfig_remote);    }#ifdef USE_CRYPTO  /*   * Close packet-id persistance file   */  packet_id_persist_save (pid_persist);  if ( !(signal_received == SIGUSR1) )    packet_id_persist_close (pid_persist);#endif  /*   * Close fragmentation handler.   */#ifdef FRAGMENT_ENABLE  if (fragment)    fragment_free (fragment);#endif done:  /* pop our garbage collection level */  gc_free_level (gc_level);  /* return the signal that brought us here */  {    int s = signal_received;    signal_received = 0;    return s;  }}intmain (int argc, char *argv[]){  const int gc_level = gc_new_level ();  bool first_time = true;  int sig;#ifdef WIN32  init_win32 ();#endif  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 OPENVPN_DEBUG_COMMAND_LINE  {    int i;    for (i = 0; i < argc; ++i)      msg (M_INFO, "argv[%d] = '%s'", i, argv[i]);  }#endif#ifdef PID_TEST  packet_id_interactive_test();  /* test the sequence number code */  goto exit;#endif  do {    struct options options;    init_options (&options);    /*     * Parse command line options,     * and read configuration file.     */    parse_argv (&options, argc, argv);    /*     * OpenSSL info print mode?     */#ifdef USE_CRYPTO    if (options.show_ciphers || options.show_digests#ifdef USE_SSL	|| options.show_tls_ciphers#endif	)      {	if (first_time)	  init_ssl_lib ();	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	free_ssl_lib ();	goto exit;      }    /*     * Possibly set --dev based on --dev-node.     * For example, if --dev-node /tmp/foo/tun, and --dev undefined,     * set --dev to tun.     */    if (!options.dev)      options.dev = dev_component_in_dev_node (options.dev_node);    /*     * Static pre-shared key generation mode?     */    if (options.genkey)      {	struct key key;	notnull (options.shared_secret_file,		 "shared secret output file (--secret)");	if (options.mlock)    /* should we disable paging? */	  do_mlockall(true);	generate_key_random (&key, NULL);	write_key_file (&key, options.shared_secret_file);	CLEAR (key);	goto exit;      }#endif /* USE_CRYPTO */    /*     * Persistent TUN/TAP device management mode?     */#ifdef TUNSETPERSIST    if (options.persist_config)      {	/* sanity check on options for --mktun or --rmtun */	notnull (options.dev, "TUN/TAP device (--dev)");	if (options.remote || options.ifconfig_local || options.ifconfig_remote#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);	goto exit;      }#endif    /*     * Main OpenVPN block -- tunnel generation mode     */    {#ifdef USE_CRYPTO      if (options.test_crypto)	{	  notnull (options.shared_secret_file, "key file (--secret)");	}      else#endif	notnull (options.dev, "TUN/TAP device (--dev)");      /*       * Sanity check on daemon/inetd modes       */      if (options.daemon && options.inetd)	{	  msg (M_WARN, "Options error: only one of --daemon or --inetd may be specified");	  usage_small ();	}      if (options.inetd && (options.local || options.remote))	{	  msg (M_WARN, "Options error: --local or --remote cannot be used with --inetd");	  usage_small ();	}      /*       * Sanity check on MTU parameters       */      if (options.tun_mtu_defined && options.udp_mtu_defined)	{	  msg (M_WARN, "Options error: only one of --tun-mtu or --udp-mtu may be defined (note that --ifconfig implies --udp-mtu %d)", UDP_MTU_DEFAULT);	  usage_small ();	}      /*       * If neither --tun-mtu or --udp-mtu specified,       * use default --udp-mtu if --ifconfig specified, otherwise       * use default --tun-mtu.       */      if (!options.tun_mtu_defined && !options.udp_mtu_defined)	{	  if (options.ifconfig_local || options.ifconfig_remote)	    options.udp_mtu_defined = true;	  else	    options.tun_mtu_defined = true;	}      /*       * Sanity check on --local, --remote, and ifconfig       */      if (string_defined_equal (options.local, options.remote)	  && options.local_port == options.remote_port)	{	  msg (M_WARN, "Options error: --remote and --local addresses are the same");	  usage_small ();	}	      if (string_defined_equal (options.local, options.ifconfig_local)	  || string_defined_equal (options.local, options.ifconfig_remote)	  || string_defined_equal (options.remote, options.ifconfig_local)	  || string_defined_equal (options.remote, options.ifconfig_remote))	{	  msg (M_WARN, "Options error: --local and --remote addresses must be distinct from --ifconfig addresses");	  usage_small ();	}      if (string_defined_equal (options.ifconfig_local, options.ifconfig_remote))	{	  msg (M_WARN, "Options error: local and remote --ifconfig addresses must be different");	  usage_small ();	}#ifdef USE_CRYPTO      if (first_time)	init_ssl_lib ();#ifdef USE_SSL      if (options.tls_server + options.tls_client +	  (options.shared_secret_file != NULL) > 1)	{	  msg (M_WARN, "specify only one of --tls-server, --tls-client, or --secret");	  usage_small ();	}      if (options.tls_server)	{	  notnull (options.dh_file, "DH file (--dh)");	}      if (options.tls_server || options.tls_client)	{	  notnull (options.ca_file, "CA file (--ca)");	  notnull (options.cert_file, "certificate file (--cert)");	  notnull (options.priv_key_file, "private key file (--key)");	  if (first_time && options.askpass)	    pem_password_callback (NULL, 0, 0, NULL);	}      else	{	  /*	   * Make sure user doesn't specify any TLS options	   * when in non-TLS mode.	   */#define MUST_BE_UNDEF(parm) if (options.parm != def.parm) msg (M_FATAL, err, #parm);	  const char err[] = "Parameter %s can only be specified in TLS-mode, i.e. where --tls-server or --tls-client is also specified.";	  struct options def;	  init_options (&def);	  MUST_BE_UNDEF (ca_file);	  MUST_BE_UNDEF (dh_file);	  MUST_BE_UNDEF (cert_file);	  MUST_BE_UNDEF (priv_key_file);	  MUST_BE_UNDEF (cipher_list);	  MUST_BE_UNDEF (tls_verify);	  MUST_BE_UNDEF (tls_timeout);	  MUST_BE_UNDEF (renegotiate_bytes);	  MUST_BE_UNDEF (renegotiate_packets);	  MUST_BE_UNDEF (renegotiate_seconds);	  MUST_BE_UNDEF (handshake_window);	  MUST_BE_UNDEF (transition_window);	  MUST_BE_UNDEF (tls_auth_file);	  MUST_BE_UNDEF (single_session);	  MUST_BE_UNDEF (disable_occ);	}#undef MUST_BE_UNDEF#endif /* USE_CRYPTO */#endif /* USE_SSL */      set_check_status (D_LINK_ERRORS, D_READ_WRITE);      set_debug_level (options.verbosity);      set_mute_cutoff (options.mute);      /* Become a daemon if requested */      possibly_become_daemon (0, &options, first_time);      /* show all option settings */      show_settings (&options);      /* Do Work */      {	/* these objects are potentially persistent across SIGUSR1 resets */	struct udp_socket_addr usa;	struct key_schedule ks;	struct tuntap tuntap;	struct packet_id_persist pid_persist;	CLEAR (usa);	CLEAR (ks);	clear_tuntap (&tuntap);	packet_id_persist_init (&pid_persist);	do {	  sig = openvpn (&options, &usa, &tuntap, &ks, &pid_persist, first_time);	  first_time = false;	} while (sig == SIGUSR1);      }    }    gc_collect (gc_level);    close_syslog ();  } while (sig == SIGHUP);  thread_cleanup();#ifdef USE_CRYPTO  free_ssl_lib ();#endif#ifdef WIN32  uninit_win32 ();#endif exit:#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(USE_CRYPTO) && defined(USE_SSL)  show_tls_performance_stats();#endif  /* pop our garbage collection level */  gc_free_level (gc_level);  return OPENVPN_EXIT_STATUS_GOOD; /* exit point */}/* * Basic threading test. */#if defined(USE_PTHREAD) && defined(USE_CRYPTO)static void*test_crypto_thread (void *arg){  struct udp_socket_addr usa;  struct tuntap tuntap;  struct key_schedule ks;  struct packet_id_persist pid_persist;  const struct options *opt = (struct options*) arg;  set_nice (opt->nice_work);  CLEAR (usa);  CLEAR (ks);  clear_tuntap (&tuntap);  packet_id_persist_init (&pid_persist);  openvpn (opt, &usa, &tuntap, &ks, &pid_persist, false);  return NULL;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -