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

📄 control-proto.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * control-proto.c - control protocol implementation * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA.   * * $Id: control-proto.c,v 1.57 2001/08/12 10:59:04 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#if ENABLE_CONTROL_PROTO#define _GNU_SOURCE#include <stdio.h>#include <string.h>#include <time.h>#ifdef __MINGW32__# include <winsock2.h>#endif#ifndef __MINGW32__# include <sys/types.h># include <netinet/in.h>#endif#if HAVE_LIBKSTAT# include <kstat.h># include <sys/sysinfo.h>#elif HAVE_PSTAT# include <sys/pstat.h>#elif HAVE_SYSGET# include <sys/sysget.h># include <sys/sysinfo.h>#endif#if HAVE_TIMES# include <sys/times.h>#endif#include "libserveez.h"#include "control-proto.h"#if ENABLE_HTTP_PROTO# include "http-server/http-cache.h"#endif/* * The control server instance configuration. */ctrl_config_t ctrl_config ={  0 /* nothing */};/* * Definition of the configuration items processed by the configuration  * language. */svz_key_value_pair_t ctrl_config_prototype [] ={  SVZ_REGISTER_END ()};/* * Definition of the control protocol server. */svz_servertype_t ctrl_server_definition ={  "control protocol server", /* long server description */  "control",                 /* short server description */  NULL,                      /* global initializer */  ctrl_init,                 /* instance initializer */  ctrl_detect_proto,         /* protocol detection routine */  ctrl_connect_socket,       /* connection routine */  ctrl_finalize,             /* instance finalization routine */  NULL,                      /* global finalizer */  ctrl_info_client,          /* client info */  ctrl_info_server,          /* server info */  NULL,                      /* server timer */  NULL,                      /* handle request callback */  &ctrl_config,              /* default configuration */  sizeof (ctrl_config),      /* size of the configuration */  ctrl_config_prototype      /* configuration prototypes */};/* * Within the ctrl_idle() function this structure gets filled with * the appropriate data. */cpu_state_t cpu_state;/* * Server instance initializer. This is currently used for binding the * server to a given port configuration. */intctrl_init (svz_server_t *server){  ctrl_config_t *cfg = server->cfg;  return 0;}/* * Server instance finalizer. */intctrl_finalize (svz_server_t *server){  return 0;}/* * Server info callback. */char *ctrl_info_server (svz_server_t *server){  static char info[128];  ctrl_config_t *cfg = server->cfg;  sprintf (info, " nothing to be configured, yet");  return info;}/* * Client info callback. */char *ctrl_info_client (svz_server_t *server, svz_socket_t *sock){  static char info[128];  sprintf (info, "This is a control connection client.");  return info;}/* * This function gets called for new sockets which are not yet * identified. It returns a non-zero value when the content in * the receive buffer looks like the control protocol. */intctrl_detect_proto (svz_server_t *server, svz_socket_t *sock){  int ret = 0;  /* accept both CRLF and CR */  if (sock->recv_buffer_fill >= 2 &&       sock->recv_buffer[0] == '\r' &&      sock->recv_buffer[1] == '\n')    {      ret = 2;    }  else if (sock->recv_buffer_fill >= 1 && sock->recv_buffer[0] == '\n')    {      ret = 1;    }  /* control protocol detected */  if (ret)    {      if (ret < sock->recv_buffer_fill)	{	  memmove (sock->recv_buffer, 		   sock->recv_buffer + ret, 		   sock->recv_buffer_fill - ret);	}      sock->recv_buffer_fill -= ret;#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "control protocol client detected\n");#endif      return -1;    }  return 0;}/* * When ctrl_detect_proto has identified a client connection being * a control protocol connection you have to call the following  * routine. */intctrl_connect_socket (svz_server_t *server, svz_socket_t *sock){  svz_sock_resize_buffers (sock, CTRL_SEND_BUFSIZE, CTRL_RECV_BUFSIZE);  sock->check_request = svz_sock_check_request;  sock->handle_request = ctrl_handle_request;  sock->boundary = CTRL_PACKET_DELIMITER;  sock->boundary_size = CTRL_PACKET_DELIMITER_LEN;  sock->idle_func = ctrl_idle;  sock->idle_counter = CTRL_LOAD_UPDATE;#if HAVE_PROC_STAT  cpu_state.cpufile = CPU_FILE_NAME;  cpu_state.cpuline = CPU_LINE_FORMAT;#elif HAVE_LIBKSTAT /* not HAVE_PROC_STAT */#else /* neither HAVE_PROC_STAT nor HAVE_LIBKSTAT */  strcpy (cpu_state.info, CPU_FORMAT);#endif  cpu_state.cpuinfoline = CPU_FORMAT;  /* send welcome message */  svz_sock_printf (sock, "%s", CTRL_PASSWD);  return 0;}/* * Quit command. If the client sends this command the control protocol * connection will be closed immediately. */intctrl_quit (svz_socket_t *sock, int flag, char *arg){  return flag;}/* * Help screen. Here you will get all the available commands of the * control protocol. These depend on the features the current version  * of Serveez implements. */intctrl_help (svz_socket_t *sock, int flag, char *arg){  svz_sock_printf (sock,     "\r\n available commands:\r\n"    "   * help                - this help screen\r\n"    "   * quit                - quit this control connection\r\n"    "   * restart ident       - restart the ident coserver\r\n"    "   * restart reverse dns - restart reverse DNS lookup coserver\r\n"    "   * restart dns         - restart the DNS lookup coserver\r\n"    "   * killall             - shutdown all client connections\r\n"    "   * kill id NUM         - shutdown connection NUM\r\n"    "   * stat                - general statistics\r\n"    "   * stat SERVER         - SERVER's statistic\r\n"    "   * stat coserver       - coserver statistics\r\n"    "   * stat con            - connection statistics\r\n"    "   * stat id NUM         - NUM's connection info\r\n"    "   * stat all            - server and coserver state\r\n"#if ENABLE_HTTP_PROTO    "   * stat cache          - http cache statistics\r\n"    "   * kill cache          - free all http cache entries\r\n"#endif /* ENABLE_HTTP_PROTO */    "\r\n");  return flag;}/* * ID's connection info. This function displays a given socket id's * socket structure. */intctrl_stat_id (svz_socket_t *sock, int flag, char *arg){  int id, n;  svz_socket_t *xsock;  char proto[128];  svz_server_t *server;  svz_coserver_t *coserver;  /* Find the appropriate client or server connection. */  id = atoi (arg);  if ((xsock = svz_sock_find (id, -1)) == NULL)    {      svz_sock_printf (sock, "no such connection: %d\r\n", id);      return flag;    }  svz_sock_printf (sock, "\r\nconnection id %d (version %d) "		   "statistics\r\n\r\n", 		   id, xsock->version);  /*    * Process general socket structure's flags. Uppercase words refer   * to set bits and lowercase to unset bits.   */  svz_sock_printf (sock,    " flags    : %s %s %s %s %s %s %s\r\n"    "            %s %s %s %s %s %s %s\r\n",    xsock->flags & SOCK_FLAG_INBUF ?      "INBUF" : "inbuf",    xsock->flags & SOCK_FLAG_OUTBUF ?     "OUTBUF" : "outbuf",    xsock->flags & SOCK_FLAG_CONNECTED ?  "CONNECTED" : "connected",    xsock->flags & SOCK_FLAG_LISTENING ?  "LISTENING" : "listening",    xsock->flags & SOCK_FLAG_KILLED ?     "KILLED" : "killed",    xsock->flags & SOCK_FLAG_NOFLOOD ?    "flood" : "FLOOD",    xsock->flags & SOCK_FLAG_CONNECTING ? "CONNECTING" : "connecting",    xsock->flags & SOCK_FLAG_INITED ?     "INITED" : "inited",    xsock->flags & SOCK_FLAG_COSERVER ?   "COSERVER" : "coserver",    xsock->flags & SOCK_FLAG_PIPE ?       "PIPE" : "pipe",    xsock->flags & SOCK_FLAG_FILE ?       "FILE" : "file",    xsock->flags & SOCK_FLAG_SOCK ?       "SOCK" : "sock",    xsock->flags & SOCK_FLAG_ENQUEUED ?   "ENQUEUED" : "enqueued",    xsock->flags & SOCK_FLAG_PRIORITY ?   "PRIORITY" : "priority");  svz_sock_printf (sock, " protocol : ");  /* process connection type server flags */  if (xsock->flags & SOCK_FLAG_LISTENING)    {      /* a listening server */      strcpy (proto, "server: ");      if (xsock->proto & PROTO_TCP)	strcat (proto, "tcp ");      if (xsock->proto & PROTO_UDP)	strcat (proto, "udp ");      if (xsock->proto & PROTO_ICMP)	strcat (proto, "icmp ");      if (xsock->proto & PROTO_PIPE)	strcat (proto, "pipe ");      if (xsock->proto & PROTO_RAW)	strcat (proto, "raw ");      svz_sock_printf (sock, "%s\r\n", proto);      svz_array_foreach (xsock->data, server, n)	{	  svz_sock_printf (sock, "            %d. %s (%s)\r\n", 			   n + 1, server->name, server->description);	}    }  /* process client info */  else    {      /* usual client */      if ((server = svz_server_find (xsock->cfg)) != NULL)	{	  char *info;	  svz_sock_printf (sock, "%s client\r\n", server->name);	  if (server->info_client && 	      (info = server->info_client (server, xsock)) != NULL)	    {	      svz_sock_printf (sock, "            %s\r\n", info);	    }	}      /* coserver */      else if (xsock->flags & SOCK_FLAG_COSERVER)	{	  coserver = xsock->data;	  svz_sock_printf (sock, "internal %s coserver\r\n",			   svz_coservertypes[coserver->type].name);	}      /* unidentified */      else	{	  svz_sock_printf (sock, "not yet identified\r\n");	}    }  /* print all previously collected statistics of this connection */  if (xsock->flags & SOCK_FLAG_SOCK)    svz_sock_printf (sock, " sock fd  : %d\r\n", xsock->sock_desc);  if (xsock->flags & SOCK_FLAG_FILE)    svz_sock_printf (sock, " file fd  : %d\r\n", xsock->file_desc);  if (xsock->flags & SOCK_FLAG_PIPE)    svz_sock_printf (sock, " pipe fd  : %d (recv), %d (send)\r\n",		     xsock->pipe_desc[READ], 		     xsock->pipe_desc[WRITE]);  if (xsock->flags & SOCK_FLAG_PIPE)    {      if (xsock->send_pipe)	svz_sock_printf (sock, " foreign  : %s\r\n", xsock->send_pipe);      if (xsock->recv_pipe)	svz_sock_printf (sock, " local    : %s\r\n", xsock->recv_pipe);    }  if (xsock->flags & SOCK_FLAG_SOCK)    {      svz_sock_printf (sock, " foreign  : %s:%u\r\n",		       svz_inet_ntoa (xsock->remote_addr),		       ntohs (xsock->remote_port));      svz_sock_printf (sock, " local    : %s:%u\r\n",		       svz_inet_ntoa (xsock->local_addr),		       ntohs (xsock->local_port));    }  svz_sock_printf (sock, 		   " sendbuf  : %d (size), %d (fill), %s (last send)\r\n"		   " recvbuf  : %d (size), %d (fill), %s (last recv)\r\n"		   " idle     : %d\r\n"#if ENABLE_FLOOD_PROTECTION		   " flood    : %d (points), %d (limit)\r\n"#endif /* ENABLE_FLOOD_PROTECTION */		   " avail    : %s\r\n\r\n",		   xsock->send_buffer_size,		   xsock->send_buffer_fill,		   svz_time (xsock->last_send),		   xsock->recv_buffer_size,		   xsock->recv_buffer_fill,		   svz_time (xsock->last_recv),		   xsock->idle_counter,#if ENABLE_FLOOD_PROTECTION		   xsock->flood_points,		   xsock->flood_limit,#endif /* ENABLE_FLOOD_PROTECTION */		   xsock->unavailable ? "no" : "yes");  return flag;}/* * General statistics about Serveez. Here we display all the information * we could get from the system and the process itself. * Furthermore we check if the command is something about a certain * server and give information about it if so. */intctrl_stat (svz_socket_t *sock, int flag, char *arg){  svz_server_t *server;  char *p;  /* find an appropriate server instance */  p = arg;  while (*p && *p != '\r' && *p != '\n')    p++;  if (*p)    *p = '\0';  if ((server = svz_hash_get (svz_servers, arg)) != NULL)    {      svz_sock_printf (sock, "\r\n%s (%s):\r\n",		       server->description, server->name);      if (server->info_server && (p = server->info_server (server)) != NULL)	{	  svz_sock_printf (sock, "%s\r\n", p);	}      svz_sock_printf (sock, "\r\n");      return flag;    }  /* print a standard output */  svz_sock_printf (sock, 		   "\r\nThis is %s version %s running since %s.\r\n", 		   svz_library, svz_version,		   svz_time (svz_config.start));  /* display compile time feature list */  svz_sock_printf (sock, "Features  : FOO"#ifdef ENABLE_AWCS_PROTO	       " AWCS"#endif#ifdef ENABLE_HTTP_PROTO	       " HTTP"#endif#ifdef ENABLE_IRC_PROTO	       " IRC"#endif#if ENABLE_CONTROL_PROTO	       " CTRL"#endif#if ENABLE_SNTP_PROTO	       " SNTP"#endif#if ENABLE_GNUTELLA	       " NUT"#endif#if ENABLE_TUNNEL	       " TUNNEL"#endif#if ENABLE_FAKEIDENT	       " IDENTD"#endif	       "\r\n");    /* second feature line */  svz_sock_printf (sock, "           "	       " IDENT"	       " REVERSE-DNS"	       " DNS"#ifdef ENABLE_FLOOD_PROTECTION	       " FLOOD"#endif#ifdef ENABLE_DEBUG	       " DEBUG"#endif#if defined (__MINGW32__) || defined (__CYGWIN__)	       " WIN32"#endif	       "\r\n");  /* display system and process information */  svz_sock_printf (sock, "Os        : %s\r\n", svz_sys_version ());  svz_sock_printf (sock, "Sys-Load  : %s\r\n", cpu_state.info);  svz_sock_printf (sock, "Proc-Load : %s\r\n", cpu_state.pinfo);  /* show general state */  svz_sock_printf (sock, "\r\n * %d connected sockets (hard limit is %d)\r\n",		   svz_sock_connections, svz_config.max_sockets);  svz_sock_printf (sock, " * uptime is %s\r\n", 		   svz_uptime (time (NULL) - svz_config.start));#if ENABLE_DEBUG  svz_sock_printf (sock, " * %d bytes of memory in %d blocks allocated\r\n", 		   svz_allocated_bytes, svz_allocated_blocks);#endif /* ENABLE_DEBUG */  svz_sock_printf (sock, "\r\n");  return flag;}/* * Connection statistics. This function displays basic information about * each socket structure currently within the socket list. */intctrl_stat_con (svz_socket_t *sock, int flag, char *arg)

⌨️ 快捷键说明

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