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

📄 socket.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
📖 第 1 页 / 共 4 页
字号:
	    case LS_MODE_TCP_ACCEPT_FROM:	      sock->sd = socket_do_accept (sock->sd,					   &sock->info.lsa->actual,					   false);	      if (sock->sd == -1)		{		  *signal_received = SIGTERM;		  goto done;		}	      tcp_connection_established (&sock->info.lsa->actual);	      break;	    default:	      ASSERT (0);	    }	}      else if (sock->info.proto == PROTO_TCPv4_CLIENT)	{	  socket_connect (&sock->sd,			  &sock->info.lsa->actual,			  sock->remote_list,			  remote_dynamic,			  &remote_changed,			  sock->connect_retry_seconds,			  signal_received);	  if (*signal_received)	    goto done;	  if (sock->http_proxy)	    {	      establish_http_proxy_passthru (sock->http_proxy,					     sock->sd,					     sock->proxy_dest_host,					     sock->proxy_dest_port,					     &sock->stream_buf.residual,					     signal_received);	    }	  else if (sock->socks_proxy)	    {	      establish_socks_proxy_passthru (sock->socks_proxy,					      sock->sd,					      sock->proxy_dest_host,					      sock->proxy_dest_port,					      signal_received);	    }	}      else if (sock->info.proto == PROTO_UDPv4 && sock->socks_proxy)	{	  socket_connect (&sock->ctrl_sd,			  &sock->info.lsa->actual,			  NULL,			  remote_dynamic,			  &remote_changed,			  sock->connect_retry_seconds,			  signal_received);	  if (*signal_received)	    goto done;	  establish_socks_proxy_udpassoc (sock->socks_proxy,					  sock->ctrl_sd,					  sock->sd, &sock->socks_relay,					  signal_received);	  if (*signal_received)	    goto done;	  sock->remote_host = sock->proxy_dest_host;	  sock->remote_port = sock->proxy_dest_port;	  sock->did_resolve_remote = false;	  sock->info.lsa->actual.sin_addr.s_addr = 0;	  sock->info.lsa->remote.sin_addr.s_addr = 0;	  resolve_remote (sock, 1, NULL, signal_received);	  if (*signal_received)	    goto done;	}            if (*signal_received)	goto done;      if (remote_changed)	{	  msg (M_INFO, "TCP/UDP: Dynamic remote address changed during TCP connection establishment");	  sock->info.lsa->remote.sin_addr.s_addr = sock->info.lsa->actual.sin_addr.s_addr;	}    }  /* set socket buffers based on --sndbuf and --rcvbuf options */  socket_set_buffers (sock->sd, &sock->socket_buffer_sizes);  /* set socket to non-blocking mode */  set_nonblock (sock->sd);  /* set socket file descriptor to not pass across execs, so that     scripts don't have access to it */  set_cloexec (sock->sd);  if (sock->ctrl_sd != -1)    set_cloexec (sock->ctrl_sd);  /* set Path MTU discovery options on the socket */  set_mtu_discover_type (sock->sd, sock->mtu_discover_type);#if EXTENDED_SOCKET_ERROR_CAPABILITY  /* if the OS supports it, enable extended error passing on the socket */  set_sock_extended_error_passing (sock->sd);#endif  /* print local address */  if (sock->inetd)    msg (M_INFO, "%s link local: [inetd]", proto2ascii (sock->info.proto, true));  else    msg (M_INFO, "%s link local%s: %s",	 proto2ascii (sock->info.proto, true),	 (sock->bind_local ? " (bound)" : ""),	 print_sockaddr_ex (&sock->info.lsa->local, sock->bind_local, ":", &gc));  /* print active remote address */  msg (M_INFO, "%s link remote: %s",       proto2ascii (sock->info.proto, true),       print_sockaddr_ex (&sock->info.lsa->actual, addr_defined (&sock->info.lsa->actual), ":", &gc)); done:  gc_free (&gc);}voidlink_socket_close (struct link_socket *sock){  if (sock)    {      if (sock->sd != -1)	{#ifdef WIN32	  overlapped_io_close (&sock->reads);	  overlapped_io_close (&sock->writes);#endif	  msg (D_CLOSE, "TCP/UDP: Closing socket");	  if (openvpn_close_socket (sock->sd))	    msg (M_WARN | M_ERRNO_SOCK, "TCP/UDP: Close Socket failed");	  sock->sd = -1;	}      if (sock->ctrl_sd != -1)	{	  if (openvpn_close_socket (sock->ctrl_sd))	    msg (M_WARN | M_ERRNO_SOCK, "TCP/UDP: Close Socket failed");	  sock->ctrl_sd = -1;	}      stream_buf_close (&sock->stream_buf);      free_buf (&sock->stream_buf_data);      free (sock);    }}/* for stream protocols, allow for packet length prefix */voidsocket_adjust_frame_parameters (struct frame *frame, int proto){  if (link_socket_proto_connection_oriented (proto))    frame_add_to_extra_frame (frame, sizeof (packet_size_type));}voidsetenv_trusted (const struct link_socket_info *info){  setenv_sockaddr ("trusted", &info->lsa->actual);}voidlink_socket_connection_initiated (const struct buffer *buf,				  struct link_socket_info *info,				  const struct sockaddr_in *addr,				  const char *common_name){  struct gc_arena gc = gc_new ();    /* acquire script mutex */  mutex_lock_static (L_SCRIPT);  info->lsa->actual = *addr; /* Note: skip this line for --force-dest */  setenv_trusted (info);  info->connection_established = true;  /* Print connection initiated message, with common name if available */  {    struct buffer out = alloc_buf_gc (256, &gc);    if (common_name)      buf_printf (&out, "[%s] ", common_name);    buf_printf (&out, "Peer Connection Initiated with %s", print_sockaddr (&info->lsa->actual, &gc));    msg (M_INFO, "%s", BSTR (&out));  }  /* Process --ipchange option */  if (info->ipchange_command)    {      struct buffer out = alloc_buf_gc (512, &gc);      setenv_str ("script_type", "ipchange");      buf_printf (&out, "%s %s",		  info->ipchange_command,		  print_sockaddr_ex (&info->lsa->actual, true, " ", &gc));      msg (D_TLS_DEBUG, "executing ip-change command: %s", BSTR (&out));      system_check (BSTR (&out), "ip-change command failed", false);    }  mutex_unlock_static (L_SCRIPT);  gc_free (&gc);}voidlink_socket_bad_incoming_addr (struct buffer *buf,			       const struct link_socket_info *info,			       const struct sockaddr_in *from_addr){  struct gc_arena gc = gc_new ();  msg (D_LINK_ERRORS,       "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)",       print_sockaddr (from_addr, &gc),       (int)from_addr->sin_family,       print_sockaddr (&info->lsa->remote, &gc));  buf->len = 0;  gc_free (&gc);}voidlink_socket_bad_outgoing_addr (void){  msg (D_READ_WRITE, "TCP/UDP: No outgoing address to send packet");}in_addr_tlink_socket_current_remote (const struct link_socket_info *info){  const struct link_socket_addr *lsa = info->lsa;  if (addr_defined (&lsa->actual))    return ntohl (lsa->actual.sin_addr.s_addr);  else if (addr_defined (&lsa->remote))    return ntohl (lsa->remote.sin_addr.s_addr);  else    return 0;}/* * Return a status string describing socket state. */const char *socket_stat (const struct link_socket *s, unsigned int rwflags, struct gc_arena *gc){  struct buffer out = alloc_buf_gc (64, gc);  if (s)    {      if (rwflags & EVENT_READ)	{	  buf_printf (&out, "S%s",		      (s->rwflags & EVENT_READ) ? "R" : "r");#ifdef WIN32	  buf_printf (&out, "%s",		      overlapped_io_state_ascii (&s->reads));#endif	}      if (rwflags & EVENT_WRITE)	{	  buf_printf (&out, "S%s",		      (s->rwflags & EVENT_WRITE) ? "W" : "w");#ifdef WIN32	  buf_printf (&out, "%s",		      overlapped_io_state_ascii (&s->writes));#endif	}    }  else    {      buf_printf (&out, "S?");    }  return BSTR (&out);}/* * Stream buffer functions, used to packetize a TCP * stream connection. */static inline voidstream_buf_reset (struct stream_buf *sb){  msg (D_STREAM_DEBUG, "STREAM: RESET");  sb->residual_fully_formed = false;  sb->buf = sb->buf_init;  buf_reset (&sb->next);  sb->len = -1;}voidstream_buf_init (struct stream_buf *sb,		 struct buffer *buf){  sb->buf_init = *buf;  sb->maxlen = sb->buf_init.len;  sb->buf_init.len = 0;  sb->residual = alloc_buf (sb->maxlen);  sb->error = false;  stream_buf_reset (sb);  msg (D_STREAM_DEBUG, "STREAM: INIT maxlen=%d", sb->maxlen);}static inline voidstream_buf_set_next (struct stream_buf *sb){  /* set up 'next' for next i/o read */  sb->next = sb->buf;  sb->next.offset = sb->buf.offset + sb->buf.len;  sb->next.len = (sb->len >= 0 ? sb->len : sb->maxlen) - sb->buf.len;  msg (D_STREAM_DEBUG, "STREAM: SET NEXT, buf=[%d,%d] next=[%d,%d] len=%d maxlen=%d",       sb->buf.offset, sb->buf.len,       sb->next.offset, sb->next.len,       sb->len, sb->maxlen);  ASSERT (sb->next.len > 0);  ASSERT (buf_safe (&sb->buf, sb->next.len));}static inline voidstream_buf_get_final (struct stream_buf *sb, struct buffer *buf){  msg (D_STREAM_DEBUG, "STREAM: GET FINAL len=%d",       buf_defined (&sb->buf) ? sb->buf.len : -1);  ASSERT (buf_defined (&sb->buf));  *buf = sb->buf;}static inline voidstream_buf_get_next (struct stream_buf *sb, struct buffer *buf){  msg (D_STREAM_DEBUG, "STREAM: GET NEXT len=%d",       buf_defined (&sb->next) ? sb->next.len : -1);  ASSERT (buf_defined (&sb->next));  *buf = sb->next;}boolstream_buf_read_setup_dowork (struct link_socket* sock){  if (sock->stream_buf.residual.len && !sock->stream_buf.residual_fully_formed)    {      ASSERT (buf_copy (&sock->stream_buf.buf, &sock->stream_buf.residual));      ASSERT (buf_init (&sock->stream_buf.residual, 0));      sock->stream_buf.residual_fully_formed = stream_buf_added (&sock->stream_buf, 0);      msg (D_STREAM_DEBUG, "STREAM: RESIDUAL FULLY FORMED [%s], len=%d",	   sock->stream_buf.residual_fully_formed ? "YES" : "NO",	   sock->stream_buf.residual.len);    }  if (!sock->stream_buf.residual_fully_formed)    stream_buf_set_next (&sock->stream_buf);  return !sock->stream_buf.residual_fully_formed;}boolstream_buf_added (struct stream_buf *sb,		  int length_added){  msg (D_STREAM_DEBUG, "STREAM: ADD length_added=%d", length_added);  if (length_added > 0)    sb->buf.len += length_added;  /* if length unknown, see if we can get the length prefix from     the head of the buffer */  if (sb->len < 0 && sb->buf.len >= (int) sizeof (packet_size_type))    {      packet_size_type net_size;      ASSERT (buf_read (&sb->buf, &net_size, sizeof (net_size)));      sb->len = ntohps (net_size);      if (sb->len < 1 || sb->len > sb->maxlen)	{	  msg (M_WARN, "WARNING: Bad encapsulated packet length from peer (%d), which must be > 0 and <= %d -- please ensure that --tun-mtu or --link-mtu is equal on both peers -- this condition could also indicate a possible active attack on the TCP link -- [Attemping restart...]", sb->len, sb->maxlen);	  stream_buf_reset (sb);	  sb->error = true;	  return false;	}    }  /* is our incoming packet fully read? */  if (sb->len > 0 && sb->buf.len >= sb->len)    {      /* save any residual data that's part of the next packet */      ASSERT (buf_init (&sb->residual, 0));      if (sb->buf.len > sb->len)	  ASSERT (buf_copy_excess (&sb->residual, &sb->buf, sb->len));      msg (D_STREAM_DEBUG, "STREAM: ADD returned TRUE, buf_len=%d, residual_len=%d",	   BLEN (&sb->buf),	   BLEN (&sb->residual));      return true;    }  else    {      msg (D_STREAM_DEBUG, "STREAM: ADD returned FALSE (have=%d need=%d)", sb->buf.len, sb->len);      stream_buf_set_next (sb);      return false;    }}voidstream_buf_close (struct stream_buf* sb){  free_buf (&sb->residual);}/* * Format IP addresses in ascii */const char *print_sockaddr (const struct sockaddr_in *addr, struct gc_arena *gc){  return print_sockaddr_ex(addr, true, ":", gc);}const char *print_sockaddr_ex (const struct sockaddr_in *addr, bool do_port, const char* separator, struct gc_arena *gc){  struct buffer out = alloc_buf_gc (64, gc);  const int port = ntohs (addr->sin_port);  mutex_lock_static (L_INET_NTOA);  buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->sin_addr) : "[undef]"));  mutex_unlock_static (L_INET_NTOA);  if (do_port && port)    {      if (separator)	buf_printf (&out, "%s", separator);      buf_printf (&out, "%d", port);    }  return BSTR (&out);}/* * Convert an in_addr_t in host byte order * to an ascii dotted quad. */const char *print_in_addr_t (in_addr_t addr, bool empty_if_undef, struct gc_arena *gc){  struct in_addr ia;  struct buffer out = alloc_buf_gc (64, gc);  if (addr || !empty_if_undef)    {      CLEAR (ia);      ia.s_addr = htonl (addr);      mutex_lock_static (L_INET_NTOA);      buf_printf (&out, "%s", inet_ntoa (ia));      mutex_unlock_static (L_INET_NTOA);    }  return BSTR (&out);}/* set environmental variables for ip/port in *addr */voidsetenv_sockaddr (const char *name_prefix, const struct sockaddr_in *addr){  char name_buf[256];  openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix);  mutex_lock_static (L_INET_NTOA);  setenv_str (name_buf, inet_ntoa (addr->sin_addr));  mutex_unlock_static (L_INET_NTOA);  openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix);  setenv_int (name_buf, ntohs (addr->sin_port));}voidsetenv_in_addr_t (const char *name_prefix, in_addr_t addr){

⌨️ 快捷键说明

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