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

📄 awcs-proto.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
  while (*cmd && *cmd != ' ')    {      awcs_process_id (address, cmd);      sock = (svz_socket_t *) svz_hash_get (cfg->clients, (char *) &address);      if (sock)	{	  if (svz_sock_write (sock, msg, cmd_len))	    svz_sock_schedule_for_shutdown (sock);	}#if ENABLE_DEBUG      else	{	  svz_log (LOG_DEBUG, "awcs: master sent invalid id (multicast %d)\n", 		   address);	}#endif /* ENABLE_DEBUG */    }  return 0;}/* * Process a status request. */static intawcs_process_status (awcs_config_t *cfg, char *cmd, int cmd_len){#if ENABLE_DEBUG  svz_log (LOG_DEBUG, "awcs: sending status message\n");#endif /* ENABLE_DEBUG */  awcs_status_alive (cfg);  return 0;}/* * Kick all clients in the client list at the beginning of @var{cmd}.  * The rest of @var{cmd} is the kicking reason. */static intawcs_process_kick (awcs_config_t *cfg, char *cmd, int cmd_len){  svz_socket_t *sock;  int address;  while (*cmd && *cmd != ' ')    {      awcs_process_id (address, cmd);      sock = (svz_socket_t *) svz_hash_get (cfg->clients, (char *) &address);      if (sock)	{#if ENABLE_DEBUG	  svz_log (LOG_DEBUG, "awcs: kicking socket %d\n", sock->sock_desc);#endif /* ENABLE_DEBUG */	  /*	   * This is a hack. We set the handler to NULL to be sure	   * that the master server will not get a KICKED status	   * message for a kick he initiated.	   */	  sock->kicked_socket = NULL;	  svz_sock_schedule_for_shutdown (sock);	}#if ENABLE_DEBUG      else	{	  svz_log (LOG_DEBUG, "awcs: master sent invalid id (kick %d)\n",		   address);	}#endif /* ENABLE_DEBUG */    }  return 0;}/* * Turn off flood protection for clients listed in command if flag is  * false, turn it on otherwise. */static intawcs_process_floodcmd (awcs_config_t *cfg, char *cmd, int cmd_len, int flag){  svz_socket_t *sock;  int address;  while (*cmd && *cmd != ' ')    {      awcs_process_id (address, cmd);      sock = (svz_socket_t *) svz_hash_get (cfg->clients, (char *) &address);      if (sock)	{#if ENABLE_DEBUG	  svz_log (LOG_DEBUG, "awcs: switching flood control for socket "		   "%d %s\n", sock->sock_desc, flag ? "on" : "off");#endif /* ENABLE_DEBUG */	  if (flag)	    sock->flags &= ~SOCK_FLAG_NOFLOOD;	  else	    sock->flags |= SOCK_FLAG_NOFLOOD;	}#if ENABLE_DEBUG      else	{	  svz_log (LOG_DEBUG, "awcs: master sent invalid id (floodcmd %d)\n",		   address);	}#endif /* ENABLE_DEBUG */    }  return 0;}/* * Handle a request from the master server.  Return a non-zero value * on error. */static intawcs_handle_master_request (awcs_config_t *cfg, char *request, int request_len){  if (request_len <= 0)    return -1;#if 0  svz_hexdump (stdout, "master request", cfg->server->sock_desc,	       request, request_len, 0);#endif  request_len--;  switch (*request++)    {    case '0':      request++;      request_len--;      awcs_process_broadcast (cfg, request, request_len);      break;    case '1':      request++;      request_len--;      awcs_process_multicast (cfg, request, request_len);      break;    case '2':      request++;      request_len--;      awcs_process_status (cfg, request, request_len);      break;    case '3':      request++;      request_len--;      awcs_process_kick (cfg, request, request_len);      break;    case '4':      request++;      request_len--;      awcs_process_floodcmd (cfg, request, request_len, 0);      break;    case '5':      request++;      request_len--;      awcs_process_floodcmd (cfg, request, request_len, 1);      break;    case '6':      /* The following code should not be executed anymore. */      svz_log (LOG_NOTICE, "awcs: skipping '6' ...\n");      break;    default:      svz_log (LOG_ERROR, "awcs: bad master server request\n");      break;    }  return 0;}/* * Schedule all aWCS clients for shutdown. Call this if the * connection to the master server has been lost. */voidawcs_disconnect_clients (awcs_config_t *cfg){  svz_socket_t **sock;  int n;  if ((sock = (svz_socket_t **) svz_hash_values (cfg->clients)) != NULL)    {      for (n = 0; n < svz_hash_size (cfg->clients); n++)	svz_sock_schedule_for_shutdown (sock[n]);      svz_hash_xfree (sock);    }}/* * Handle the request REQUEST of length REQUEST_LEN from socket * SOCK.  Return a non-zero value on error. */static intawcs_handle_request (svz_socket_t *sock, char *request, int request_len){  int ret;  awcs_config_t *cfg = sock->cfg;#if 0  svz_hexdump (stdout, "awcs request", sock->sock_desc, request, 	       request_len, 1000);#endif  if (!cfg->server)    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: no master server (awcs_handle_request)\n");#endif      awcs_disconnect_clients (cfg);      return -1;    }  if (sock == cfg->server)    {      awcs_handle_master_request (cfg, request, request_len);    }  else    {      ret = svz_sock_printf (cfg->server, AWCS_ID_FMT " ", sock->id);      if (ret == 0)	{	  ret = svz_sock_write (cfg->server, request, request_len);	}      if (ret)	{	  svz_log (LOG_FATAL, "awcs: master write error\n");	  svz_sock_schedule_for_shutdown (cfg->server);	  cfg->server = NULL;	  awcs_disconnect_clients (cfg);	  return -1;	}    }  return 0;}/* * Checks whether a complete request has been accumulated in socket * @var{sock}'s receive queue.  If yes, then the request gets handled  * and removed from the queue. */intawcs_check_request (svz_socket_t *sock){  int retval = 0;  int request_len = 0;  char * p, * packet;  p = sock->recv_buffer;  packet = p;  do    {      while (p < sock->recv_buffer + sock->recv_buffer_fill && *p != '\0')        p++;      if (*p == '\0' && p < sock->recv_buffer + sock->recv_buffer_fill)        {          p++;          request_len += (p - packet);	  retval = awcs_handle_request (sock, packet, p - packet);          packet = p;        }    }  while (p < sock->recv_buffer + sock->recv_buffer_fill);    if (request_len > 0)    {      memmove (sock->recv_buffer, packet,	       sock->recv_buffer_fill - request_len);    }  sock->recv_buffer_fill -= request_len;  return 0;}/* * Gets called when a client has connected as socket SOCK and has been * identified as an aWCS client. MASTER ist set if it was a master * server detection. */intawcs_connect_socket (svz_server_t *server, svz_socket_t *sock){  awcs_config_t *cfg = server->cfg;  /*   * Don't allow clients without master server or multiple master servers.   */  if ((!cfg->server && !cfg->master) || (cfg->server && cfg->master))    {      if (!cfg->server && !cfg->master)	{#if ENABLE_DEBUG	  svz_log (LOG_DEBUG,		   "awcs: master not present, cannot connect socket %d\n",		   sock->sock_desc);#endif	}      if (cfg->server && cfg->master)	{#if ENABLE_DEBUG	  svz_log (LOG_DEBUG,		   "awcs: master is present, cannot connect socket %d\n",		   sock->sock_desc);#endif	}      return -1;    }#if ENABLE_DEBUG  if (sock->flags & SOCK_FLAG_PIPE)    {      svz_log (LOG_DEBUG, "awcs: connection on pipe (%d-%d)\n",	       sock->pipe_desc[READ], sock->pipe_desc[WRITE]);    }  else     {      svz_log (LOG_DEBUG, "awcs: connection on socket %d\n",	       sock->sock_desc);    }#endif /* ENABLE_DEBUG */  sock->disconnected_socket = awcs_disconnected_socket;  sock->check_request = awcs_check_request;  if (cfg->master)    {#if ENABLE_DEBUG      if (sock->flags & SOCK_FLAG_PIPE)	{	  svz_log (LOG_NOTICE, 		   "awcs: master server connected on pipe (%d-%d)\n",		   sock->pipe_desc[READ], sock->pipe_desc[WRITE]);	}      else	{	  svz_log (LOG_NOTICE, 		   "awcs: master server connected on socket %d\n",		   sock->sock_desc);	}#endif /* ENABLE_DEBUG */      cfg->server = sock;      sock->idle_func = awcs_idle_func;      sock->idle_counter = 3;      sock->flags |= (SOCK_FLAG_NOFLOOD | SOCK_FLAG_PRIORITY);      svz_log (LOG_NOTICE,	       "awcs: resizing master buffers: %d, %d\n",	       MASTER_SEND_BUFSIZE, MASTER_RECV_BUFSIZE);      svz_sock_resize_buffers (sock, MASTER_SEND_BUFSIZE, MASTER_RECV_BUFSIZE);      sock->flags |= SOCK_FLAG_INITED;    }  else    {      svz_hash_put (cfg->clients, (char *) &sock->id, sock);      sock->kicked_socket = awcs_kicked_socket;    }  /*   * Tell the master server about the connection (even itself).   */  awcs_status_connected (sock);  return 0;}/* * Gets called when the socket SOCK had disconnected.  All clients are * kicked when the socket was the master server, otherwise a diconnection * message is sent to the master server. */intawcs_disconnected_socket (svz_socket_t *sock){  awcs_config_t *cfg = sock->cfg;    if (sock == cfg->server)    {      svz_log (LOG_ERROR, "awcs: lost master server\n");      cfg->server = NULL;      awcs_disconnect_clients (cfg);    }  else    {      awcs_status_disconnected (sock, 1);      svz_hash_delete (cfg->clients, (char *) &sock->id);    }  return 0;}/* * Gets called when the socket SOCK got kicked.  REASON is true when * a output buffer overflow occured and false, when it was an input * buffer overflow or flooding. */intawcs_kicked_socket (svz_socket_t *sock, int reason){  if (!reason)    awcs_status_kicked (sock, KICK_FLOODING);  else    awcs_status_kicked (sock, KICK_CRAWLING);  return 0;}/* * The socket for the master server gets set this function as the timer * function.  The function sends an idle message to the master server * and resets its timeout counter. */intawcs_idle_func (svz_socket_t *sock){  awcs_config_t *cfg = sock->cfg;  if (sock == cfg->server)    {      sock->idle_counter = 3;      awcs_status_notify (cfg);    }  return 0;}/* * This function gets called for new sockets which are not yet * identified.  It returns a non-zero value when the contents in * the receive buffer looks like an aWCS identification request. */intawcs_detect_proto (svz_server_t *server, svz_socket_t *sock){  awcs_config_t *cfg = server->cfg;  int len = 0;#if 0  svz_hexdump (stdout, "detecting awcs", sock->sock_desc,	       sock->recv_buffer, sock->recv_buffer_fill, 0);#endif  if (sock->recv_buffer_fill >= MASTER_DETECTION &&       !memcmp (sock->recv_buffer, AWCS_MASTER, MASTER_DETECTION))    {      cfg->master = 1;      svz_log (LOG_NOTICE, "awcs: master detected\n");      len = MASTER_DETECTION;    }  else if (sock->recv_buffer_fill >= CLIENT_DETECTION && 	   !memcmp (sock->recv_buffer, AWCS_CLIENT, CLIENT_DETECTION))    {      cfg->master = 0;      svz_log (LOG_NOTICE, "awcs: client detected\n");      len = CLIENT_DETECTION;    }  if (len == 0) return 0;  if (sock->recv_buffer_fill > len)    {      memmove (sock->recv_buffer, 	       sock->recv_buffer + len, 	       sock->recv_buffer_fill - len);    }  sock->recv_buffer_fill -= len;  return len;}int have_awcs = 1;#else /* ENABLE_AWCS_PROTO */int have_awcs = 0;	/* Shut compiler warnings up,			   make runtime checking possible */#endif /* not ENABLE_AWCS_PROTO */

⌨️ 快捷键说明

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