SilcUInt32 tmp_len, tmp2_len;
SilcBool local, ret;
- if (idata->conn_type == SILC_CONN_CLIENT ||
- packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) {
+ if (idata->conn_type == SILC_CONN_CLIENT) {
+ SILC_LOG_DEBUG(("Notify received from client, drop it"));
+ return;
+ }
+
+ if (packet->src_id_type != SILC_ID_SERVER){
+ SILC_LOG_DEBUG(("Bad notify packet received"));
+ return;
+ }
+
+ if (!packet->dst_id) {
SILC_LOG_DEBUG(("Bad notify packet received"));
return;
}
/* Parse the Notify Payload */
payload = silc_notify_payload_parse(buffer->data, silc_buffer_len(buffer));
- if (!payload)
+ if (!payload) {
+ SILC_LOG_DEBUG(("Marlformed notify payload"));
return;
+ }
/* If we are router and this packet is not already broadcast packet
we will broadcast it. The sending socket really cannot be router or
/* Packet is destined to channel */
if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
packet->dst_id_type, &channel_id,
- sizeof(channel_id)))
+ sizeof(channel_id))) {
+ SILC_LOG_DEBUG(("Malformed destination ID in notify packet"));
goto out;
+ }
silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
packet->type, packet->flags |
type = silc_notify_get_type(payload);
args = silc_notify_get_args(payload);
- if (!args)
+ if (!args) {
+ SILC_LOG_DEBUG(("Notify doesn't have any arguments, drop it"));
goto out;
+ }
switch(type) {
case SILC_NOTIFY_TYPE_JOIN:
channel = silc_idlist_find_channel_by_id(server->local_list,
SILC_ID_GET_ID(id), NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
goto out;
}
}
channel = silc_idlist_find_channel_by_id(server->local_list,
&channel_id, NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(&channel_id, SILC_ID_CHANNEL)));
goto out;
}
}
tmp_len = 128;
/* Update statistics */
+ SILC_VERIFY(server->stat.clients > 0);
server->stat.clients--;
if (server->stat.cell_clients)
server->stat.cell_clients--;
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
silc_schedule_task_del_by_context(server->schedule, client);
- /* Remove from public key hash table. */
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash, client->data.public_key,
- client);
+ /* Remove client's public key from repository, this will free it too. */
+ if (client->data.public_key) {
+ silc_skr_del_public_key(server->repository, client->data.public_key,
+ client);
+ client->data.public_key = NULL;
+ }
/* Remove the client from all channels. */
silc_server_remove_from_channels(server, NULL, client, TRUE,
client->mode = 0;
client->router = NULL;
client->connection = NULL;
+ client->data.created = silc_time();
+ silc_dlist_del(server->expired_clients, client);
+ silc_dlist_add(server->expired_clients, client);
break;
case SILC_NOTIFY_TYPE_TOPIC_SET:
channel = silc_idlist_find_channel_by_id(server->local_list,
&channel_id, NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(&channel_id, SILC_ID_CHANNEL)));
goto out;
}
}
channel = silc_idlist_find_channel_by_id(server->local_list,
&channel_id, NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(&channel_id, SILC_ID_CHANNEL)));
goto out;
}
}
channel = silc_idlist_find_channel_by_id(server->local_list,
&channel_id, NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(&channel_id, SILC_ID_CHANNEL)));
goto out;
}
}
channel = silc_idlist_find_channel_by_id(server->local_list,
SILC_ID_GET_ID(id), NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
goto out;
}
}
channel = silc_idlist_find_channel_by_id(server->global_list,
SILC_ID_GET_ID(id), NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
goto out;
}
}
/* Get client entry */
client = silc_idlist_find_client_by_id(server->global_list,
- SILC_ID_GET_ID(id),
+ SILC_ID_GET_ID(id2),
TRUE, &cache);
local = FALSE;
if (!client) {
client = silc_idlist_find_client_by_id(server->local_list,
- SILC_ID_GET_ID(id),
+ SILC_ID_GET_ID(id2),
TRUE, &cache);
local = TRUE;
if (!client)
}
/* Update statistics */
+ SILC_VERIFY(server->stat.clients > 0);
server->stat.clients--;
if (server->stat.cell_clients)
server->stat.cell_clients--;
if (local)
silc_server_del_from_watcher_list(server, client);
- /* Remove from public key hash table. */
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- client->data.public_key,
- client);
-
/* Remove the client */
+ silc_dlist_del(server->expired_clients, client);
silc_idlist_del_data(client);
silc_idlist_del_client(local ? server->local_list :
server->global_list, client);
channel = silc_idlist_find_channel_by_id(server->local_list,
&channel_id, NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
goto out;
}
}
silc_server_check_watcher_list(server, client, NULL,
SILC_NOTIFY_TYPE_KILLED);
- /* Remove from public key hash table. */
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- client->data.public_key,
- client);
+ /* Remove client's public key from repository, this will free it too. */
+ if (client->data.public_key) {
+ silc_skr_del_public_key(server->repository, client->data.public_key,
+ client);
+ client->data.public_key = NULL;
+ }
/* Update statistics */
+ SILC_VERIFY(server->stat.clients > 0);
server->stat.clients--;
if (server->stat.cell_clients)
server->stat.cell_clients--;
client->mode = 0;
client->router = NULL;
client->connection = NULL;
+ client->data.created = silc_time();
+ silc_dlist_del(server->expired_clients, client);
+ silc_dlist_add(server->expired_clients, client);
break;
}
channel = silc_idlist_find_channel_by_id(server->local_list,
SILC_ID_GET_ID(id), NULL);
if (!channel) {
- SILC_LOG_DEBUG(("Notify for unknown channel"));
+ SILC_LOG_DEBUG(("Notify for unknown channel %s",
+ silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
goto out;
}
}
if (!client)
goto out;
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- client->data.public_key,
- client);
-
silc_server_remove_from_channels(server, NULL, client, TRUE,
NULL, TRUE, FALSE);
+ silc_dlist_del(server->expired_clients, client);
silc_idlist_del_data(client);
silc_idlist_del_client(server->global_list, client);
}
break;
default:
+ SILC_LOG_DEBUG(("Unsupported notify %d", type));
break;
}
SilcPacket packet)
{
silc_server_notify_process(server, sock, packet, &packet->buffer);
+ silc_packet_free(packet);
}
void silc_server_notify_list(SilcServer server,
silc_buffer_pull(&packet->buffer, len);
}
+ silc_packet_free(packet);
silc_buffer_free(buffer);
}
if (packet->src_id_type != SILC_ID_CLIENT ||
packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
- return;
+ goto out;
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
if (client && client->mode & SILC_UMODE_DETACHED) {
SILC_LOG_DEBUG(("Client is detached, discarding packet"));
- return;
+ goto out;
}
/* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
packet->dst_id_len,
packet->dst_id_type);
if (!idp)
- return;
+ goto out;
error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
if (packet->src_id_type == SILC_ID_CLIENT) {
}
silc_buffer_free(idp);
- return;
+ goto out;
}
/* Check whether destination client wishes to receive private messages */
if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
- return;
+ goto out;
}
/* Send the private message */
silc_server_packet_route(server, dst_sock, packet);
+
+ out:
+ silc_packet_free(packet);
}
/* Received private message key packet.. This packet is never for us. It is to
SILC_LOG_DEBUG(("Start"));
if (packet->src_id_type != SILC_ID_CLIENT ||
- packet->dst_id_type != SILC_ID_CLIENT)
- return;
-
- if (!packet->dst_id)
+ packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
+ silc_packet_free(packet);
return;
+ }
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
packet->dst_id_len, NULL,
&idata, NULL);
- if (!dst_sock)
+ if (!dst_sock) {
+ silc_packet_free(packet);
return;
+ }
/* Relay the packet */
silc_server_packet_route(server, dst_sock, packet);
+
+ silc_packet_free(packet);
}
/* Processes incoming command reply packet. The command reply packet may
SILC_LOG_DEBUG(("Start"));
- if (packet->dst_id_type == SILC_ID_CHANNEL)
+ if (packet->dst_id_type == SILC_ID_CHANNEL) {
+ silc_packet_free(packet);
return;
+ }
if (packet->dst_id_type == SILC_ID_CLIENT) {
/* Destination must be one of ours */
if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT,
- &id, sizeof(id)))
+ &id, sizeof(id))) {
+ silc_packet_free(packet);
return;
+ }
client = silc_idlist_find_client_by_id(server->local_list, &id,
TRUE, NULL);
if (!client) {
SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
+ silc_packet_free(packet);
return;
}
}
/* For now this must be for us */
if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
+ silc_packet_free(packet);
return;
}
}
/* Relay the packet to the client */
if (packet->dst_id_type == SILC_ID_CLIENT && client)
silc_server_packet_route(server, client->connection, packet);
+
+ silc_packet_free(packet);
}
/* Process received channel message. The message can be originated from
SilcChannelID id;
SilcClientID cid;
SilcID sid;
- void *sender_id = NULL;
SilcClientEntry sender_entry = NULL;
SilcIDListData idata;
SilcChannelClientEntry chl;
/* Sanity checks */
if (packet->dst_id_type != SILC_ID_CHANNEL) {
SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
- return;
+ goto out;
}
/* Find channel entry */
if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL,
&id, sizeof(id)))
- return;
+ goto out;
channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
if (!channel) {
channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
packet->dst_id_len,
packet->dst_id_type);
if (!idp)
- return;
+ goto out;
error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
if (packet->src_id_type == SILC_ID_CLIENT) {
}
silc_buffer_free(idp);
- return;
+ goto out;
}
}
not client (as it can be server as well) we don't do the check. */
if (!silc_id_str2id2(packet->src_id, packet->src_id_len,
packet->src_id_type, &sid))
- return;
+ goto out;
if (sid.type == SILC_ID_CLIENT) {
sender_entry = silc_idlist_find_client_by_id(server->local_list,
SILC_ID_GET_ID(sid),
if (!sender_entry || !silc_server_client_on_channel(sender_entry,
channel, &chl)) {
SILC_LOG_DEBUG(("Client not on channel"));
- return;
+ goto out;
}
/* If channel is moderated check that client is allowed to send
!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
SILC_LOG_DEBUG(("Channel is silenced from normal users"));
- return;
+ goto out;
}
if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
SILC_LOG_DEBUG(("Channel is silenced from operators"));
- return;
+ goto out;
}
if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
SILC_LOG_DEBUG(("Sender is quieted on the channel"));
- return;
+ goto out;
}
/* If the packet is coming from router, but the client entry is local
if (server->server_type == SILC_ROUTER &&
idata->conn_type == SILC_CONN_ROUTER && local) {
SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
- return;
+ goto out;
}
}
/* Distribute the packet to our local clients. This will send the
packet for further routing as well, if needed. */
- silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
- packet->src_id_type, sender_entry,
- packet->buffer.data,
+ silc_server_packet_relay_to_channel(server, sock, channel,
+ SILC_ID_GET_ID(sid), sid.type,
+ sender_entry, packet->buffer.data,
silc_buffer_len(&packet->buffer));
+
+ out:
+ silc_packet_free(packet);
}
/* Received channel key packet. We distribute the key to all of our locally
if (packet->src_id_type != SILC_ID_SERVER ||
(server->server_type == SILC_ROUTER && !server->backup_router &&
- idata->conn_type == SILC_CONN_ROUTER))
+ idata->conn_type == SILC_CONN_ROUTER)) {
+ silc_packet_free(packet);
return;
+ }
/* Save the channel key */
channel = silc_server_save_channel_key(server, buffer, NULL);
if (!channel) {
SILC_LOG_ERROR(("Bad channel key from %s", idata->sconn->remote_host));
+ silc_packet_free(packet);
return;
}
we will also send it to locally connected servers. */
silc_server_send_channel_key(server, sock, channel, FALSE);
- if (server->server_type != SILC_BACKUP_ROUTER) {
+ if (server->server_type != SILC_BACKUP_ROUTER)
/* Distribute to local cell backup routers. */
silc_server_backup_send(server, (SilcServerEntry)idata,
SILC_PACKET_CHANNEL_KEY, 0,
buffer->data, silc_buffer_len(buffer),
FALSE, TRUE);
- }
+
+ silc_packet_free(packet);
}
/* Received New Client packet and processes it. Creates Client ID for the
SilcClientEntry client;
SilcClientID *client_id;
char *username = NULL, *realname = NULL;
- SilcUInt16 username_len;
+ SilcUInt16 username_len, nickname_len;
SilcUInt32 id_len, tmp_len;
int ret;
- char *host, *nickname, *nicknamec;
+ char *host, *nickname = NULL, *nicknamec;
const char *hostname, *ip;
SILC_LOG_DEBUG(("Creating new client"));
- if (idata->conn_type != SILC_CONN_CLIENT)
+ if (idata->conn_type != SILC_CONN_CLIENT) {
+ silc_packet_free(packet);
return NULL;
+ }
/* Take client entry */
client = (SilcClientEntry)idata;
- silc_socket_stream_get_info(sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
+ NULL, &hostname, &ip, NULL);
- /* Remove the old cache entry. */
- if (!silc_idcache_del_by_context(server->local_list->clients, client,
- NULL)) {
- SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
- silc_server_disconnect_remote(server, sock,
- SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
- silc_server_free_sock_user_data(server, sock, NULL);
- return NULL;
- }
+ SILC_LOG_DEBUG(("%s %s", ip, hostname));
/* Make sure this client hasn't registered already */
if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
- silc_server_disconnect_remote(server, sock,
- SILC_STATUS_ERR_OPERATION_ALLOWED,
- "Too many registrations");
- silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
return NULL;
}
/* Parse incoming packet */
ret = silc_buffer_unformat(buffer,
+ SILC_STR_ADVANCE,
SILC_STR_UI16_NSTRING_ALLOC(&username,
&username_len),
SILC_STR_UI16_STRING_ALLOC(&realname),
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
return NULL;
}
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
return NULL;
}
if (username_len > 128) {
- username[128] = '\0';
username_len = 128;
+ username[username_len - 1] = '\0';
+ }
+
+ /* Take nickname from NEW_CLIENT packet, if present */
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI16_NSTRING_ALLOC(&nickname,
+ &nickname_len),
+ SILC_STR_END) >= 0) {
+ if (nickname_len > 128) {
+ nickname_len = 128;
+ nickname[nickname_len - 1] = '\0';
+ }
+ }
+
+ /* Nickname is initially same as username, if not present in NEW_CLIENT */
+ if (!nickname) {
+ nickname = strdup(username);
+ nickname_len = strlen(nickname);
}
/* Check for valid username string */
- nicknamec = silc_identifier_check(username, username_len,
+ nicknamec = silc_identifier_check(nickname, nickname_len,
SILC_STRING_UTF8, 128, &tmp_len);
if (!nicknamec) {
silc_free(username);
silc_free(realname);
+ silc_free(nickname);
SILC_LOG_ERROR(("Client %s (%s) sent bad username string '%s', closing "
"connection", hostname, ip, username));
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
return NULL;
}
- /* Nickname is initially same as username */
- nickname = strdup(username);
-
/* Make sanity checks for the hostname of the client. If the hostname
is provided in the `username' check that it is the same than the
resolved hostname, or if not resolved the hostname that appears in
host = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
if (strcmp(hostname, ip) && strcmp(hostname, host)) {
+ silc_free(nickname);
silc_free(username);
silc_free(host);
silc_free(realname);
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
return NULL;
}
client->data.public_key);
phostname = strdup(silc_pubkey->identifier.host);
if (!strcmp(hostname, ip) && phostname && strcmp(phostname, host)) {
+ silc_free(nickname);
silc_free(username);
silc_free(host);
silc_free(phostname);
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
return NULL;
}
username = newusername;
}
+ SILC_LOG_DEBUG(("%s %s", ip, hostname));
+
/* Create Client ID */
if (!silc_id_create_client_id(server, server->id, server->rng,
server->md5hash, nicknamec,
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_BAD_NICKNAME, NULL);
silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
return NULL;
}
client->userinfo = realname ? realname : strdup(username);
client->id = client_id;
id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
-
- /* Add the client again to the ID cache */
- silc_idcache_add(server->local_list->clients, nicknamec,
- client_id, client);
+ silc_idcache_update_by_context(server->local_list->clients, client,
+ client_id, nicknamec, TRUE);
/* Notify our router about new client on the SILC network */
silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
if (server->server_type == SILC_ROUTER)
silc_server_check_watcher_list(server, client, NULL, 0);
+ silc_packet_free(packet);
return client;
}
SILC_LOG_DEBUG(("Creating new server"));
if (idata->conn_type != SILC_CONN_SERVER &&
- idata->conn_type != SILC_CONN_ROUTER)
+ idata->conn_type != SILC_CONN_ROUTER) {
+ silc_packet_free(packet);
return NULL;
+ }
/* Take server entry */
new_server = (SilcServerEntry)idata;
- silc_socket_stream_get_info(sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
+ NULL, &hostname, &ip, NULL);
/* Statistics */
if (server->server_type == SILC_ROUTER)
id_type = silc_id_payload_get_type(idp);
- silc_socket_stream_get_info(sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
+ NULL, &hostname, &ip, NULL);
/* Normal server cannot have other normal server connections */
server_entry = (SilcServerEntry)idata;
global list. Cell wide information however is kept in the local
list. */
entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
- &id, router, NULL);
+ silc_id_dup(&id, SILC_ID_CLIENT),
+ router, NULL);
if (!entry) {
SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
silc_server_check_watcher_list(server, entry, NULL, 0);
if (server->server_type == SILC_ROUTER) {
- /* Add the client's public key to hash table or get the key with
+ /* Add the client's public key to repository or get the key with
GETKEY command. */
if (entry->data.public_key) {
- if (!silc_hash_table_find_by_context(server->pk_hash,
- entry->data.public_key,
- entry, NULL))
- silc_hash_table_add(server->pk_hash, entry->data.public_key,
- entry);
- } else
+ if (!silc_server_get_public_key_by_client(server, entry, NULL))
+ silc_skr_add_public_key_simple(server->repository,
+ entry->data.public_key,
+ SILC_SKR_USAGE_IDENTIFICATION,
+ entry, NULL);
+ } else {
silc_server_send_command(server, router_sock,
SILC_COMMAND_GETKEY, ++server->cmd_ident,
1, 1, buffer->data,
silc_buffer_len(buffer));
+ }
}
}
break;
/* As a router we keep information of all global information in our
global list. Cell wide information however is kept in the local
list. */
- entry = silc_idlist_add_server(id_list, NULL, 0, &id, router,
+ entry = silc_idlist_add_server(id_list, NULL, 0,
+ silc_id_dup(&id, SILC_ID_SERVER), router,
router_sock);
if (!entry) {
SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
SilcPacket packet)
{
silc_server_new_id_real(server, sock, packet, &packet->buffer, TRUE);
+ silc_packet_free(packet);
}
/* Receoved New Id List packet, list of New ID payloads inside one
SILC_LOG_DEBUG(("Processing New ID List"));
if (idata->conn_type == SILC_CONN_CLIENT ||
- packet->src_id_type != SILC_ID_SERVER)
+ packet->src_id_type != SILC_ID_SERVER) {
+ silc_packet_free(packet);
return;
+ }
/* If the sender of this packet is server and we are router we need to
broadcast this packet to other routers in the network. Broadcast
}
idp = silc_buffer_alloc(256);
- if (!idp)
+ if (!idp) {
+ silc_packet_free(packet);
return;
+ }
while (silc_buffer_len(&packet->buffer)) {
SILC_GET16_MSB(id_len, packet->buffer.data + 2);
}
silc_buffer_free(idp);
+ silc_packet_free(packet);
}
/* Received New Channel packet. Information about new channels in the
}
/* Create the channel with the provided Channel ID */
- channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
- channel_name,
- &channel_id, FALSE);
+ channel =
+ silc_server_create_new_channel_with_id(
+ server, NULL, NULL,
+ channel_name,
+ silc_id_dup(&channel_id, SILC_ID_CHANNEL),
+ FALSE);
if (!channel) {
silc_channel_payload_free(payload);
return;
SilcPacket packet)
{
silc_server_new_channel_process(server, sock, packet, &packet->buffer);
+ silc_packet_free(packet);
}
/* Received New Channel List packet, list of New Channel List payloads inside
if (idata->conn_type == SILC_CONN_CLIENT ||
packet->src_id_type != SILC_ID_SERVER ||
- server->server_type == SILC_SERVER)
+ server->server_type == SILC_SERVER) {
+ silc_packet_free(packet);
return;
+ }
buffer = silc_buffer_alloc(512);
- if (!buffer)
+ if (!buffer) {
+ silc_packet_free(packet);
return;
+ }
while (silc_buffer_len(&packet->buffer)) {
SILC_GET16_MSB(len1, packet->buffer.data);
}
silc_buffer_free(buffer);
+ silc_packet_free(packet);
}
/* Received key agreement packet. This packet is never for us. It is to
SILC_LOG_DEBUG(("Start"));
if (packet->src_id_type != SILC_ID_CLIENT ||
- packet->dst_id_type != SILC_ID_CLIENT)
- return;
-
- if (!packet->dst_id)
+ packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
+ silc_packet_free(packet);
return;
+ }
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
packet->dst_id_len, NULL,
&idata, NULL);
- if (!dst_sock)
+ if (!dst_sock) {
+ silc_packet_free(packet);
return;
+ }
/* Relay the packet */
silc_server_packet_route(server, dst_sock, packet);
+ silc_packet_free(packet);
}
/* Received connection auth request packet that is used during connection
if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
SILC_LOG_DEBUG(("Request not from client"));
+ silc_packet_free(packet);
return;
}
- silc_socket_stream_get_info(sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
+ NULL, &hostname, &ip, NULL);
/* Parse the payload */
ret = silc_buffer_unformat(&packet->buffer,
SILC_STR_UI_SHORT(&conn_type),
SILC_STR_UI_SHORT(NULL),
SILC_STR_END);
- if (ret == -1)
- return;
-
- if (conn_type != SILC_CONN_CLIENT)
+ if (ret == -1 || conn_type != SILC_CONN_CLIENT) {
+ silc_packet_free(packet);
return;
+ }
/* Get the authentication method for the client */
auth_meth = SILC_AUTH_NONE;
/* Send it back to the client */
silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
+ silc_packet_free(packet);
}
/* Received file transger packet. This packet is never for us. It is to
SILC_LOG_DEBUG(("Start"));
if (packet->src_id_type != SILC_ID_CLIENT ||
- packet->dst_id_type != SILC_ID_CLIENT)
- return;
-
- if (!packet->dst_id)
+ packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
+ silc_packet_free(packet);
return;
+ }
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
packet->dst_id_len, NULL,
&idata, NULL);
- if (!dst_sock)
+ if (!dst_sock) {
+ silc_packet_free(packet);
return;
+ }
/* Relay the packet */
silc_server_packet_route(server, dst_sock, packet);
+ silc_packet_free(packet);
}
typedef struct {
SILC_LOG_DEBUG(("Start"));
- silc_socket_stream_get_info(sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
+ NULL, &hostname, &ip, NULL);
if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
SilcHashTableList htl;
SilcChannelClientEntry chl;
SilcServerResumeResolve r;
+ SilcPublicKey public_key;
const char *cipher, *hostname, *ip;
- silc_socket_stream_get_info(sock, NULL, &hostname, &ip, NULL);
+ SILC_LOG_DEBUG(("Resuming client"));
+
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
+ NULL, &hostname, &ip, NULL);
if (silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING(&id_string, &id_len),
silc_packet_set_context(sock, detached_client);
detached_client->connection = sock;
- if (detached_client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- detached_client->data.public_key,
- detached_client);
- if (idata->public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- idata->public_key, idata);
+ if (detached_client->data.public_key) {
+ /* Delete the detached client's public key from repository */
+ silc_skr_del_public_key(server->repository,
+ detached_client->data.public_key,
+ detached_client);
+ detached_client->data.public_key = NULL;
+ }
+
+ if (idata->public_key) {
+ /* Delete the resuming client's public key from repository. It will
+ be added later again. */
+ public_key = silc_pkcs_public_key_copy(idata->public_key);
+ silc_skr_del_public_key(server->repository, idata->public_key, idata);
+ idata->public_key = public_key;
+ }
/* Take new keys and stuff into use in the old entry */
silc_idlist_del_data(detached_client);
silc_idlist_add_data(detached_client, idata);
+ idata->public_key = NULL;
- if (detached_client->data.public_key)
- silc_hash_table_add(server->pk_hash,
- detached_client->data.public_key, detached_client);
+ if (detached_client->data.public_key) {
+ /* Add the resumed client's public key back to repository. */
+ if (!silc_server_get_public_key_by_client(server, detached_client, NULL))
+ silc_skr_add_public_key_simple(server->repository,
+ detached_client->data.public_key,
+ SILC_SKR_USAGE_IDENTIFICATION,
+ detached_client, NULL);
+ }
detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
detached_client->mode &= ~SILC_UMODE_DETACHED;
server->stat.my_detached--;
+ silc_dlist_del(server->expired_clients, detached_client);
/* We are finished - reset resuming client */
detached_client->resuming_client = NULL;
silc_server_check_watcher_list(server, detached_client, NULL,
SILC_NOTIFY_TYPE_UMODE_CHANGE);
- /* Delete this current client entry since we're resuming to old one. */
- server->stat.my_clients--;
+ /* Delete this current client entry since we're resuming to old one.
+ We decrement clients/cell_clients as we are getting rid of the
+ current client and replacing it with the detached one. We keep the
+ server user count as-is (incremented by the current client entry) as
+ we decremented the count already during detach, thus we'd be undoing
+ that operation. */
+ SILC_VERIFY(server->stat.clients > 0);
server->stat.clients--;
if (server->stat.cell_clients)
server->stat.cell_clients--;
silc_server_remove_from_channels(server, NULL, client, FALSE,
NULL, FALSE, FALSE);
silc_server_del_from_watcher_list(server, client);
+ silc_dlist_del(server->expired_clients, client);
if (!silc_idlist_del_client(server->local_list, client))
silc_idlist_del_client(server->global_list, client);
client = detached_client;
silc_buffer_free(nidp);
}
- /* Add the client again to the ID cache to get it to correct list */
- if (!silc_idcache_del_by_context(server->local_list->clients, client,
- NULL))
- silc_idcache_del_by_context(server->global_list->clients, client, NULL);
- silc_free(client->id);
- *client->id = client_id;
- silc_idcache_add(server->local_list->clients, nicknamec,
- client->id, client);
+ /* Update entry */
+ if (!silc_idcache_update_by_context(server->local_list->clients, client,
+ &client_id, NULL, FALSE))
+ silc_idcache_update_by_context(server->global_list->clients, client,
+ &client_id, NULL, FALSE);
+
+ /* Move entry to local list if it is in global list */
+ if (silc_idcache_find_by_context(server->global_list->clients, client,
+ &id_cache))
+ silc_idcache_move(server->global_list->clients,
+ server->local_list->clients, id_cache);
/* Send some nice info to the client */
silc_server_send_connect_notifys(server, sock, client);
/* Client is detached, and now it is resumed. Remove the detached
mode and mark that it is resumed. */
- if (detached_client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- detached_client->data.public_key,
- detached_client);
+ if (detached_client->data.public_key) {
+ /* Delete the detached client's public key from repository */
+ silc_skr_del_public_key(server->repository,
+ detached_client->data.public_key,
+ detached_client);
+ detached_client->data.public_key = NULL;
+ }
silc_idlist_del_data(detached_client);
detached_client->mode &= ~SILC_UMODE_DETACHED;
detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
+ silc_dlist_del(server->expired_clients, detached_client);
/* Check if anyone is watching this client */
if (server->server_type == SILC_ROUTER)
server_entry->server_type == SILC_ROUTER)
local = FALSE;
- /* Change the client to correct list. */
- if (!silc_idcache_del_by_context(server->local_list->clients,
- detached_client, NULL))
- silc_idcache_del_by_context(server->global_list->clients,
- detached_client, NULL);
- silc_idcache_add(local && server->server_type == SILC_ROUTER ?
- server->local_list->clients :
- server->global_list->clients, nicknamec,
- detached_client->id, detached_client);
+ /* Move entry to correct list */
+ if (local && server->server_type == SILC_ROUTER) {
+ if (silc_idcache_find_by_context(server->global_list->clients,
+ detached_client, &id_cache))
+ silc_idcache_move(server->global_list->clients,
+ server->local_list->clients, id_cache);
+ } else {
+ if (silc_idcache_find_by_context(server->local_list->clients,
+ detached_client, &id_cache))
+ silc_idcache_move(server->local_list->clients,
+ server->global_list->clients, id_cache);
+ }
/* Change the owner of the client */
detached_client->router = server_entry;