From 778b0b1bf2014dace4a249a85e9ccdd89b16aa50 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 24 Feb 2001 22:47:01 +0000 Subject: [PATCH] CONNECT, CLOSE and SHUTDOWN commands. --- CHANGES | 18 +++ apps/silcd/command.c | 158 +++++++++++++++++++++++--- apps/silcd/command.h | 2 +- apps/silcd/server.c | 27 ++++- apps/silcd/server.h | 2 + apps/silcd/server_internal.h | 1 - doc/draft-riikonen-silc-spec-01.nroff | 14 +-- lib/silcclient/command.c | 4 +- lib/silcclient/command.h | 2 +- lib/silccore/silccommand.h | 2 +- lib/silccore/silcmode.h | 5 + 11 files changed, 203 insertions(+), 32 deletions(-) diff --git a/CHANGES b/CHANGES index 0fc7f959..a0299768 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,21 @@ +Sat Feb 24 23:45:49 EET 2001 Pekka Riikonen + + * DIE command was renamed to SHUTDOWN. Updated the both code + and protocol specs. + + * Defined SILC_UMODE_NONE, SILC_UMODE_SERVER_OPERATOR and + SILC_UMODE_ROUTER_OPERATOR modes into lib/silccore/silcmode.h. + + * Implemented CONNECT, CLOSE and SHUTDOWN commands to the server + side. + + * Added function silc_server_create_connection function to create + connection to remote router. My server implementation actually + does not allow router to connect to normal server (it expects + that normal server always initiates the connection to the router) + so the CONNECT command is only good for connecting to another + router. + Sat Feb 24 16:03:45 EET 2001 Pekka Riikonen * Added SILC_NOTIFY_TYPE_KICKED to indicate that the client diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 05c385d6..c72a18c9 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -69,7 +69,8 @@ SilcServerCommand silc_command_list[] = SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER), SILC_SERVER_CMD(close, CLOSE, SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER), - SILC_SERVER_CMD(die, DIE, SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER), + SILC_SERVER_CMD(shutdown, SHUTDOWN, SILC_CF_LAG | SILC_CF_REG | + SILC_CF_OPER), SILC_SERVER_CMD(silcoper, SILCOPER, SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER), SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG | SILC_CF_REG), @@ -1693,10 +1694,6 @@ SILC_SERVER_CMD_FUNC(info) silc_server_command_free(cmd); } -SILC_SERVER_CMD_FUNC(connect) -{ -} - /* Server side of command PING. This just replies to the ping. */ SILC_SERVER_CMD_FUNC(ping) @@ -1736,10 +1733,6 @@ SILC_SERVER_CMD_FUNC(ping) silc_server_command_free(cmd); } -SILC_SERVER_CMD_FUNC(oper) -{ -} - /* Assembles USERS command and executes it. This is called when client joins to a channel and we wan't to send USERS command reply to the client. */ @@ -2965,22 +2958,159 @@ SILC_SERVER_CMD_FUNC(kick) silc_server_command_free(cmd); } +SILC_SERVER_CMD_FUNC(oper) +{ +} + +SILC_SERVER_CMD_FUNC(silcoper) +{ +} + +/* Server side command of CONNECT. Connects us to the specified remote + server or router. */ + +SILC_SERVER_CMD_FUNC(connect) +{ + SilcServerCommandContext cmd = (SilcServerCommandContext)context; + SilcServer server = cmd->server; + SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; + unsigned char *tmp; + unsigned int tmp_len; + unsigned int port; + + SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CONNECT, cmd, 0, 0); + + /* Check whether client has the permissions. */ + if (client->mode == SILC_UMODE_NONE) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE, + SILC_STATUS_ERR_NO_SERVER_PRIV); + goto out; + } + + if (server->server_type == SILC_ROUTER && + client->mode & SILC_UMODE_SERVER_OPERATOR) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE, + SILC_STATUS_ERR_NO_ROUTER_PRIV); + goto out; + } + + /* Get the remote server */ + tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len); + if (!tmp) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE, + SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); + goto out; + } + + /* Get port */ + tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); + if (tmp) + SILC_GET32_MSB(port, tmp); + + /* Create the connection. It is done with timeout and is async. */ + silc_server_create_connection(server, tmp, port); + + /* Send reply to the sender */ + silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE, + SILC_STATUS_OK); + + out: + silc_server_command_free(cmd); +} + SILC_SERVER_CMD_FUNC(restart) { } + +/* Server side command of CLOSE. Closes connection to a specified server. */ SILC_SERVER_CMD_FUNC(close) { + SilcServerCommandContext cmd = (SilcServerCommandContext)context; + SilcServer server = cmd->server; + SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; + SilcServerID *server_id; + SilcServerEntry server_entry; + unsigned char *tmp; + unsigned int tmp_len; + + SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 0, 0); + + /* Check whether client has the permissions. */ + if (client->mode == SILC_UMODE_NONE) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE, + SILC_STATUS_ERR_NO_SERVER_PRIV); + goto out; + } + + /* Get the server ID */ + tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len); + if (!tmp) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE, + SILC_STATUS_ERR_NO_SERVER_ID); + goto out; + } + server_id = silc_id_payload_parse_id(tmp, tmp_len); + if (!server_id) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE, + SILC_STATUS_ERR_NO_SERVER_ID); + goto out; + } + + /* Check that the server ID is valid and that I have an active + connection to it. Check only local list as it holds the local + connections. */ + server_entry = silc_idlist_find_server_by_id(server->local_list, + server_id, NULL); + if (!server_entry) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE, + SILC_STATUS_ERR_NO_SERVER_ID); + goto out; + } + + /* Close the connection to the server */ + silc_server_free_sock_user_data(server, server_entry->connection); + silc_server_disconnect_remote(server, server_entry->connection, + "Server closed connection: " + "Closed by operator"); + + /* Send reply to the sender */ + silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE, + SILC_STATUS_OK); + + out: + silc_server_command_free(cmd); } + +/* Server side command of SHUTDOWN. Shutdowns the server and closes all + active connections. */ -SILC_SERVER_CMD_FUNC(die) +SILC_SERVER_CMD_FUNC(shutdown) { + SilcServerCommandContext cmd = (SilcServerCommandContext)context; + SilcServer server = cmd->server; + SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; + + SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_SHUTDOWN, cmd, 0, 0); + + /* Check whether client has the permission. */ + if (client->mode == SILC_UMODE_NONE) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_SHUTDOWN, + SILC_STATUS_ERR_NO_SERVER_PRIV); + goto out; + } + + /* Then, gracefully, or not, bring the server down. */ + silc_server_stop(server); + + /* Send reply to the sender */ + silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE, + SILC_STATUS_OK); + + out: + silc_server_command_free(cmd); } -SILC_SERVER_CMD_FUNC(silcoper) -{ -} - /* Server side command of LEAVE. Removes client from a channel. */ SILC_SERVER_CMD_FUNC(leave) diff --git a/apps/silcd/command.h b/apps/silcd/command.h index 9180768a..8fc42e1e 100644 --- a/apps/silcd/command.h +++ b/apps/silcd/command.h @@ -150,7 +150,7 @@ SILC_SERVER_CMD_FUNC(kick); SILC_SERVER_CMD_FUNC(ignore); SILC_SERVER_CMD_FUNC(restart); SILC_SERVER_CMD_FUNC(close); -SILC_SERVER_CMD_FUNC(die); +SILC_SERVER_CMD_FUNC(shutdown); SILC_SERVER_CMD_FUNC(silcoper); SILC_SERVER_CMD_FUNC(leave); SILC_SERVER_CMD_FUNC(users); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 21565758..a020fa61 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -622,7 +622,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) /* Allocate connection object for hold connection specific stuff. */ sconn = silc_calloc(1, sizeof(*sconn)); sconn->server = server; - sconn->remote_host = server->config->routers->host; + sconn->remote_host = strdup(server->config->routers->host); sconn->remote_port = server->config->routers->port; silc_task_register(server->timeout_queue, fd, @@ -652,7 +652,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) /* Allocate connection object for hold connection specific stuff. */ sconn = silc_calloc(1, sizeof(*sconn)); sconn->server = server; - sconn->remote_host = ptr->host; + sconn->remote_host = strdup(ptr->host); sconn->remote_port = ptr->port; silc_task_register(server->timeout_queue, fd, @@ -870,8 +870,10 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) out: /* Free the temporary connection data context */ - if (sconn) + if (sconn) { + silc_free(sconn->remote_host); silc_free(sconn); + } /* Free the protocol object */ silc_protocol_free(protocol); @@ -1752,6 +1754,25 @@ void silc_server_packet_parse_type(SilcServer server, } +/* Creates connection to a remote router. */ + +void silc_server_create_connection(SilcServer server, + char *remote_host, unsigned int port) +{ + SilcServerConnection sconn; + + /* Allocate connection object for hold connection specific stuff. */ + sconn = silc_calloc(1, sizeof(*sconn)); + sconn->server = server; + sconn->remote_host = strdup(remote_host); + sconn->remote_port = port; + + silc_task_register(server->timeout_queue, 0, + silc_server_connect_router, + (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); +} + /* Closes connection to socket connection */ void silc_server_close_connection(SilcServer server, diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 1b83e1a8..4d4ab240 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -87,6 +87,8 @@ void silc_server_packet_parse(SilcPacketParserContext *parser_context); void silc_server_packet_parse_type(SilcServer server, SilcSocketConnection sock, SilcPacketContext *packet); +void silc_server_create_connection(SilcServer server, + char *remote_host, unsigned int port); void silc_server_close_connection(SilcServer server, SilcSocketConnection sock); void silc_server_free_client_data(SilcServer server, diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index 874b4520..bc0e3d75 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -57,7 +57,6 @@ typedef struct { } SilcServerStatistics; typedef struct { - void *id_entry; SilcSocketConnection sock; /* Remote host name and port */ diff --git a/doc/draft-riikonen-silc-spec-01.nroff b/doc/draft-riikonen-silc-spec-01.nroff index 7e9c35cb..1c286fc0 100644 --- a/doc/draft-riikonen-silc-spec-01.nroff +++ b/doc/draft-riikonen-silc-spec-01.nroff @@ -2258,15 +2258,12 @@ List of all defined commands in SILC follows. 11 SILC_COMMAND_CONNECT Max Arguments: 2 - Arguments: (1) - (2) [[ ]] + Arguments: (1) (2) [] This command is used by operators to force a server to try to - establish a new connection to another router (if the connecting - server is normal server) or server (if the connecting server is - router server). Operator may specify the server/router to be - connected by setting argument. The separator - between and is whitespace (` '). + establish a new connection to remote server or router. The + Operator must specify the server/router to be connected by + setting argument. The port is 32 bit MSB value. Reply messages to the command: @@ -2284,7 +2281,6 @@ List of all defined commands in SILC follows. SILC_STATUS_ERR_NOT_REGISTERED SILC_STATUS_ERR_NOT_ENOUGH_PARAMS SILC_STATUS_ERR_TOO_MANY_PARAMS - SILC_STATUS_ERR_NO_SUCH_SERVER_ID SILC_STATUS_ERR_NO_SERVER_PRIV SILC_STATUS_ERR_NO_ROUTER_PRIV @@ -2884,7 +2880,7 @@ List of all defined commands in SILC follows. SILC_STATUS_ERR_NO_SUCH_SERVER_ID - 22 SILC_COMMAND_DIE + 22 SILC_COMMAND_SHUTDOWN Max Arguments: 0 Arguments: None diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 8a3e6910..288a138a 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -51,7 +51,7 @@ SilcClientCommand silc_command_list[] = SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), SILC_CLIENT_CMD(close, CLOSE, "CLOSE", SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), - SILC_CLIENT_CMD(die, DIE, "DIE", + SILC_CLIENT_CMD(shutdown, SHUTDOWN, "SHUTDOWN", SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), SILC_CLIENT_CMD(silcoper, SILCOPER, "SILOPER", SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER, 2), @@ -1237,7 +1237,7 @@ SILC_CLIENT_CMD_FUNC(close) { } -SILC_CLIENT_CMD_FUNC(die) +SILC_CLIENT_CMD_FUNC(shutdown) { } diff --git a/lib/silcclient/command.h b/lib/silcclient/command.h index cf236483..a47c7461 100644 --- a/lib/silcclient/command.h +++ b/lib/silcclient/command.h @@ -164,7 +164,7 @@ SILC_CLIENT_CMD_FUNC(cumode); SILC_CLIENT_CMD_FUNC(kick); SILC_CLIENT_CMD_FUNC(restart); SILC_CLIENT_CMD_FUNC(close); -SILC_CLIENT_CMD_FUNC(die); +SILC_CLIENT_CMD_FUNC(shutdown); SILC_CLIENT_CMD_FUNC(silcoper); SILC_CLIENT_CMD_FUNC(leave); SILC_CLIENT_CMD_FUNC(users); diff --git a/lib/silccore/silccommand.h b/lib/silccore/silccommand.h index d6e98263..4f29464c 100644 --- a/lib/silccore/silccommand.h +++ b/lib/silccore/silccommand.h @@ -76,7 +76,7 @@ typedef enum { #define SILC_COMMAND_KICK 19 #define SILC_COMMAND_RESTART 20 #define SILC_COMMAND_CLOSE 21 -#define SILC_COMMAND_DIE 22 +#define SILC_COMMAND_SHUTDOWN 22 #define SILC_COMMAND_SILCOPER 23 #define SILC_COMMAND_LEAVE 24 #define SILC_COMMAND_USERS 25 diff --git a/lib/silccore/silcmode.h b/lib/silccore/silcmode.h index 26b45c74..53d04ee4 100644 --- a/lib/silccore/silcmode.h +++ b/lib/silccore/silcmode.h @@ -39,4 +39,9 @@ #define SILC_CHANNEL_UMODE_CHANFO 0x0001 /* channel founder */ #define SILC_CHANNEL_UMODE_CHANOP 0x0002 /* channel operator */ +/* SILC modes */ +#define SILC_UMODE_NONE 0x0000 /* Normal SILC user */ +#define SILC_UMODE_SERVER_OPERATOR 0x0001 /* Server operator */ +#define SILC_UMODE_ROUTER_OPERATOR 0x0002 /* Router (SILC) operator */ + #endif -- 2.24.0