and would not work with many channels. Affected file is
silcd/server.c.
+ * Fixed some memory leaks around the server code.
+
Fri Jul 6 18:26:31 EEST 2001 Pekka Riikonen <priikone@silcnet.org>
* Changed the dynamic tables to static size tables in the
o Incomplete IPv6 support:
- o silc_server_get_users_on_channel does not support IPv6 based
- Client ID's.
- o silc_server_route_get and the route code in general supports
- only IPv4.
o silcd/serverid.c and its routines supports only IPv4.
o DNS/IP lookup blocks the server. This must be fixed. Check the
TODO In SILC Protocol
=====================
- o pp-03 draft:
-
- o Add SILC_MESSAGE_FLAG_SIGNED flag that indicates that the
- messages is signed with the senders private key and thus can
- be verified with its public key. This is especially handy
- feature when sending privat messages without having negotiated
- private keys, thus the servers decrypts and re-ecnrypts the
- messages. Other applications exists as well.
-
o If channel founder mode is set and the invite mode is set on channel
then the founder should be added to the list automatically so that
if the founder signoff's it will be able join again to the invite only
/* Check invite list if channel is invite-only channel */
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
channel->mode & SILC_CHANNEL_MODE_INVITE) {
- if (!channel->invite_list) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_NOT_INVITED);
- goto out;
- }
-
- if (!silc_string_match(channel->invite_list, check)) {
+ if (!channel->invite_list ||
+ !silc_string_match(channel->invite_list, check)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_NOT_INVITED);
goto out;
SilcBuffer buffer = packet->buffer;
/* Re-encrypt and send if private messge key does not exist */
- if ((packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) == FALSE) {
+ if (!(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY)) {
silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ packet->dst_id_len + packet->padlen);
broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
+ va_end(ap);
}
/* Sends notify message and gets the arguments from the `args' Argument
dest_id, dest_id_type,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
+ va_end(ap);
}
/* Sends notify message to a channel. The notify message sent is
SILC_PACKET_NOTIFY, route_notify,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
+ va_end(ap);
}
/* Send notify message to all channels the client has joined. It is quaranteed
if (sent_clients_count)
silc_free(sent_clients);
silc_free(packetdata.src_id);
+ va_end(ap);
}
/* Sends New ID Payload to remote end. The packet is used to distribute
silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
packet->data, packet->len, TRUE);
silc_buffer_free(packet);
+ va_end(ap);
}
/* Send the heartbeat packet. */
silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
{
va_list ap;
+ SilcBuffer p;
va_start(ap, argc);
- return silc_notify_payload_encode(notify, argc, ap);
+ p = silc_notify_payload_encode(notify, argc, ap);
+ va_end(ap);
+
+ return p;
}
/* Returns assembled packets for channel users of the `channel'. */
SilcBuffer client_id_list;
SilcBuffer client_mode_list;
SilcBuffer idp;
- uint32 list_count = 0;
+ uint32 list_count = 0, len = 0;
- /* XXX rewrite - this does not support IPv6 based Client ID's. */
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl))
+ len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
- client_id_list =
- silc_buffer_alloc((SILC_ID_CLIENT_LEN + 4) *
- silc_hash_table_count(channel->user_list));
+ client_id_list = silc_buffer_alloc(len);
client_mode_list =
silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
+
silc_hash_table_list(channel->user_list, &htl);
while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
/* Client ID */
if (client) {
silc_free(id);
- if (client && client->data.registered == FALSE)
+ if (client->data.registered == FALSE)
return NULL;
/* If we are router and the client has router then the client is in
our cell but not directly connected to us. */
if (server->server_type == SILC_ROUTER && client->router) {
- /* We are of course in this case the client's router thus the real
- "router" of the client is the server who owns the client. Thus
- we will send the packet to that server. */
+ /* We are of course in this case the client's router thus the route
+ to the client is the server who owns the client. So, we will send
+ the packet to that server. */
if (idata)
*idata = (SilcIDListData)client->router;
return client->router->connection;
0x0010 SILC_MESSAGE_FLAG_REQUEST
This is a generic request flag to send request
- messages.
+ messages. A separate document should define any
+ payloads associated to this flag.
- 0x0020 - 0x0200 RESERVED
+ 0x0020 SILC_MESSAGE_FLAG_SIGNED
+
+ This flag indicates that the message is signed
+ with sender's private key and thus can be verified
+ by the receiver using the sender's public key. A
+ separate document should define the detailed procedure
+ of the signing process and any associated payloads
+ of this flag.
+
+ 0x0040 - 0x0200 RESERVED
Reserved for future flags
#define SILC_MESSAGE_FLAG_ACTION 0x0004
#define SILC_MESSAGE_FLAG_NOTICE 0x0008
#define SILC_MESSAGE_FLAG_REQUEST 0x0010
-#define SILC_MESSAGE_FLAG_RESERVED 0x0020 /* to 0x0200 */
+#define SILC_MESSAGE_FLAG_SIGNED 0x0020
+#define SILC_MESSAGE_FLAG_RESERVED 0x0040 /* to 0x0200 */
#define SILC_MESSAGE_FLAG_PRIVATE 0x0400 /* to 0x8000 */
/***/
silc_free(argv_lens);
silc_free(argv_types);
+ va_end(ap);
+
return buffer;
}
silc_free(argv_lens);
silc_free(argv_types);
+ va_end(ap);
+
return buffer;
}
#define SILC_HASH_TABLE_SIZE 3
/* Produce the index by hashing the key */
-#define SILC_HASH_TABLE_HASH_F(f, c) \
+#define SILC_HASH_TABLE_HASH(f, c) \
((f)(key, (c)) % primesize[ht->table_size])
/* Check whether need to rehash */
void *compare_user_context)
{
SilcHashTableEntry *entry, prev = NULL;
- uint32 i = SILC_HASH_TABLE_HASH_F(hash, hash_user_context);
+ uint32 i = SILC_HASH_TABLE_HASH(hash, hash_user_context);
SILC_HT_DEBUG(("index %d key %p", i, key));
void *compare_user_context)
{
SilcHashTableEntry *entry, prev = NULL;
- uint32 i = SILC_HASH_TABLE_HASH_F(hash, hash_user_context);
+ uint32 i = SILC_HASH_TABLE_HASH(hash, hash_user_context);
SILC_HT_DEBUG(("index %d key %p context %p", i, key, context));
void *compare_user_context)
{
SilcHashTableEntry *entry;
- uint32 i = SILC_HASH_TABLE_HASH_F(hash, hash_user_context);
+ uint32 i = SILC_HASH_TABLE_HASH(hash, hash_user_context);
SILC_HT_DEBUG(("index %d key %p", i, key));
void *foreach_user_context)
{
SilcHashTableEntry *entry;
- uint32 i = SILC_HASH_TABLE_HASH_F(hash, hash_user_context);
+ uint32 i = SILC_HASH_TABLE_HASH(hash, hash_user_context);
SILC_HT_DEBUG(("index %d key %p", i, key));
void *hash_user_context)
{
SilcHashTableEntry *entry;
- uint32 i = SILC_HASH_TABLE_HASH_F(hash, hash_user_context);
+ uint32 i = SILC_HASH_TABLE_HASH(hash, hash_user_context);
SILC_HT_DEBUG(("index %d key %p", i, key));
void *hash_user_context)
{
SilcHashTableEntry *entry;
- uint32 i = SILC_HASH_TABLE_HASH_F(hash, hash_user_context);
+ uint32 i = SILC_HASH_TABLE_HASH(hash, hash_user_context);
SILC_HT_DEBUG(("index %d key %p", i, key));
(*entry)->key = key;
(*entry)->context = context;
+
+ if (SILC_HASH_REHASH_INC)
+ silc_hash_table_rehash(ht, 0);
}
/* Allocates new hash table and returns it. If the `table_size' is not