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

📄 tunnel.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Tunnel server TCP and pipe detection routine. It is greedy. Thus it cannot  * share the port configuration with other TCP or pipe servers. */inttnl_detect_proto (svz_server_t *server, svz_socket_t *sock){  svz_log (LOG_NOTICE, "tunnel: %s connection accepted\n",	   sock->flags & SOCK_FLAG_PIPE ? "pipe" : "tcp");  return -1;}/* * If any TCP or pipe connection has been accepted this routine is called  * to setup the tunnel server specific callbacks. */inttnl_connect_socket (svz_server_t *server, svz_socket_t *sock){  svz_socket_t *xsock = NULL;  tnl_connect_t *source;    sock->flags |= SOCK_FLAG_NOFLOOD;  sock->check_request = sock->flags & SOCK_FLAG_PIPE ?    tnl_check_request_pipe_source : tnl_check_request_tcp_source;  sock->disconnected_socket = tnl_disconnect_source;  svz_sock_resize_buffers (sock, UDP_BUF_SIZE, UDP_BUF_SIZE);  /* try connecting to target */  xsock = tnl_create_socket (sock, sock->flags & SOCK_FLAG_PIPE ?			     TNL_FLAG_SRC_PIPE : TNL_FLAG_SRC_TCP);  if (xsock == NULL)    return -1;  /* put the source connection into data field */  source = tnl_create_connect ();  source->source_sock = sock;  source->target_sock = xsock;  source->ip = sock->remote_addr;  source->port = sock->remote_port;  xsock->data = source;  sock->data = source;  return 0;}/* * The tunnel servers TCP check_request routine for target connections. * Each TCP target connection gets assigned this function in order to * send data back to its source connection. */inttnl_check_request_tcp_target (svz_socket_t *sock){  svz_socket_t *xsock = NULL;  tnl_connect_t *source = sock->data;#if ENABLE_DEBUG  if (source == NULL || source->source_sock == NULL)    {      svz_log (LOG_FATAL, "tunnel: tcp target has no source connection\n");      return -1;    }#endif /* ENABLE_DEBUG */  /* obtain source connection */  xsock = source->source_sock;  xsock->remote_addr = source->ip;  xsock->remote_port = source->port;  /* forward data to source connection */  if (tnl_send_request_target (xsock, sock->recv_buffer, 			       sock->recv_buffer_fill, sock->userflags) == -1)    {      svz_sock_schedule_for_shutdown (xsock);      return -1;    }  /* empty the receive buffer of this target connection */  sock->recv_buffer_fill = 0;  return 0;}/* * The tunnel servers TCP check_request() routine for the source connections. * It simply copies the received data to the send buffer of the target * connection. */inttnl_check_request_tcp_source (svz_socket_t *sock){  tnl_connect_t *target = sock->data;  svz_socket_t *xsock;#if ENABLE_DEBUG  if (target == NULL || target->target_sock == NULL)    {      svz_log (LOG_FATAL, "tunnel: tcp source has no target connection\n");      return -1;    }#endif /* ENABLE_DEBUG */  /* obtain target connection */  xsock = target->target_sock;  /* forward data to target connection */  if (tnl_send_request_source (xsock, sock->recv_buffer, 			       sock->recv_buffer_fill, sock->userflags) == -1)    {      return -1;    }  sock->recv_buffer_fill = 0;  return 0;}/* * This function is the handle_request() routine for target UDP sockets. */inttnl_handle_request_udp_target (svz_socket_t *sock, char *packet, int len){  tnl_connect_t *source = sock->data;  svz_socket_t *xsock = NULL;#if ENABLE_DEBUG  if (source == NULL || source->source_sock == NULL)    {      svz_log (LOG_FATAL, "tunnel: udp target has no source connection\n");      return -1;    }#endif /* ENABLE_DEBUG */  /* get source connection from data field */  xsock = source->source_sock;  xsock->remote_addr = source->ip;  xsock->remote_port = source->port;  /* forward packet data to source connection */  if (tnl_send_request_target (xsock, packet, len, sock->userflags) == -1)    {      /* shutdown the source connection if it is TCP or pipe */      if (sock->userflags & (TNL_FLAG_SRC_TCP | TNL_FLAG_SRC_PIPE))	svz_sock_schedule_for_shutdown (xsock);      return -1;    }  /* returning zero means that the packet has been processed */  return 0;}/* * This function is the handle_request() routine for source UDP sockets. * It accepts UDP connections (listening connection) or forwards data * to existing target sockets. */inttnl_handle_request_udp_source (svz_socket_t *sock, char *packet, int len){  tnl_config_t *cfg = sock->cfg;  tnl_connect_t *source;  svz_socket_t *xsock = NULL;  /* check if there is such a connection in the source hash already */  source = svz_hash_get (cfg->client, tnl_addr (sock));  if (source)    {      /* get existing target socket */      xsock = source->target_sock;    }  else    {      /* start connecting to a new target */      if ((xsock = tnl_create_socket (sock, TNL_FLAG_SRC_UDP)) == NULL)	return 0;      /* foreign address not in hash, create new target connection */      source = tnl_create_connect ();      source->source_sock = sock;      source->ip = sock->remote_addr;      source->port = sock->remote_port;      svz_hash_put (cfg->client, tnl_addr (sock), source);      /* put the source connection into data field of target */      xsock->data = source;      source->target_sock = xsock;    }  /* forward packet data to target connection */  if (tnl_send_request_source (xsock, packet, len, sock->userflags) == -1)    {      svz_sock_schedule_for_shutdown (xsock);      return 0;    }  return 0;}/* * This function is the handle_request routine for target ICMP sockets. */inttnl_handle_request_icmp_target (svz_socket_t *sock, char *packet, int len){  tnl_connect_t *source = sock->data;  svz_socket_t *xsock = NULL;#if ENABLE_DEBUG  if (source == NULL || source->source_sock == NULL)    {      svz_log (LOG_FATAL,	       "tunnel: icmp target has no source connection\n");      return -1;    }#endif /* ENABLE_DEBUG */  /* get source connection from data field */  xsock = source->source_sock;  xsock->remote_addr = source->ip;  xsock->remote_port = source->port;  /* forward packet data to source connection */  if (tnl_send_request_target (xsock, packet, len, sock->userflags) == -1)    {      /* shutdown source connection if it is TCP or pipe */      if (sock->userflags & (TNL_FLAG_SRC_TCP | TNL_FLAG_SRC_PIPE))	svz_sock_schedule_for_shutdown (xsock);      return -1;    }  /* packet successfully processed */  return 0;}/* * This function is the handle_request() routine for source ICMP sockets. * It accepts ICMP connections (listening connection) or forwards data * to existing target sockets. */inttnl_handle_request_icmp_source (svz_socket_t *sock, char *packet, int len){  tnl_config_t *cfg = sock->cfg;  tnl_connect_t *source;  svz_socket_t *xsock = NULL;  /* check if there is such a connection in the source hash already */  source = svz_hash_get (cfg->client, tnl_addr (sock));  if (source)    {      /* get existing target socket */      xsock = source->target_sock;    }  else    {      /* start connecting */      if ((xsock = tnl_create_socket (sock, TNL_FLAG_SRC_ICMP)) == NULL)	return 0;      /* foreign address not in hash, create new target connection */      source = tnl_create_connect ();      source->source_sock = sock;      source->ip = sock->remote_addr;      source->port = sock->remote_port;      svz_hash_put (cfg->client, tnl_addr (sock), source);      /* put the source connection into data field */      xsock->data = source;      source->target_sock = xsock;    }  /* forward packet data to target connection */  if (tnl_send_request_source (xsock, packet, len, sock->userflags) == -1)    {      svz_sock_schedule_for_shutdown (xsock);      return 0;    }  return 0;}/* * The targets's disconnection routine for types of targets (TCP, PIPE, * ICMP and UDP). */inttnl_disconnect_target (svz_socket_t *sock){  tnl_config_t *cfg = sock->cfg;  tnl_connect_t *source = sock->data;  svz_socket_t *xsock;  char *key;  /* do not do anything if we are shutting down */  if (svz_nuke_happened)    {      /* if source is TCP or PIPE then shutdown referring connection */      if (sock->userflags & (TNL_FLAG_SRC_TCP | TNL_FLAG_SRC_PIPE))	{	  xsock = source ? source->source_sock : NULL;	  if (xsock)	    xsock->data = NULL;	  tnl_free_connect (sock);	}      return 0;    }#if ENABLE_DEBUG  if (source == NULL || source->source_sock == NULL)    {      svz_log (LOG_FATAL, "tunnel: target has no source connection\n");      return -1;    }#endif /* ENABLE_DEBUG */  /* obtain source connection */  xsock = source->source_sock;  /* if the source connection is ICMP send a disconnection message */  if (sock->userflags & TNL_FLAG_SRC_ICMP)    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG,	       "tunnel: sending icmp disconnect on socket id %d\n",	       xsock->id);#endif /* ENABLE_DEBUG */      svz_icmp_send_control (xsock, ICMP_SERVEEZ_CLOSE);    }  /* if source is TCP or PIPE then shutdown referring connection */  if (sock->userflags & (TNL_FLAG_SRC_TCP | TNL_FLAG_SRC_PIPE))    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "tunnel: shutdown referrer id %d\n", xsock->id);#endif /* ENABLE_DEBUG */      svz_sock_schedule_for_shutdown (xsock);      xsock->data = NULL;      tnl_free_connect (sock);    }  /* else delete target connection from its hash */  else if ((key = svz_hash_contains (cfg->client, source)) != NULL)    {      svz_hash_delete (cfg->client, key);      tnl_free_connect (sock);    }  return 0;}/* * What happens if a source connection gets lost. */inttnl_disconnect_source (svz_socket_t *sock){  tnl_connect_t *target = sock->data;  svz_socket_t *xsock;  /* if target is TCP or PIPE shutdown referring connection */  if (sock->userflags & (TNL_FLAG_TGT_TCP | TNL_FLAG_TGT_PIPE))    {#if ENABLE_DEBUG      if (target == NULL || target->target_sock == NULL)	{	  svz_log (LOG_DEBUG, "tunnel: tcp/pipe source has no "		   "target connection\n");	  return -1;	}#endif /* ENABLE_DEBUG */      /* get target connection */      xsock = target->target_sock;#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "tunnel: shutdown referrer id %d\n", xsock->id);#endif /* ENABLE_DEBUG */      svz_sock_schedule_for_shutdown (xsock);      xsock->data = NULL;      tnl_free_connect (sock);    }  return 0;}/* * Because UDP and ICMP sockets cannot not be detected as being closed * we need to shutdown target sockets ourselves. */inttnl_idle (svz_socket_t *sock){  time_t t = time (NULL);  if (t - sock->last_recv < TNL_TIMEOUT || t - sock->last_send < TNL_TIMEOUT)    {      sock->idle_counter = TNL_TIMEOUT;      return 0;    }  return -1;}#else /* not ENABLE_TUNNEL */int tunnel_dummy; /* Shut compiler warnings up. */#endif /* not ENABLE_TUNNEL */

⌨️ 快捷键说明

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