conn->remote_host = strdup(hostname);
conn->remote_port = port;
conn->context = context;
+ conn->pending_commands = silc_dlist_init();
/* Add the connection to connections table */
for (i = 0; i < client->conns_count; i++)
for (i = 0; i < client->conns_count; i++)
if (client->conns[i] == conn) {
+ if (conn->pending_commands)
+ silc_dlist_uninit(conn->pending_commands);
silc_free(conn);
client->conns[i] = NULL;
}
memset(conn->hmac_key, 0, conn->hmac_key_len);
silc_free(conn->hmac_key);
}
+ if (conn->pending_commands)
+ silc_dlist_uninit(conn->pending_commands);
conn->sock = NULL;
conn->remote_port = 0;
conn->local_id_data = NULL;
conn->remote_host = NULL;
conn->current_channel = NULL;
+ conn->pending_commands = NULL;
silc_client_del_connection(client, conn);
}
SilcNotifyPayload payload;
SilcNotifyType type;
SilcArgumentPayload args;
- int i;
SilcClientID *client_id = NULL;
SilcChannelID *channel_id = NULL;
SilcPacketContext *p = silc_packet_context_dup(packet);
p->context = (void *)client;
p->sock = sock;
- silc_client_command_pending(SILC_COMMAND_WHOIS,
+ silc_client_command_pending(conn,SILC_COMMAND_WHOIS, 0,
silc_client_notify_by_server_pending, p);
goto out;
}
SilcPacketContext *p = silc_packet_context_dup(packet);
p->context = (void *)client;
p->sock = sock;
- silc_client_command_pending(SILC_COMMAND_WHOIS,
+ silc_client_command_pending(conn, SILC_COMMAND_WHOIS, 0,
silc_client_notify_by_server_pending, p);
goto out;
}
SilcPacketContext *p = silc_packet_context_dup(packet);
p->context = (void *)client;
p->sock = sock;
- silc_client_command_pending(SILC_COMMAND_WHOIS,
+ silc_client_command_pending(conn, SILC_COMMAND_WHOIS, 0,
silc_client_notify_by_server_pending, p);
goto out;
}
(void *)channel->id, (void *)channel, TRUE);
}
-/* Processes received key for channel. The received key will be used
- to protect the traffic on the channel for now on. Client must receive
- the key to the channel before talking on the channel is possible.
- This is the key that server has generated, this is not the channel
- private key, it is entirely local setting. */
+/* Saves channel key from encoded `key_payload'. This is used when we
+ receive Channel Key Payload and when we are processing JOIN command
+ reply. */
-void silc_client_receive_channel_key(SilcClient client,
- SilcSocketConnection sock,
- SilcBuffer packet)
+void silc_client_save_channel_key(SilcClientConnection conn,
+ SilcBuffer key_payload,
+ SilcChannelEntry channel)
{
unsigned char *id_string, *key, *cipher;
unsigned int tmp_len;
- SilcClientConnection conn = (SilcClientConnection)sock->user_data;
SilcChannelID *id;
SilcIDCacheEntry id_cache = NULL;
- SilcChannelEntry channel;
SilcChannelKeyPayload payload;
- SILC_LOG_DEBUG(("Received key for channel"));
-
- payload = silc_channel_key_payload_parse(packet);
+ payload = silc_channel_key_payload_parse(key_payload);
if (!payload)
return;
silc_channel_key_payload_free(payload);
return;
}
- id = silc_id_payload_parse_id(id_string, tmp_len);
+
+ id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
/* Find channel. */
- if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
- SILC_ID_CHANNEL, &id_cache))
- goto out;
+ if (!channel) {
+ if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
+ SILC_ID_CHANNEL, &id_cache))
+ goto out;
+ /* Get channel entry */
+ channel = (SilcChannelEntry)id_cache->context;
+ }
+
/* Save the key */
key = silc_channel_key_get_key(payload, &tmp_len);
cipher = silc_channel_key_get_cipher(payload, NULL);
-
- channel = (SilcChannelEntry)id_cache->context;
channel->key_len = tmp_len;
channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
memcpy(channel->key, key, tmp_len);
if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
- client->ops->say(client, conn,
+ conn->client->ops->say(conn->client, conn,
"Cannot talk to channel: unsupported cipher %s", cipher);
goto out;
}
silc_channel_key_payload_free(payload);
}
+/* Processes received key for channel. The received key will be used
+ to protect the traffic on the channel for now on. Client must receive
+ the key to the channel before talking on the channel is possible.
+ This is the key that server has generated, this is not the channel
+ private key, it is entirely local setting. */
+
+void silc_client_receive_channel_key(SilcClient client,
+ SilcSocketConnection sock,
+ SilcBuffer packet)
+{
+ SILC_LOG_DEBUG(("Received key for channel"));
+
+ /* Save the key */
+ silc_client_save_channel_key(sock->user_data, packet, NULL);
+}
+
/* Process received message to a channel (or from a channel, really). This
decrypts the channel message with channel specific key and parses the
channel payload. Finally it displays the message on the screen. */
SilcChannelUser chu;
SilcIDCacheEntry id_cache = NULL;
SilcClientID *client_id = NULL;
- int i;
char *nickname;
/* Sanity checks */
SilcIDCacheList list;
SilcChannelEntry channel;
SilcChannelUser chu;
- int i;
if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
SILC_ID_CHANNEL, &list))
SilcIDCacheList list;
SilcChannelEntry channel;
SilcChannelUser chu;
- int i;
if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
SILC_ID_CHANNEL, &list))