+Thu Oct 11 22:19:26 EDT 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Changed the backup router adding and getting interfaces
+ in the server. The router that will be replaced by the
+ specified backup router is now sent as argument. Affected
+ files silcd/serverconfig.[ch], silcd/backup_router.[ch], and
+ silcd/server.c.
+
+ * Added silc_net_addr2bin_ne to return the binary form of
+ the IP address in network byte order. Affected files
+ lib/silcutil/[unix/win32].silc[unix/win32]net.[ch].
+
Thu Oct 11 12:14:19 EDT 2001 Pekka Riikonen <priikone@silcnet.org>
* Check for existing server ID in silc_server_new_server
TODO/bugs in Irssi SILC client
==============================
+ o /key msg * list crashes the client
+
o Add local command to switch the channel's private key when channel has
several private keys. Currently sending channel messages with many
keys is not possible because changing the key is not possible by the
sconn->remote_host = strdup(ptr->host);
sconn->remote_port = ptr->port;
sconn->backup = ptr->backup_router;
-
+ if (sconn->backup) {
+ sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
+ sconn->backup_replace_port = ptr->backup_replace_port;
+ }
+
silc_schedule_task_add(server->schedule, fd,
silc_server_connect_router,
(void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
}
} else {
/* Add this server to be our backup router */
- silc_server_backup_add(server, id_entry, FALSE);
+ silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
+ sconn->backup_replace_port, FALSE);
}
sock->protocol = NULL;
/* Free the temporary connection data context */
if (sconn) {
silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
silc_free(sconn);
}
/* If the incoming connection is router and marked as backup router
then add it to be one of our backups */
if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && conn->backup_router) {
- silc_server_backup_add(server, new_server, conn->backup_local);
+ silc_server_backup_add(server, new_server, conn->backup_replace_ip,
+ conn->backup_replace_port, conn->backup_local);
/* Change it back to SERVER type since that's what it really is. */
if (conn->backup_local) {
SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
SilcServerEntry backup_router = NULL;
+ if (user_data->id)
+ backup_router = silc_server_backup_get(server, user_data->id);
+
/* If this was our primary router connection then we're lost to
the outside world. */
if (server->router == user_data) {
- backup_router = silc_server_backup_get(server);
-
/* Check whether we have a backup router connection */
if (!backup_router || backup_router == user_data) {
silc_schedule_task_add(server->schedule, 0,
server->id_entry->router = backup_router;
server->router = backup_router;
server->router_connect = time(0);
+ server->backup_primary = TRUE;
if (server->server_type == SILC_BACKUP_ROUTER) {
server->server_type = SILC_ROUTER;
silc_server_backup_replaced_add(server, user_data->id,
backup_router);
}
+ } else if (backup_router) {
+ SILC_LOG_INFO(("Enabling the use of backup router %s",
+ backup_router->server_name));
+ SILC_LOG_DEBUG(("Enabling the use of backup router %s",
+ backup_router->server_name));
+
+ /* Mark this connection as replaced */
+ silc_server_backup_replaced_add(server, user_data->id,
+ backup_router);
}
if (!backup_router) {
The backup router knows all the other stuff already. */
if (server->server_type == SILC_ROUTER)
silc_server_announce_servers(server, FALSE, time(0) - 300,
- server->router->connection);
+ backup_router->connection);
/* Announce our clients and channels to the router */
silc_server_announce_clients(server, time(0) - 300,
- server->router->connection);
+ backup_router->connection);
silc_server_announce_channels(server, time(0) - 300,
- server->router->connection);
+ backup_router->connection);
}
break;
}
char *remote_host;
int remote_port;
bool backup;
+ char *backup_replace_ip;
+ int backup_replace_port;
/* Current connection retry info */
uint32 retry_count;
/* Backup router */
typedef struct {
SilcServerEntry server;
+ SilcIDIP ip;
+ uint16 port;
bool local;
} SilcServerBackupEntry;
long start;
} *SilcServerBackupProtocolContext;
-/* Sets the `backup_server' to be one of our backup router. This can be
- called multiple times to set multiple backup routers. If `local' is
- TRUE then the `backup_server' is in the local cell, if FALSE it is
- in some other cell. */
+/* Adds the `backup_server' to be one of our backup router. This can be
+ called multiple times to set multiple backup routers. The `ip' and `port'
+ is the IP and port that the `backup_router' will replace if the `ip'
+ will become unresponsive. If `local' is TRUE then the `backup_server' is
+ in the local cell, if FALSE it is in some other cell. */
void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server,
- bool local)
+ const char *ip, int port, bool local)
{
int i;
+ SILC_LOG_DEBUG(("Start"));
+
+ if (!ip)
+ return;
+
if (!server->backup)
server->backup = silc_calloc(1, sizeof(*server->backup));
if (!server->backup->servers[i].server) {
server->backup->servers[i].server = backup_server;
server->backup->servers[i].local = local;
+ memset(server->backup->servers[i].ip.data, 0,
+ sizeof(server->backup->servers[i].ip.data));
+ silc_net_addr2bin_ne(ip, server->backup->servers[i].ip.data,
+ sizeof(server->backup->servers[i].ip.data));
+ //server->backup->servers[i].port = port;
return;
}
}
(i + 1));
server->backup->servers[i].server = backup_server;
server->backup->servers[i].local = local;
+ memset(server->backup->servers[i].ip.data, 0,
+ sizeof(server->backup->servers[i].ip.data));
+ silc_net_addr2bin_ne(ip, server->backup->servers[i].ip.data,
+ sizeof(server->backup->servers[i].ip.data));
+ //server->backup->servers[i].port = server_id->port;
server->backup->servers_count++;
}
-/* Returns the first backup router context. Returns NULL if we do not have
- any backup servers. */
+/* Returns backup router for IP and port in `replacing' or NULL if there
+ does not exist backup router. */
-SilcServerEntry silc_server_backup_get(SilcServer server)
+SilcServerEntry silc_server_backup_get(SilcServer server,
+ SilcServerID *server_id)
{
- SilcServerEntry backup_router;
int i;
+ SILC_LOG_DEBUG(("Start"));
+
if (!server->backup)
return NULL;
for (i = 0; i < server->backup->servers_count; i++) {
- if (server->backup->servers[i].server) {
- backup_router = server->backup->servers[i].server;
- server->backup->servers[i].server = NULL;
- return backup_router;
- }
+ SILC_LOG_HEXDUMP(("IP"), server_id->ip.data, 16);
+ SILC_LOG_HEXDUMP(("IP"), server->backup->servers[i].ip.data, 16);
+ if (server->backup->servers[i].server &&
+ !memcmp(&server->backup->servers[i].ip, &server_id->ip.data,
+ sizeof(server_id->ip.data)))
+ return server->backup->servers[i].server;
}
return NULL;
}
-/* Deletes the backup server `server_entry. */
-
-void silc_server_backup_del(SilcServer server,
- SilcServerEntry server_entry)
+/* Deletes the backup server `server_entry'. */
+void silc_server_backup_del(SilcServer server, SilcServerEntry server_entry)
{
int i;
+ SILC_LOG_DEBUG(("Start"));
+
if (!server->backup)
return ;
int i;
SilcServerBackupReplaced *r = silc_calloc(1, sizeof(*r));;
+ SILC_LOG_DEBUG(("Start"));
+
if (!server->backup)
server->backup = silc_calloc(1, sizeof(*server->backup));
if (!server->backup->replaced) {
{
int i;
- SILC_LOG_DEBUG(("***********************************************"));
+ SILC_LOG_DEBUG(("Start"));
+
+ SILC_LOG_DEBUG(("*************************************"));
if (!server->backup || !server->backup->replaced)
return FALSE;
SILC_LOG_HEXDUMP(("IP"), server_id->ip.data, server_id->ip.data_len);
SILC_LOG_HEXDUMP(("IP"), server->backup->replaced[i]->ip.data,
server->backup->replaced[i]->ip.data_len);
- if (!memcmp(&server->backup->replaced[i]->ip, &server_id->ip,
- sizeof(server_id->ip))) {
+ if (!memcmp(&server->backup->replaced[i]->ip, &server_id->ip.data,
+ sizeof(server_id->ip.data))) {
if (server_entry)
*server_entry = server->backup->replaced[i]->server;
SILC_LOG_DEBUG(("REPLACED"));
{
int i;
+ SILC_LOG_DEBUG(("Start"));
+
if (!server->backup || !server->backup->replaced)
return;
SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("********************************"));
ret = silc_buffer_unformat(packet->buffer,
SILC_STR_UI_CHAR(&type),
SILC_STR_UI_CHAR(&session),
if (ret < 0)
return;
+ SILC_LOG_DEBUG(("********************************"));
/* If the backup resuming protocol is active then process the packet
in the protocol. */
if (sock->protocol && sock->protocol->protocol &&
return;
}
+ SILC_LOG_DEBUG(("********************************"));
/* We don't have protocol active. If we are router and the packet is
coming from our primary router then lets check whether it means we've
been replaced by an backup router in my cell. This is usually received
to use it at this moment. */
SilcIDListData idata = (SilcIDListData)sock->user_data;
+ SILC_LOG_INFO(("We are replaced by an backup router in this cell, will "
+ "wait untill backup resuming protocol is executed"));
+
SILC_LOG_DEBUG(("We are replaced by an backup router in this cell"));
idata->status |= SILC_IDLIST_STATUS_DISABLED;
return;
}
+ SILC_LOG_DEBUG(("********************************"));
if (type == SILC_SERVER_BACKUP_START ||
type == SILC_SERVER_BACKUP_START_GLOBAL) {
/* We have received a start for resuming protocol. */
silc_server_protocol_backup_done);
silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
}
+ SILC_LOG_DEBUG(("EEEEEEEEEEEEEEEEEEEEEEEEe"));
}
/* Timeout task callback to connect to remote router */
if (sock < 0) {
silc_schedule_task_add(server->schedule, 0,
silc_server_backup_connect_to_router,
- context, 2, 0, SILC_TASK_TIMEOUT,
+ context, 5, 0, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
return;
}
sconn->callback_context = context;
silc_schedule_task_add(server->schedule, 0,
silc_server_backup_connect_to_router,
- sconn, 2, 0, SILC_TASK_TIMEOUT,
+ sconn, 1, 0, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
}
(SilcServerBackupProtocolContext)backup_router->protocol->context;
SilcBuffer buffer;
+ SILC_LOG_DEBUG(("Start"));
+
SILC_LOG_DEBUG(("********************************"));
SILC_LOG_DEBUG(("Sending CONNECTED packet, session %d", ctx->session));
to be back online. We send the CONNECTED packet after we've
established the connection to the primary router. */
primary = silc_server_config_get_primary_router(server->config);
- if (primary) {
+ if (primary && server->backup_primary) {
silc_server_backup_reconnect(server,
primary->host, primary->port,
silc_server_backup_connect_primary,
ctx->sock);
- if (server->server_type == SILC_ROUTER &&
- (!server->router ||
- server->router->data.status & SILC_IDLIST_STATUS_DISABLED))
- protocol->state++;
- else
- protocol->state = SILC_PROTOCOL_STATE_END;
-
} else {
/* Nowhere to connect just return the CONNECTED packet */
SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
- protocol->state++;
}
+ if (server->server_type == SILC_ROUTER &&
+ (!server->router ||
+ server->router->data.status & SILC_IDLIST_STATUS_DISABLED))
+ protocol->state++;
+ else
+ protocol->state = SILC_PROTOCOL_STATE_END;
+
ctx->sessions = silc_realloc(ctx->sessions,
sizeof(*ctx->sessions) *
(ctx->sessions_count + 1));
SILC_LOG_DEBUG(("********************************"));
SILC_LOG_DEBUG(("RESUMED packet"));
+ server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
+
/* This connection is performing this protocol too now */
((SilcSocketConnection)server_entry->connection)->protocol =
protocol;
silc_server_update_clients_by_server(server, backup_router,
primary, TRUE, FALSE);
silc_server_backup_replaced_del(server, backup_router);
- silc_server_backup_add(server, backup_router,
+ silc_server_backup_add(server, backup_router,
+ ((SilcSocketConnection)primary->
+ connection)->ip,
+ ((SilcSocketConnection)primary->
+ connection)->port,
backup_router->server_type != SILC_ROUTER ?
TRUE : FALSE);
}
#define SILC_SERVER_BACKUP_REPLACED 20
/* Adds the `backup_server' to be one of our backup router. This can be
- called multiple times to set multiple backup routers. If `local' is
- TRUE then the `backup_server' is in the local cell, if FALSE it is
- in some other cell. */
+ called multiple times to set multiple backup routers. The `replacing' is
+ the IP and port that the `backup_router' will replace if the `replacing'
+ will become unresponsive. If `local' is TRUE then the `backup_server' is
+ in the local cell, if FALSE it is in some other cell. */
void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server,
- bool local);
+ const char *ip, int port, bool local);
-/* Returns the first backup router context. Returns NULL if we do not have
- any backup servers. This removes the returned server from being
- backup router and needs to be added later with silc_server_backup_add
- if it needs to be backup router again. */
-SilcServerEntry silc_server_backup_get(SilcServer server);
+/* Returns backup router for IP and port in `replacing' or NULL if there
+ does not exist backup router. */
+SilcServerEntry silc_server_backup_get(SilcServer server,
+ SilcServerID *server_id);
-/* Deletes the backup server `server_entry. */
-void silc_server_backup_del(SilcServer server,
- SilcServerEntry server_entry);
+/* Deletes the backup server `server_entry'. */
+void silc_server_backup_del(SilcServer server, SilcServerEntry server_entry);
/* Marks the IP address and port from the `server_id' as being replaced
by backup router indicated by the `server'. If the router connects at
SilcServerEntry router; /* Pointer to the primary router */
unsigned long router_connect; /* Time when router was connected */
SilcServerBackup backup; /* Backup routers */
- bool backup_router;
+ bool backup_router; /* TRUE if this is backup router */
+ bool backup_primary; /* TRUE if we've switched our primary
+ router to a backup router. */
/* Current command identifier, 0 not used */
uint16 cmd_ident;
silc_free(tmp);
}
- /* Check whether this connection is backup router connection */
- ret = silc_config_get_token(line, &tmp);
- if (ret != -1) {
- config->routers->backup_router = atoi(tmp);
- if (config->routers->backup_router != 0)
- config->routers->backup_router = TRUE;
- silc_free(tmp);
- }
-
- /* Check whether this backup is local (in cell) or remote (other cell) */
- ret = silc_config_get_token(line, &tmp);
- if (ret != -1) {
- config->routers->backup_local = atoi(tmp);
- if (config->routers->backup_local != 0)
- config->routers->backup_local = TRUE;
- silc_free(tmp);
+ /* Get backup replace IP */
+ ret = silc_config_get_token(line, &config->routers->backup_replace_ip);
+ if (ret != -1)
+ config->routers->backup_router = TRUE;
+
+ if (config->routers->backup_router) {
+ /* Get backup replace port */
+ ret = silc_config_get_token(line, &tmp);
+ if (ret != -1) {
+ config->routers->backup_replace_port = atoi(tmp);
+ silc_free(tmp);
+ }
+
+ /* Check whether the backup connection is local */
+ ret = silc_config_get_token(line, &tmp);
+ if (ret != -1) {
+ config->routers->backup_local = atoi(tmp);
+ if (config->routers->backup_local != 0)
+ config->routers->backup_local = TRUE;
+ silc_free(tmp);
+ }
}
check = TRUE;
uint32 class;
bool initiator;
bool backup_router;
+ char *backup_replace_ip;
+ uint16 backup_replace_port;
bool backup_local;
struct SilcServerConfigSectionServerConnectionStruct *next;
struct SilcServerConfigSectionServerConnectionStruct *prev;
endif
if SILC_DIST_TOOLKIT
-SILC_EXTRA_DIST = toolkit
+SILC_EXTRA_DIST = toolkit examples
+else
+if SILC_DIST_SERVER
+SILC_EXTRA_DIST = examples
else
SILC_EXTRA_DIST =
endif
+endif
EXTRA_DIST = \
CodingStyle \
+#
+# Example configuration file. Note that this attempts to present various
+# configuration possibilities and may not actually give any sensible
+# configuration. For real life example see the examples/ directory.
+#
+
#
# Configured ciphers.
#
# configured connection is the primary route.
#
# Format: <remote host>:<auth method>:<auth data>:<port>:<version ID>:
-# <class>:<initiator>:<backup connection>:<local backup>
+# <class>:<initiator>:<backup replace IP>:<backup replace port>:
+# <local backup>
#
# The <auth data> is either passphrase or file path to the public key
# file. If you are the initiator of the connection then set the <initiator>
# incoming connection) then set it to 0.
#
# If the connection is backup router connection then set the <backup
-# connection> to value 1. For normal connection set it to 0. If this
+# replace IP> to the IP address of the router that the backup router will
+# replace if it becomes unavailable. Set also the router's port to the
+# <backup replace port>. For normal connection leave both empty. If this
# backup router is in our cell then set the <local backup> to value 1.
# If the backup router is in other cell then set it to value 0.
#
[RouterConnection]
-#10.2.1.100:passwd:veryverysecret:706:1:1:1:0:0
-#10.2.100.131:pubkey:/path/to/the/publickey:706:1:1:1:0:0
-#10.2.100.100:pubkey:/path/to/the/publickey:706:1:1:0:1:1
+#10.2.1.100:passwd:veryverysecret:706:1:1:1
+#10.2.100.131:pubkey:/path/to/the/publickey:706:1:1:1
+#10.2.100.100:pubkey:/path/to/the/publickey:706:1:1:0:10.2.1.6:706:1
#
# Denied connections.
This directory includes example files for a small SILC network. The
-network conists of three (3) routers, and seven (7) servers. One of
+network consists of three (3) routers, and seven (7) servers. One of
the cell also has a backup router too. The topology of the network is
as follows:
make authentication simple all servers and routers authenticate themselves
to other routers by simple password.
+Also note that the format in the configuration file is very raw so if you
+need any help to understand what some setting means please check the
+documented example configuration files in doc/ directory. Mainly, the
+example_silcd.conf.
+
If you want to test this network you should change the IP addresses
in the configuration file or perhaps set IP aliases for you local
machine.
[ServerConnection]
# backup connections
-212.146.42.101:passwd:priikone:706:1:1
-212.146.42.102:passwd:priikone:706:1:1
+212.146.42.101:passwd:priikone:706:1:1:1
+212.146.42.102:passwd:priikone:706:1:1:1
[RouterConnection]
# my primary
-212.146.42.250:passwd:priikone:706:1:1:1:0
+212.146.42.250:passwd:priikone:706:1:1:1
# backup connection to my primary's primary
-212.146.42.251:passwd:priikone:706:1:1:1:1
+212.146.42.251:passwd:priikone:706:1:1:1:212.146.42.250:706
# this use my primary as it's primary and me as backup
-212.146.42.252:passwd:priikone:706:1:1:0:1
+212.146.42.252:passwd:priikone:706:1:1:0:212.146.42.250:706
[DenyConnection]
[RouterConnection]
# my primary
-212.146.42.251:passwd:priikone:706:1:1:1:0
+212.146.42.251:passwd:priikone:706:1:1:1
# this use me as primary
-212.146.42.252:passwd:priikone:706:1:1:0:0
-# our backup router
-212.146.42.100:passwd:priikone:706:1:1:0:1:1
+212.146.42.252:passwd:priikone:706:1:1:0
+# our backup router (it will replace me if I'll go down)
+212.146.42.100:passwd:priikone:706:1:1:0:212.146.42.250:706:1
[DenyConnection]
[RouterConnection]
# my primary
-212.146.42.252:passwd:priikone:706:1:1:1:0
+212.146.42.252:passwd:priikone:706:1:1:1
# this use me as primary
-212.146.42.250:passwd:priikone:706:1:1:0:0
+212.146.42.250:passwd:priikone:706:1:1:0
# this is the 212.146.42.250 router's backup router
-212.146.42.100:passwd:priikone:706:1:1:0:1:0
+212.146.42.100:passwd:priikone:706:1:1:0:212.146.42.250:706:0
[DenyConnection]
[RouterConnection]
# my primary
-212.146.42.250:passwd:priikone:706:1:1:1:0
+212.146.42.250:passwd:priikone:706:1:1:1
# this use me as primary
-212.146.42.251:passwd:priikone:706:1:1:0:0
+212.146.42.251:passwd:priikone:706:1:1:0
# this is 212.146.42.250 router's (my primary's) backup router
-212.146.42.100:passwd:priikone:706:1:1:1:1:0
+212.146.42.100:passwd:priikone:706:1:1:1:212.146.42.250:706:0
[DenyConnection]
{
return getsockopt(sock, level, option, optval, opt_len);
}
+
/* Checks whether IP address sent as argument is valid IP address. */
bool silc_net_is_ip(const char *addr)
bool silc_net_addr2bin(const char *addr, unsigned char *bin,
uint32 bin_len);
+/****f* silcutil/SilcNetAPI/silc_net_addr2bin_ne
+ *
+ * SYNOPSIS
+ *
+ * bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
+ * uint32 bin_len);
+ *
+ * DESCRIPTION
+ *
+ * Converts the IP number string from numbers-and-dots notation to
+ * binary form in network byte order.
+ *
+ ***/
+bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
+ uint32 bin_len);
+
/****f* silcutil/SilcNetAPI/silc_net_check_host_by_sock
*
* SYNOPSIS
return ret != 0;
}
+
+/* Converts the IP number string from numbers-and-dots notation to
+ binary form in network byte order. */
+
+bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
+ uint32 bin_len)
+{
+ struct in_addr tmp;
+ int ret;
+
+ ret = inet_aton(addr, &tmp);
+
+ if (bin_len < 4)
+ return FALSE;
+
+ SILC_PUT32_MSB(tmp.s_addr, bin);
+
+ return ret != 0;
+}
return ret != INADDR_NONE;
}
+/* Converts the IP number string from numbers-and-dots notation to
+ binary form in network byte order. */
+
+bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
+ uint32 bin_len)
+{
+ unsigned long ret;
+
+ ret = inet_addr(addr);
+
+ if (bin_len < 4)
+ return FALSE;
+
+ SILC_PUT32_MSB(ret, bin);
+
+ return ret != INADDR_NONE;
+}
+
/* Set socket to non-blocking mode. */
int silc_net_set_socket_nonblock(int sock)