TRUE : FALSE, cipher, hmac, sequence,
silc_server_packet_parse, server);
- /* If this socket connection is not authenticated yet and the packet
- processing failed we will drop the connection since it can be
- a malicious flooder. */
- if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
- (!sock->protocol || sock->protocol->protocol->type ==
- SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
- SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
- SILC_SET_DISCONNECTING(sock);
+ /* 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);
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
server->server_name,
server->router->server_name));
}
+ server->backup_noswitch = FALSE;
/* Free the server entry */
silc_server_backup_del(server, user_data);
}
silc_hash_table_del(client->channels, channel);
- silc_hash_table_del(channel->user_list, chl->client);
+ silc_hash_table_del(channel->user_list, client);
channel->user_count--;
/* If there is no global users on the channel anymore mark the channel
chl->client->router && !silc_server_channel_has_global(channel))
channel->global_users = FALSE;
+ memset(chl, 'A', sizeof(*chl));
silc_free(chl);
/* Update statistics */
return FALSE;
}
- silc_hash_table_del(client->channels, chl->channel);
- silc_hash_table_del(channel->user_list, chl->client);
+ silc_hash_table_del(client->channels, channel);
+ silc_hash_table_del(channel->user_list, client);
channel->user_count--;
/* If there is no global users on the channel anymore mark the channel
chl->client->router && !silc_server_channel_has_global(channel))
channel->global_users = FALSE;
+ memset(chl, 'O', sizeof(*chl));
silc_free(chl);
/* Update statistics */
return buffer;
}
-/* Finds client entry by Client ID and if it is not found then resolves
- it using WHOIS command. */
-
-SilcClientEntry silc_server_get_client_resolve(SilcServer server,
- SilcClientID *client_id,
- bool always_resolve,
- bool *resolved)
-{
- SilcClientEntry client;
-
- if (resolved)
- *resolved = FALSE;
-
- client = silc_idlist_find_client_by_id(server->local_list, client_id,
- TRUE, NULL);
- if (!client) {
- client = silc_idlist_find_client_by_id(server->global_list,
- client_id, TRUE, NULL);
- if (!client && server->server_type == SILC_ROUTER)
- return NULL;
- }
-
- if (!client && server->standalone)
- return NULL;
-
- if (!client || !client->nickname || !client->username ||
- always_resolve) {
- SilcBuffer buffer, idp;
-
- if (client) {
- client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
- client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
- client->resolve_cmd_ident = ++server->cmd_ident;
- }
-
- idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
- buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
- server->cmd_ident, 1,
- 4, idp->data, idp->len);
- silc_server_packet_send(server, client ? client->router->connection :
- SILC_PRIMARY_ROUTE(server),
- SILC_PACKET_COMMAND, 0,
- buffer->data, buffer->len, FALSE);
- silc_buffer_free(idp);
- silc_buffer_free(buffer);
-
- if (resolved)
- *resolved = TRUE;
-
- return NULL;
- }
-
- return client;
-}
-
/* A timeout callback for the re-key. We will be the initiator of the
re-key protocol. */