JOIN command replys.
+Tue Feb 24 16:49:10 EET 2004 Pekka Riikonen <priikone@silcnet.org>
+
+ * Implemented the user limit to the CMODE_CHANGE notify,
+ CMODE command reply and JOIN command reply in server.
+ Affected files are silcd/server.c, command.c, command_reply.c,
+ packet_send.c and packet_receive.c.
+
Mon Feb 23 23:31:15 EET 2004 Pekka Riikonen <priikone@silcnet.org>
* Defined SILC_STRFMT_END that must be used now with
o stringprep (RFC3454) for UTF-8 strings + all other UTF-8 string things.
- o <user limit> to CMODE_CHANGE notify, and JOIN and CMODE command
- replies.
-
o Check that founder key is distributed ok during backup resuming.
o Testing
SilcSocketConnection sock = cmd->sock;
unsigned char *tmp;
SilcUInt32 tmp_len, user_count;
- unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4];
+ unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4], ulimit[4];
SilcClientEntry client;
SilcChannelClientEntry chl;
SilcBuffer reply, chidp, clidp, keyp = NULL;
SILC_PUT32_MSB(channel->mode, mode);
SILC_PUT32_MSB(created, tmp2);
SILC_PUT32_MSB(user_count, tmp3);
+ if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
+ SILC_PUT32_MSB(channel->user_limit, ulimit);
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
reply =
silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
- SILC_STATUS_OK, 0, ident, 15,
+ SILC_STATUS_OK, 0, ident, 16,
2, channel->channel_name,
strlen(channel->channel_name),
3, chidp->data, chidp->len,
15, fkey ? fkey->data : NULL,
fkey ? fkey->len : 0,
16, chpklist ? chpklist->data : NULL,
- chpklist ? chpklist->len : 0);
+ chpklist ? chpklist->len : 0,
+ 17, (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ ulimit : NULL),
+ (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ sizeof(ulimit) : 0));
/* Send command reply */
silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
SilcChannelClientEntry chl;
SilcBuffer packet, cidp;
unsigned char *tmp, *tmp_id, *tmp_mask, *chpkdata = NULL;
- char *cipher = NULL, *hmac = NULL, *passphrase = NULL;
+ char *cipher = NULL, *hmac = NULL, *passphrase = NULL, ulimit[4];
SilcUInt32 mode_mask = 0, old_mask = 0, tmp_len, tmp_len2, chpklen;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
bool set_mask = FALSE, set_chpk = FALSE;
/* Send CMODE_CHANGE notify. */
cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+ if (mode_mask & SILC_CHANNEL_MODE_ULIMIT)
+ SILC_PUT32_MSB(channel->user_limit, ulimit);
silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
- SILC_NOTIFY_TYPE_CMODE_CHANGE, 7,
+ SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
cidp->data, cidp->len,
tmp_mask, 4,
cipher, cipher ? strlen(cipher) : 0,
fkey ? fkey->data : NULL,
fkey ? fkey->len : 0,
chpkdata ? chpkdata : NULL,
- chpkdata ? chpklen : 0);
+ chpkdata ? chpklen : 0,
+ mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
+ ulimit : NULL,
+ mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
+ sizeof(ulimit) : 0);
/* Set CMODE notify type to network */
if (chpkdata && chpklen)
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
- SILC_STATUS_OK, 0, ident, 4,
+ SILC_STATUS_OK, 0, ident, 5,
2, tmp_id, tmp_len2,
3, tmp_mask, 4,
4, fkey ? fkey->data : NULL,
fkey ? fkey->len : 0,
5, chpklist ? chpklist->data :
NULL, chpklist ? chpklist->len
- : 0);
+ : 0,
+ 7, (mode_mask &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ ulimit : NULL),
+ (mode_mask &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ sizeof(ulimit) : 0));
+
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
if (tmp && server->server_type == SILC_SERVER)
silc_server_set_channel_pk_list(server, NULL, entry, tmp, len);
+ /* The the user limit */
+ tmp = silc_argument_get_arg_type(cmd->args, 17, &len);
+ if (tmp && len == 4)
+ SILC_GET32_MSB(entry->user_limit, tmp);
+
/* If channel was not created we know there is global users on the
channel. */
entry->global_users = (created == 0 ? TRUE : FALSE);
mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
SilcBuffer chpklist;
SilcBuffer sidp;
- unsigned char mask[4];
+ unsigned char mask[4], ulimit[4];
SILC_LOG_DEBUG(("Channel public key list received from router"));
tmp = silc_argument_get_arg_type(args, 7, &tmp_len);
break;
sidp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
SILC_PUT32_MSB(channel->mode, mask);
+ if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
+ SILC_PUT32_MSB(channel->user_limit, ulimit);
silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
- SILC_NOTIFY_TYPE_CMODE_CHANGE, 7,
+ SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
sidp->data, sidp->len,
mask, 4,
channel->cipher,
channel->passphrase ?
strlen(channel->passphrase) : 0,
NULL, 0,
- chpklist->data, chpklist->len);
+ chpklist->data, chpklist->len,
+ (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ ulimit : NULL),
+ (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ sizeof(ulimit) : 0));
silc_buffer_free(sidp);
silc_buffer_free(chpklist);
goto out;
}
}
+ /* Get the user limit */
+ tmp = silc_argument_get_arg_type(args, 8, &tmp_len);
+ if (tmp && tmp_len == 4 && mode & SILC_CHANNEL_MODE_ULIMIT)
+ SILC_GET32_MSB(channel->user_limit, tmp);
+
/* Send the same notify to the channel */
silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
FALSE, TRUE, packet->buffer->data,
SilcBuffer channel_pubkeys)
{
SilcBuffer idp, fkey = NULL;
- unsigned char mode[4];
+ unsigned char mode[4], ulimit[4];
idp = silc_id_payload_encode((void *)id, id_type);
SILC_PUT32_MSB(mode_mask, mode);
if (founder_key)
fkey = silc_pkcs_public_key_payload_encode(founder_key);
+ if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
+ SILC_PUT32_MSB(channel->user_limit, ulimit);
silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
- 7, idp->data, idp->len,
+ 8, idp->data, idp->len,
mode, 4,
cipher, cipher ? strlen(cipher) : 0,
hmac, hmac ? strlen(hmac) : 0,
strlen(passphrase) : 0,
fkey ? fkey->data : NULL, fkey ? fkey->len : 0,
channel_pubkeys ? channel_pubkeys->data : NULL,
- channel_pubkeys ? channel_pubkeys->len : 0);
+ channel_pubkeys ? channel_pubkeys->len : 0,
+ mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
+ ulimit : NULL,
+ mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
+ sizeof(ulimit) : 0);
silc_buffer_free(fkey);
silc_buffer_free(idp);
}
silc_schedule_task_del_by_fd(server->schedule, sock);
silc_schedule_unset_listen_fd(server->schedule, sock);
- if (silc_net_get_socket_opt(sock, SOL_SOCKET, SO_ERROR, &opt, &optlen) ||
+ if (silc_net_get_socket_opt(sock, SOL_SOCKET, SO_ERROR, &opt, &optlen) ||
(opt != 0)) {
SILC_LOG_ERROR(("Could not connect to router %s:%d: %s",
sconn->remote_host, sconn->remote_port,
SilcBuffer chidp, clidp, csidp;
SilcBuffer tmp, fkey = NULL, chpklist;
int len;
- unsigned char mode[4];
+ unsigned char mode[4], ulimit[4];
char *hmac;
SILC_LOG_DEBUG(("Start"));
/* CMODE notify */
SILC_PUT32_MSB(channel->mode, mode);
+ if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
+ SILC_PUT32_MSB(channel->user_limit, ulimit);
hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
if (channel->founder_key)
fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
tmp =
silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
- 7, csidp->data, csidp->len,
+ 8, csidp->data, csidp->len,
mode, sizeof(mode),
NULL, 0,
hmac, hmac ? strlen(hmac) : 0,
fkey ? fkey->data : NULL,
fkey ? fkey->len : 0,
chpklist ? chpklist->data : NULL,
- chpklist ? chpklist->len : 0);
+ chpklist ? chpklist->len : 0,
+ (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ ulimit : NULL),
+ (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ sizeof(ulimit) : 0));
len = tmp->len;
*channel_modes =
silc_buffer_realloc(*channel_modes,
if (chpk && type == 0x03 && channel->channel_pubkeys &&
server->server_type != SILC_ROUTER) {
SilcBuffer sidp;
- unsigned char mask[4];
+ unsigned char mask[4], ulimit[4];
SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
silc_hash_table_free(channel->channel_pubkeys);
/* Send notify that removes the old list */
sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
+ if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
+ SILC_PUT32_MSB(channel->user_limit, ulimit);
silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
- SILC_NOTIFY_TYPE_CMODE_CHANGE, 7,
+ SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
sidp->data, sidp->len,
mask, 4,
channel->cipher,
channel->passphrase,
channel->passphrase ?
strlen(channel->passphrase) : 0,
- NULL, 0, NULL, 0);
+ NULL, 0, NULL, 0,
+ (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ ulimit : NULL),
+ (channel->mode &
+ SILC_CHANNEL_MODE_ULIMIT ?
+ sizeof(ulimit) : 0));
silc_buffer_free(sidp);
}