/* If we are backup router then this primary router is whom we are
backing up. */
if (server->server_type == SILC_BACKUP_ROUTER)
- silc_server_backup_add(server, server->id_entry, sock->ip, 0, TRUE);
+ silc_server_backup_add(server, server->id_entry, sock->ip,
+ sconn->remote_port, TRUE);
}
} else {
/* Add this server to be our backup router */
/* If processing failed the connection is closed. */
if (!ret) {
+ /* On packet processing errors we may close our primary router
+ connection but won't become primary router if we are the backup
+ since this is local error condition. */
+ if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
+ server->backup_noswitch = TRUE;
+
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
silc_server_close_connection(server, sock);
SilcServer server = (SilcServer)context;
SilcSocketConnection sock = parser_context->sock;
SilcIDListData idata = (SilcIDListData)sock->user_data;
+ bool ret;
if (idata)
idata->psn_receive = parser_context->packet->sequence + 1;
the idata->receive_key might have become valid in the last packet
and we want to call this processor with valid cipher. */
if (idata)
- silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
+ ret = silc_packet_receive_process(
+ sock, server->server_type == SILC_ROUTER ?
TRUE : FALSE, idata->receive_key,
idata->hmac_receive, idata->psn_receive,
silc_server_packet_parse, server);
else
- silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
+ ret = silc_packet_receive_process(
+ sock, server->server_type == SILC_ROUTER ?
TRUE : FALSE, NULL, NULL, 0,
silc_server_packet_parse, server);
+
+ if (!ret) {
+ /* On packet processing errors we may close our primary router
+ connection but won't become primary router if we are the backup
+ since this is local error condition. */
+ if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
+ server->backup_noswitch = TRUE;
+
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_server_close_connection(server, sock);
+ }
+
return FALSE;
}
char *cp;
int len;
- if (!sock)
+ if (!sock || SILC_IS_DISCONNECTED(sock))
return;
memset(buf, 0, sizeof(buf));
sock->type != SILC_SOCKET_TYPE_ROUTER)
backup_router = NULL;
- if (server->server_shutdown)
+ if (server->server_shutdown || server->backup_noswitch)
backup_router = NULL;
/* If this was our primary router connection then we're lost to
/* Mark this connection as replaced */
silc_server_backup_replaced_add(server, user_data->id,
backup_router);
+ } else if (server->server_type == SILC_SERVER &&
+ sock->type == SILC_SOCKET_TYPE_ROUTER) {
+ /* Reconnect to the router (backup) */
+ silc_schedule_task_add(server->schedule, 0,
+ silc_server_connect_to_router,
+ server, 1, 0,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
}
if (!backup_router) {
server->server_name,
server->router->server_name));
}
+ server->backup_noswitch = FALSE;
/* Free the server entry */
silc_server_backup_del(server, user_data);
return;
}
- if (sock->user_data)
- silc_server_free_sock_user_data(server, sock, NULL);
-
silc_server_disconnect_remote(server, sock,
protocol ==
SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
SILC_STATUS_ERR_AUTH_FAILED :
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
"Connection timeout");
+
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
}
/* Creates new channel. Sends NEW_CHANNEL packet to primary route. This