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

📄 socket.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
📖 第 1 页 / 共 4 页
字号:
      new_sd = -1;    }  return new_sd;}static voidtcp_connection_established (const struct sockaddr_in *remote){  struct gc_arena gc = gc_new ();  msg (M_INFO, "TCP connection established with %s",        print_sockaddr (remote, &gc));  gc_free (&gc);}static intsocket_listen_accept (socket_descriptor_t sd,		      struct sockaddr_in *remote,		      const char *remote_dynamic,		      bool *remote_changed,		      const struct sockaddr_in *local,		      bool do_listen,		      bool nowait,		      volatile int *signal_received){  struct gc_arena gc = gc_new ();  struct sockaddr_in remote_verify = *remote;  int new_sd = -1;  socket_do_listen (sd, local, do_listen, true);  while (true)    {      int status;      fd_set reads;      struct timeval tv;      FD_ZERO (&reads);      FD_SET (sd, &reads);      tv.tv_sec = 5;      tv.tv_usec = 0;      status = select (sd + 1, &reads, NULL, NULL, &tv);      get_signal (signal_received);      if (*signal_received)	{	  gc_free (&gc);	  return sd;	}      if (status < 0)	msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: select() failed");      if (status <= 0)	continue;      new_sd = socket_do_accept (sd, remote, nowait);      if (new_sd >= 0)	{	  update_remote (remote_dynamic, &remote_verify, remote_changed);	  if (addr_defined (&remote_verify)	      && !addr_match (&remote_verify, remote))	    {	      msg (M_WARN,		   "TCP NOTE: Rejected connection attempt from %s due to --remote setting",		   print_sockaddr (remote, &gc));	      if (openvpn_close_socket (new_sd))		msg (M_SOCKERR, "TCP: close socket failed (new_sd)");	    }	  else	    break;	}      sleep (1);    }  if (!nowait && openvpn_close_socket (sd))    msg (M_SOCKERR, "TCP: close socket failed (sd)");  tcp_connection_established (remote);  gc_free (&gc);  return new_sd;}static voidsocket_connect (socket_descriptor_t *sd,		struct sockaddr_in *remote,		struct remote_list *remote_list,		const char *remote_dynamic,		bool *remote_changed,		const int connect_retry_seconds,		volatile int *signal_received){  struct gc_arena gc = gc_new ();  msg (M_INFO, "Attempting to establish TCP connection with %s",        print_sockaddr (remote, &gc));  while (true)    {      const int status = connect (*sd, (struct sockaddr *) remote,				  sizeof (*remote));      get_signal (signal_received);      if (*signal_received)	goto done;      if (!status)	break;      msg (D_LINK_ERRORS | M_ERRNO_SOCK,	   "TCP: connect to %s failed, will try again in %d seconds",	   print_sockaddr (remote, &gc),	   connect_retry_seconds);      openvpn_close_socket (*sd);      sleep (connect_retry_seconds);      if (remote_list)	{	  remote_list_next (remote_list);	  remote_dynamic = remote_list_host (remote_list);	  remote->sin_port = htons (remote_list_port (remote_list));	  *remote_changed = true;	}      *sd = create_socket_tcp ();      update_remote (remote_dynamic, remote, remote_changed);    }  msg (M_INFO, "TCP connection established with %s",        print_sockaddr (remote, &gc)); done:  gc_free (&gc);}/* For stream protocols, allocate a buffer to build up packet.   Called after frame has been finalized. */static voidsocket_frame_init (const struct frame *frame, struct link_socket *sock){#ifdef WIN32  overlapped_io_init (&sock->reads, frame, FALSE, false);  overlapped_io_init (&sock->writes, frame, TRUE, false);  sock->rw_handle.read = sock->reads.overlapped.hEvent;  sock->rw_handle.write = sock->writes.overlapped.hEvent;#endif  if (link_socket_connection_oriented (sock))    {#ifdef WIN32      stream_buf_init (&sock->stream_buf, &sock->reads.buf_init);#else      alloc_buf_sock_tun (&sock->stream_buf_data, frame, false);      stream_buf_init (&sock->stream_buf, &sock->stream_buf_data);#endif    }}/* * Adjust frame structure based on a Path MTU value given * to us by the OS. */voidframe_adjust_path_mtu (struct frame *frame, int pmtu, int proto){  frame_set_mtu_dynamic (frame, pmtu - datagram_overhead (proto), SET_MTU_UPPER_BOUND);}static voidresolve_bind_local (struct link_socket *sock){  struct gc_arena gc = gc_new ();  /* resolve local address if undefined */  if (!addr_defined (&sock->info.lsa->local))    {      sock->info.lsa->local.sin_family = AF_INET;      sock->info.lsa->local.sin_addr.s_addr =	(sock->local_host ? getaddr (				     GETADDR_RESOLVE				     | GETADDR_FATAL				     | GETADDR_FATAL_ON_SIGNAL,				     sock->local_host,				     0,				     NULL,				     NULL)	 : htonl (INADDR_ANY));      sock->info.lsa->local.sin_port = htons (sock->local_port);    }    /* bind to local address/port */  if (sock->bind_local)    {      if (bind (sock->sd, (struct sockaddr *) &sock->info.lsa->local,		sizeof (sock->info.lsa->local)))	{	  const int errnum = openvpn_errno_socket ();	  msg (M_FATAL, "TCP/UDP: Socket bind failed on local address %s: %s",	       print_sockaddr (&sock->info.lsa->local, &gc),	       strerror_ts (errnum, &gc));	}    }  gc_free (&gc);}static voidresolve_remote (struct link_socket *sock,		int phase,		const char **remote_dynamic,		volatile int *signal_received){  struct gc_arena gc = gc_new ();  if (!sock->did_resolve_remote)    {      /* resolve remote address if undefined */      if (!addr_defined (&sock->info.lsa->remote))	{	  sock->info.lsa->remote.sin_family = AF_INET;	  sock->info.lsa->remote.sin_addr.s_addr = 0;	  if (sock->remote_host)	    {	      unsigned int flags = 0;	      int retry = 0;	      bool status = false;	      if (phase == 1)		{		  if (sock->resolve_retry_seconds)		    {		      flags = GETADDR_RESOLVE;		      retry = 0;		    }		  else		    {		      flags = GETADDR_RESOLVE | GETADDR_FATAL | GETADDR_MENTION_RESOLVE_RETRY;		      retry = 0;		    }		}	      else if (phase == 2)		{		  if (sock->resolve_retry_seconds)		    {		      flags = GETADDR_RESOLVE | GETADDR_FATAL;		      retry = sock->resolve_retry_seconds;		    }		  else		    {		      ASSERT (0);		    }		}	      else		{		  ASSERT (0);		}	      sock->info.lsa->remote.sin_addr.s_addr = getaddr (		    flags,		    sock->remote_host,		    retry,		    &status,		    signal_received);	      if (!status || (signal_received && *signal_received))		goto done;	    }	  sock->info.lsa->remote.sin_port = htons (sock->remote_port);	}        /* should we re-use previous active remote address? */      if (addr_defined (&sock->info.lsa->actual))	{	  msg (M_INFO, "TCP/UDP: Preserving recently used remote address: %s",	       print_sockaddr (&sock->info.lsa->actual, &gc));	  if (remote_dynamic)	    *remote_dynamic = NULL;	}      else	sock->info.lsa->actual = sock->info.lsa->remote;      /* remember that we finished */      sock->did_resolve_remote = true;    } done:  gc_free (&gc);}struct link_socket *link_socket_new (void){  struct link_socket *sock;  ALLOC_OBJ_CLEAR (sock, struct link_socket);  sock->sd = -1;  sock->ctrl_sd = -1;  return sock;}/* bind socket if necessary */voidlink_socket_init_phase1 (struct link_socket *sock,			 const char *local_host,			 struct remote_list *remote_list,			 int local_port,			 int proto,			 int mode,			 const struct link_socket *accept_from,			 struct http_proxy_info *http_proxy,			 struct socks_proxy_info *socks_proxy,			 bool bind_local,			 bool remote_float,			 int inetd,			 struct link_socket_addr *lsa,			 const char *ipchange_command,			 int resolve_retry_seconds,			 int connect_retry_seconds,			 int mtu_discover_type,			 int rcvbuf,			 int sndbuf){  const char *remote_host;  int remote_port;  ASSERT (sock);  sock->remote_list = remote_list;  remote_list_next (remote_list);  remote_host = remote_list_host (remote_list);  remote_port = remote_list_port (remote_list);  sock->mode = mode;  if (mode == LS_MODE_TCP_ACCEPT_FROM)    {      ASSERT (accept_from);      sock->sd = accept_from->sd;    }  sock->local_host = local_host;  sock->local_port = local_port;  sock->http_proxy = http_proxy;  sock->socks_proxy = socks_proxy;  sock->bind_local = bind_local;  sock->inetd = inetd;  sock->resolve_retry_seconds = resolve_retry_seconds;  sock->connect_retry_seconds = connect_retry_seconds;  sock->mtu_discover_type = mtu_discover_type;  sock->socket_buffer_sizes.rcvbuf = rcvbuf;  sock->socket_buffer_sizes.sndbuf = sndbuf;  sock->info.proto = proto;  sock->info.remote_float = remote_float;  sock->info.lsa = lsa;  sock->info.ipchange_command = ipchange_command;  /* are we running in HTTP proxy mode? */  if (sock->http_proxy)    {      ASSERT (sock->info.proto == PROTO_TCPv4_CLIENT);      ASSERT (!sock->inetd);      /* the proxy server */      sock->remote_host = http_proxy->server;      sock->remote_port = http_proxy->port;      /* the OpenVPN server we will use the proxy to connect to */      sock->proxy_dest_host = remote_host;      sock->proxy_dest_port = remote_port;    }  /* or in Socks proxy mode? */  else if (sock->socks_proxy)    {      ASSERT (!sock->inetd);      /* the proxy server */      sock->remote_host = socks_proxy->server;      sock->remote_port = socks_proxy->port;      /* the OpenVPN server we will use the proxy to connect to */      sock->proxy_dest_host = remote_host;      sock->proxy_dest_port = remote_port;    }  else    {      sock->remote_host = remote_host;      sock->remote_port = remote_port;    }  /* bind behavior for TCP server vs. client */  if (sock->info.proto == PROTO_TCPv4_SERVER)    sock->bind_local = true;  else if (sock->info.proto == PROTO_TCPv4_CLIENT)    sock->bind_local = false;  /* were we started by inetd or xinetd? */  if (sock->inetd)    {      ASSERT (sock->info.proto != PROTO_TCPv4_CLIENT);      ASSERT (inetd_socket_descriptor >= 0);      sock->sd = inetd_socket_descriptor;    }  else    {      create_socket (sock);      resolve_bind_local (sock);      resolve_remote (sock, 1, NULL, NULL);    }}/* finalize socket initialization */voidlink_socket_init_phase2 (struct link_socket *sock,			 const struct frame *frame,			 volatile int *signal_received){  struct gc_arena gc = gc_new ();  const char *remote_dynamic = NULL;  bool remote_changed = false;  ASSERT (sock);  /* initialize buffers */  socket_frame_init (frame, sock);  /*   * Pass a remote name to connect/accept so that   * they can test for dynamic IP address changes   * and throw a SIGUSR1 if appropriate.   */  if (sock->resolve_retry_seconds)    remote_dynamic = sock->remote_host;  /* were we started by inetd or xinetd? */  if (sock->inetd)    {      if (sock->info.proto == PROTO_TCPv4_SERVER)	sock->sd =	  socket_listen_accept (sock->sd,				&sock->info.lsa->actual,				remote_dynamic,				&remote_changed,				&sock->info.lsa->local,				false,				sock->inetd == INETD_NOWAIT,				signal_received);      ASSERT (!remote_changed);      if (*signal_received)	goto done;    }  else    {      resolve_remote (sock, 2, &remote_dynamic, signal_received);      if (*signal_received)	goto done;      /* TCP client/server */      if (sock->info.proto == PROTO_TCPv4_SERVER)	{	  switch (sock->mode)	    {	    case LS_MODE_DEFAULT:	      sock->sd = socket_listen_accept (sock->sd,					       &sock->info.lsa->actual,					       remote_dynamic,					       &remote_changed,					       &sock->info.lsa->local,					       true,					       false,					       signal_received);	      break;	    case LS_MODE_TCP_LISTEN:	      socket_do_listen (sock->sd,				&sock->info.lsa->local,				true,				false);	      break;

⌨️ 快捷键说明

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