better debugging. For rest see CHANGES.
+Wed Jun 19 17:46:31 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+ * Save the channel passphrase when received succesful JOIN
+ command reply from router, on normal server. Otherwise
+ joinig +a channels from normal server is not possible.
+ Affected file silcd/command.c.
+
+ * Fixed a bug in TOPIC_SET notify handling. The notifier
+ may be other than client too, like server or channel.
+ It expected it to always be only client and ignored the
+ notify. Affected file silcd/packet_recieve.c.
+
+ * Removed some (unnecessary) debug printing from
+ lib/silccore/silcid.c and lib/silccore/silcargument.c.
+
+ * Do not force CMODE_CHANGE when server is announcing new
+ channel.
+
+ Router announces stuff only after server reannounces channel
+ after CHANNEL_CHANGE notify.
+
+ These fixes optimizes the announcing procedure, and perhaps
+ fixes some problems too. Affected file silcd/packet_receive.c.
+
+ * Fixed SERVER_SIGNOFF sending to local clients. It was
+ totally broken and sent the notify to all local clients,
+ instead of only to those that was on same channel as the
+ signing off clients. Affected file silcd/server_util.c.
+
+ * Added -D option to server. It can be used to give debug
+ level. The levels are from 0 - 99, and are predefined for
+ smooth server debugging. (see silcd.c for the predefined
+ levels). Affected file silcd/server.c.
+
Wed Jun 19 16:01:51 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
* Fixed a bug in Irssi SILC client to close the connection
SILC_GET32_MSB(created, tmp);
if (silc_argument_get_arg_type(reply->args, 7, NULL))
create_key = FALSE; /* Router returned the key already */
+
+ if (silc_command_get_status(reply->payload, NULL, NULL) &&
+ channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
+ /* Save channel passphrase, if user provided it successfully */
+ unsigned char *pa;
+ SilcUInt32 pa_len;
+ pa = silc_argument_get_arg_type(reply->args, 3, &pa_len);
+ if (pa) {
+ silc_free(channel->passphrase);
+ channel->passphrase = silc_memdup(pa, pa_len);
+ }
+ }
}
if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
goto out;
- client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
+ client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
if (!client_id)
goto out;
/* Get client entry */
- client = silc_idlist_find_client_by_id(server->global_list,
- client_id, TRUE, &cache);
- if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ if (id_type == SILC_ID_CLIENT) {
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
if (!client) {
- silc_free(client_id);
- goto out;
+ client = silc_idlist_find_client_by_id(server->local_list,
+ client_id, TRUE, &cache);
+ if (!client) {
+ silc_free(client_id);
+ goto out;
+ }
}
+ silc_free(client_id);
}
- silc_free(client_id);
/* Get the topic */
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
if (channel->topic && !strcmp(channel->topic, tmp))
goto out;
- /* Get user's channel entry and check that topic set is allowed. */
- if (!silc_server_client_on_channel(client, channel, &chl))
- goto out;
- if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
- !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
- !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
- SILC_LOG_DEBUG(("Topic change is not allowed"));
- goto out;
+ if (client) {
+ /* Get user's channel entry and check that topic set is allowed. */
+ if (!silc_server_client_on_channel(client, channel, &chl))
+ goto out;
+ if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
+ !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
+ !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
+ SILC_LOG_DEBUG(("Topic change is not allowed"));
+ goto out;
+ }
}
/* Change the topic */
silc_server_send_notify_topic_set(server, sock,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
- channel->id, SILC_ID_CHANNEL,
+ server->id, SILC_ID_SERVER,
channel->topic);
}
}
SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
silc_server_send_notify_channel_change(server, sock, FALSE,
channel_id, channel->id);
+
+ /* Wait that server re-announces this channel */
+ return;
}
+#if 0 /* Lets expect that server send CMODE_CHANGE notify anyway to
+ (attempt) force mode change, and may very well get it. */
+
/* If the mode is different from what we have then enforce the
mode change. */
mode = silc_channel_get_mode(payload);
channel->passphrase,
channel->founder_key);
}
+#endif
/* Create new key for the channel and send it to the server and
everybody else possibly on the channel. */
users_modes->len, FALSE);
silc_buffer_free(users_modes);
}
+ if (channel->topic) {
+ silc_server_send_notify_topic_set(server, sock,
+ server->server_type == SILC_ROUTER ?
+ TRUE : FALSE, channel,
+ server->id, SILC_ID_SERVER,
+ channel->topic);
+ }
}
}
clients (for server locally connected, and for router local cell). */
void silc_server_packet_send_clients(SilcServer server,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
+ SilcHashTable clients,
SilcPacketType type,
SilcPacketFlags flags,
bool route,
bool force_send)
{
SilcSocketConnection sock = NULL;
+ SilcHashTableList htl;
SilcClientEntry client = NULL;
SilcServerEntry *routed = NULL;
SilcUInt32 routed_count = 0;
bool gone = FALSE;
- int i, k;
+ int k;
SILC_LOG_DEBUG(("Sending packet to list of clients"));
/* Send to all clients in table */
- for (i = 0; i < clients_count; i++) {
- client = clients[i];
-
+ silc_hash_table_list(clients, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void **)&client)) {
/* If client has router set it is not locally connected client and
we will route the message to the router set in the client. Though,
send locally connected server in all cases. */
client->id, SILC_ID_CLIENT,
data, data_len, force_send);
}
-
+ silc_hash_table_list_reset(&htl);
silc_free(routed);
}
/* Send the message to clients on the channel's client list. */
silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
client = chl->client;
if (!client)
continue;
/* Send the message to clients on the channel's client list. */
silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
client = chl->client;
if (!client || client == sender_entry)
continue;
/* Send the message to clients on the channel's client list. */
silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
if (chl->client && !chl->client->router) {
sock = (SilcSocketConnection)chl->client->connection;
packetdata.src_id_type = SILC_ID_SERVER;
silc_hash_table_list(client->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
channel = chl->channel;
/* Send the message to all clients on the channel's client list. */
silc_hash_table_list(channel->user_list, &htl2);
- while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
+ while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
c = chl2->client;
if (sender && c == sender)
SilcSocketConnection sock,
SilcPacketContext *packet);
void silc_server_packet_send_clients(SilcServer server,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
+ SilcHashTable clients,
SilcPacketType type,
SilcPacketFlags flags,
bool route,
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
- SILC_LOG_DEBUG(("Start"));
-
- if (silc_verify_public_key_internal(server, ctx->sock,
- (ctx->responder == FALSE ?
- SILC_SOCKET_TYPE_ROUTER:
- ctx->sconfig.ref_ptr ? SILC_SOCKET_TYPE_SERVER :
- ctx->rconfig.ref_ptr ? SILC_SOCKET_TYPE_ROUTER :
- SILC_SOCKET_TYPE_CLIENT),
- pk_data, pk_len, pk_type))
+ SILC_LOG_DEBUG(("Verifying received public key"));
+
+ if (silc_verify_public_key_internal(
+ server, ctx->sock,
+ (ctx->responder == FALSE ?
+ SILC_SOCKET_TYPE_ROUTER:
+ ctx->sconfig.ref_ptr ? SILC_SOCKET_TYPE_SERVER :
+ ctx->rconfig.ref_ptr ? SILC_SOCKET_TYPE_ROUTER :
+ SILC_SOCKET_TYPE_CLIENT),
+ pk_data, pk_len, pk_type))
completion(ske, SILC_SKE_STATUS_OK, completion_context);
else
completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
SilcUnknownEntry conn_data;
SilcIDListData idata;
- SILC_LOG_DEBUG(("Setting new key into use"));
+ SILC_LOG_DEBUG(("Setting new keys into use"));
conn_data = silc_calloc(1, sizeof(*conn_data));
idata = (SilcIDListData)conn_data;
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
- SILC_LOG_DEBUG(("Start"));
-
if (ske->status != SILC_SKE_STATUS_OK) {
SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol",
silc_ske_map_status(ske->status)));
/* Send Ok to the other end. We will end the protocol as responder
sends Ok to us when we will take the new keys into use. */
if (ctx->responder == FALSE) {
+ SILC_LOG_DEBUG(("Ending key exchange protocol"));
silc_ske_end(ctx->ske);
/* End the protocol on the next round */
SilcServer server = (SilcServer)ctx->server;
SilcSKEStatus status = SILC_SKE_STATUS_OK;
- SILC_LOG_DEBUG(("Start"));
-
if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
protocol->state = SILC_PROTOCOL_STATE_START;
- SILC_LOG_DEBUG(("State=%d", protocol->state));
+ SILC_LOG_DEBUG(("Current protocol state %d", protocol->state));
switch(protocol->state) {
case SILC_PROTOCOL_STATE_START:
if (ctx->responder == TRUE) {
/* Start the key exchange by processing the received security
properties packet from initiator. */
+ SILC_LOG_DEBUG(("Process security property list (KE)"));
status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
silc_version_string,
ctx->packet->buffer, ctx->flags);
} else {
SilcSKEStartPayload *start_payload;
+ SILC_LOG_DEBUG(("Send security property list (KE)"));
+
/* Assemble security properties. */
silc_ske_assemble_security_properties(ske, ctx->flags,
silc_version_string,
*/
if (ctx->responder == TRUE) {
/* Sends the selected security properties to the initiator. */
+ SILC_LOG_DEBUG(("Send security property list reply (KE)"));
status = silc_ske_responder_phase_1(ctx->ske);
} else {
/* Call Phase-1 function. This processes the Key Exchange Start
paylaod reply we just got from the responder. The callback
function will receive the processed payload where we will
save it. */
+ SILC_LOG_DEBUG(("Process security property list reply (KE)"));
status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
}
the initiator. This also creates our parts of the Diffie
Hellman algorithm. The silc_server_protocol_ke_continue
will be called after the public key has been verified. */
+ SILC_LOG_DEBUG(("Process KE1 packet"));
status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
} else {
/* Call the Phase-2 function. This creates Diffie Hellman
key exchange parameters and sends our public part inside
Key Exhange 1 Payload to the responder. */
+ SILC_LOG_DEBUG(("Send KE1 packet"));
status = silc_ske_initiator_phase_2(ctx->ske,
server->public_key,
server->private_key,
if (ctx->responder == TRUE) {
/* This creates the key exchange material and sends our
public parts to the initiator inside Key Exchange 2 Payload. */
+ SILC_LOG_DEBUG(("Process KE2 packet"));
status = silc_ske_responder_finish(ctx->ske,
server->public_key,
server->private_key,
/* Finish the protocol. This verifies the Key Exchange 2 payload
sent by responder. The silc_server_protocol_ke_continue will
be called after the public key has been verified. */
+ SILC_LOG_DEBUG(("Send KE2 packet"));
status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
}
int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
int hash_len = silc_hash_len(ctx->ske->prop->hash);
+ SILC_LOG_DEBUG(("Process computed key material"));
+
/* Process the key material */
keymat = silc_calloc(1, sizeof(*keymat));
status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
/* Send Ok to the other end if we are responder. If we are initiator
we have sent this already. */
- if (ctx->responder == TRUE)
+ if (ctx->responder == TRUE) {
+ SILC_LOG_DEBUG(("Ending key exchange protocol"));
silc_ske_end(ctx->ske);
+ }
/* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
return TRUE;
}
+ SILC_LOG_ERROR(("Error computing signature"));
+
silc_free(*auth_data);
silc_buffer_free(auth);
return FALSE;
remote_auth_len, ske);
}
+ SILC_LOG_DEBUG(("Authentication %s", result ? "successful" : "failed"));
+
return result;
}
(SilcServerConnAuthInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
- SILC_LOG_DEBUG(("Start"));
-
if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
protocol->state = SILC_PROTOCOL_STATE_START;
- SILC_LOG_DEBUG(("State=%d", protocol->state));
+ SILC_LOG_DEBUG(("Current protocol state %d", protocol->state));
switch(protocol->state) {
case SILC_PROTOCOL_STATE_START:
SilcIDListData idata = (SilcIDListData)ctx->sock->user_data;
SilcSKEStatus status;
- SILC_LOG_DEBUG(("Start"));
-
if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
protocol->state = SILC_PROTOCOL_STATE_START;
- SILC_LOG_DEBUG(("State=%d", protocol->state));
+ SILC_LOG_DEBUG(("Current protocol state %d", protocol->state));
switch(protocol->state) {
case SILC_PROTOCOL_STATE_START:
context = (void *)server;
- SILC_LOG_DEBUG(("Start"));
-
/* Check whether we could resolve both IP and FQDN. */
if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
server->config->require_reverse_lookup)) {
initiator of the protocol thus we will wait for initiation from
there before we start the protocol. */
server->stat.auth_attempts++;
+ SILC_LOG_DEBUG(("Starting key exchange protocol"));
silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
&sock->protocol, proto_ctx,
silc_server_accept_new_connection_second);
if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
(protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
/* Error occured during protocol */
+ SILC_LOG_DEBUG(("Error key exchange protocol"));
silc_protocol_free(protocol);
sock->protocol = NULL;
silc_ske_free_key_material(ctx->keymat);
ctx->ske->prop->hmac,
ctx->ske->prop->group,
ctx->responder)) {
+ SILC_LOG_ERROR(("Error setting key material in use"));
silc_protocol_free(protocol);
sock->protocol = NULL;
silc_ske_free_key_material(ctx->keymat);
but we won't start it yet. We will be receiving party of this
protocol thus we will wait that connecting party will make
their first move. */
+ SILC_LOG_DEBUG(("Starting connection authentication protocol"));
silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
&sock->protocol, proto_ctx,
silc_server_accept_new_connection_final);
void *id_entry;
SilcUInt32 hearbeat_timeout = server->config->param.keepalive_secs;
- SILC_LOG_DEBUG(("Start"));
-
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
/* Error occured during protocol */
+ SILC_LOG_DEBUG(("Error during authentication protocol"));
silc_protocol_free(protocol);
sock->protocol = NULL;
if (ctx->packet)
if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
&server->config->param,
conn->param, ctx->ske)) {
+ SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
+ sock->ip));
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_BANNED_FROM_SERVER,
+ NULL);
server->stat.auth_failures++;
goto out;
}
&server->config->param,
rconn ? rconn->param : NULL,
ctx->ske)) {
+ SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
+ sock->ip));
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_BANNED_FROM_SERVER,
+ NULL);
server->stat.auth_failures++;
goto out;
}
&server->config->param,
sconn ? sconn->param : NULL,
ctx->ske)) {
+ SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
+ sock->ip));
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_BANNED_FROM_SERVER,
+ NULL);
server->stat.auth_failures++;
goto out;
}
SilcUInt32 sequence = 0;
int ret;
- if (!sock)
+ if (!sock) {
+ SILC_LOG_DEBUG(("Unknown socket connection"));
return;
-
- SILC_LOG_DEBUG(("Processing packet"));
+ }
/* Packet sending */
if (type == SILC_TASK_WRITE) {
/* Do not send data to disconnected connection */
- if (SILC_IS_DISCONNECTED(sock))
+ if (SILC_IS_DISCONNECTED(sock)) {
+ SILC_LOG_DEBUG(("Disconnected socket connection, cannot send"));
return;
+ }
server->stat.packets_sent++;
SilcIDListData idata = (SilcIDListData)sock->user_data;
int ret;
- SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("Parsing packet"));
/* Parse the packet */
if (parse_ctx->normal)
SilcPacketType type = packet->type;
SilcIDListData idata = (SilcIDListData)sock->user_data;
- SILC_LOG_DEBUG(("Parsing packet type %d", type));
-
/* Parse the packet type */
switch (type) {
case SILC_PACKET_DISCONNECT:
SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
break;
}
-
}
/* Creates connection to a remote router. */
keys are regnerated. This is called only by the function
silc_server_remove_clients_by_server. */
-static void silc_server_remove_clients_channels(SilcServer server,
- SilcSocketConnection sock,
- SilcClientEntry client,
- SilcHashTable channels)
+static void
+silc_server_remove_clients_channels(SilcServer server,
+ SilcServerEntry server_entry,
+ SilcHashTable clients,
+ SilcClientEntry client,
+ SilcHashTable channels)
{
SilcChannelEntry channel;
- SilcChannelClientEntry chl;
- SilcHashTableList htl;
+ SilcChannelClientEntry chl, chl2;
+ SilcHashTableList htl, htl2;
SilcBuffer clidp;
SILC_LOG_DEBUG(("Start"));
if (!client || !client->id)
return;
+ if (silc_hash_table_find(clients, client, NULL, NULL))
+ silc_hash_table_del(clients, client);
+
clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
/* Remove the client from all channels. The client is removed from
continue;
}
+ /* Mark other local clients to the table of clients whom will receive
+ the SERVER_SIGNOFF notify. */
+ silc_hash_table_list(channel->user_list, &htl2);
+ while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
+ SilcClientEntry c = chl2->client;
+ if (!c)
+ continue;
+
+ /* Add client to table, if it's not from the signoff server */
+ if (c->router != server_entry &&
+ !silc_hash_table_find(clients, c, NULL, NULL))
+ silc_hash_table_add(clients, c, c);
+ }
+ silc_hash_table_list_reset(&htl2);
+
/* Add the channel to the the channels list to regenerate the
channel key */
if (!silc_hash_table_find(channels, channel, NULL, NULL))
SilcIDCacheEntry id_cache = NULL;
SilcClientEntry client = NULL;
SilcBuffer idp;
- SilcClientEntry *clients = NULL;
- SilcUInt32 clients_c = 0;
unsigned char **argv = NULL;
SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
SilcHashTableList htl;
SilcChannelEntry channel;
- SilcHashTable channels;
+ SilcHashTable channels, clients;
int i;
SILC_LOG_DEBUG(("Start"));
from the channels. */
channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
NULL, NULL, TRUE);
+ clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
+ NULL, NULL, TRUE);
if (server_signoff) {
idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
}
if (client->router != entry) {
- if (server_signoff) {
- clients = silc_realloc(clients,
- sizeof(*clients) * (clients_c + 1));
- clients[clients_c] = client;
- clients_c++;
- }
-
if (!silc_idcache_list_next(list, &id_cache))
break;
else
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
/* Remove the client entry */
- silc_server_remove_clients_channels(server, NULL, client, channels);
+ silc_server_remove_clients_channels(server, entry, clients,
+ client, channels);
if (!server_signoff) {
client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
}
if (client->router != entry) {
- if (server_signoff && client->connection) {
- clients = silc_realloc(clients,
- sizeof(*clients) * (clients_c + 1));
- clients[clients_c] = client;
- clients_c++;
- }
-
if (!silc_idcache_list_next(list, &id_cache))
break;
else
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
/* Remove the client entry */
- silc_server_remove_clients_channels(server, NULL, client, channels);
+ silc_server_remove_clients_channels(server, entry, clients,
+ client, channels);
if (!server_signoff) {
client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
silc_buffer_free(args);
}
+
+
/* Send to local clients. We also send the list of client ID's that
is to be removed for those servers that would like to use that list. */
args = silc_argument_payload_encode(argc, argv, argv_lens,
argv_types);
not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
argc, args);
- silc_server_packet_send_clients(server, clients, clients_c,
+ silc_server_packet_send_clients(server, clients,
SILC_PACKET_NOTIFY, 0, FALSE,
not->data, not->len, FALSE);
- silc_free(clients);
silc_buffer_free(args);
silc_buffer_free(not);
for (i = 0; i < argc; i++)
silc_free(argv);
silc_free(argv_lens);
silc_free(argv_types);
+ silc_hash_table_free(clients);
}
/* We must now re-generate the channel key for all channels that had
{ "config-file", 1, NULL, 'f' },
{ "passphrase", 1, NULL, 'p' },
{ "debug", 2, NULL, 'd' },
+ { "debug-level", 1, NULL, 'D' },
{ "hexdump", 0, NULL, 'x' },
{ "help", 0, NULL, 'h' },
{ "foreground", 0, NULL, 'F' },
" Generic Options:\n"
" -f --config-file=FILE Alternate configuration file\n"
" -d --debug=string Enable debugging (Implies --foreground)\n"
+" -D --debug-level=level Enable debugging (Implies --foreground)\n"
" -x --hexdump Enable hexdumps (Implies --debug)\n"
" -h --help Display this message\n"
" -F --foreground Dont fork\n"
fclose(fdd);
}
+typedef struct {
+ int level;
+ const char *string;
+} DebugLevel;
+
+static DebugLevel debug_levels[] = {
+ /* Basic stuff from silcd/ */
+ { 5, "silc_server_*" },
+
+ /* All from silcd/ */
+ { 10, "*silcd*,*serverid*,silc_server_*,*idlist*" },
+
+ /* All from silcd/ and basic stuff from libs */
+ { 15, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,*silcske*" },
+
+ /* All from silcd/ and more stuff from libs */
+ { 20, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+ "*silcpacket*,*ske*,*silcrng*" },
+
+ /* All from silcd/ and even more stuff from libs */
+ { 25, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+ "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" },
+
+ /* All from silcd/ and even more stuff from libs + all from silccore */
+ { 30, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+ "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*"
+ "*silcid*,*argument*" },
+
+ /* All from silcd/, all from silccore, silccrypt and silcmath */
+ { 35, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+ "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*"
+ "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*" },
+
+ /* All from silcd/, all from silccore, silccrypt and silcmath + stuff
+ from silcutil */
+ { 40, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+ "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*"
+ "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*"
+ "*sockconn*" },
+
+ /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff
+ from silcutil */
+ { 45, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+ "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*"
+ "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*"
+ "*sockconn*,*net*" },
+
+ /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff
+ from silcutil */
+ { 50, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+ "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*"
+ "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*"
+ "*sockconn*,*net*,*log*,*config*" },
+
+ /* All */
+ { 90, "*" },
+
+ { -1, NULL },
+};
+
+static void silc_get_debug_level(int level)
+{
+ int i;
+
+ if (level < 0)
+ return;
+
+ for (i = 0; debug_levels[i].string; i++)
+ if (level <= debug_levels[i].level) {
+ silc_log_set_debug_string(debug_levels[i].string);
+ break;
+ }
+}
+
/* This function should not be called directly but throught the wrapper
macro SILC_SERVER_LOG_STDERR() */
/* Parse command line arguments */
if (argc > 1) {
- while ((opt = getopt_long(argc, argv, "f:p:d:xhFVC:",
+ while ((opt = getopt_long(argc, argv, "f:p:d:D:xhFVC:",
long_opts, &option_index)) != EOF) {
switch(opt) {
case 'h':
silc_debug = TRUE;
if (optarg)
silc_log_set_debug_string(optarg);
- foreground = TRUE; /* implied */
- silc_log_quick = TRUE; /* implied */
+ foreground = TRUE; /* implied */
+ silc_log_quick = TRUE; /* implied */
+#else
+ fprintf(stderr,
+ "Run-time debugging is not enabled. To enable it recompile\n"
+ "the server with --enable-debug configuration option.\n");
+#endif
+ break;
+ case 'D':
+#ifdef SILC_DEBUG
+ silc_debug = TRUE;
+ if (optarg)
+ silc_get_debug_level(atoi(optarg));
+ foreground = TRUE; /* implied */
+ silc_log_quick = TRUE; /* implied */
#else
fprintf(stderr,
"Run-time debugging is not enabled. To enable it recompile\n"
SilcUInt32 pull_len = 0;
int i = 0, ret;
- SILC_LOG_DEBUG(("Parsing argument payload"));
-
silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
newp = silc_calloc(1, sizeof(*newp));
if (!newp)
pull_len += 3 + p_len;
}
- if (buffer.len != 0)
+ if (buffer.len != 0) {
+ SILC_LOG_DEBUG(("Malformed argument payload"));
goto err;
+ }
newp->argc = argc;
newp->pos = 0;
return newp;
err:
+ SILC_LOG_DEBUG(("Error parsing argument payload"));
if (i)
for (ret = 0; ret < i; ret++)
silc_free(newp->argv[ret]);
SilcUInt32 len;
int i;
- SILC_LOG_DEBUG(("Encoding Argument payload"));
-
len = 0;
for (i = 0; i < argc; i++)
len += 3 + argv_lens[i];
SilcUInt32 len;
int i;
- SILC_LOG_DEBUG(("Encoding Argument payload"));
-
len = 0;
for (i = 0; i < payload->argc; i++)
len += 3 + payload->argv_lens[i];
SilcIDPayload newp;
int ret;
- SILC_LOG_DEBUG(("Parsing ID payload"));
-
silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
newp = silc_calloc(1, sizeof(*newp));
if (!newp)
return newp;
err:
+ SILC_LOG_DEBUG(("Error parsing ID payload"));
silc_free(newp);
return NULL;
}
SILC_STR_UI_SHORT(&idlen),
SILC_STR_END);
if (ret == -1)
- return NULL;
+ goto err;
if (type > SILC_ID_CHANNEL)
- return NULL;
+ goto err;
silc_buffer_pull(&buffer, 4);
if (idlen > buffer.len || idlen > SILC_PACKET_MAX_ID_LEN)
- return NULL;
+ goto err;
ret = silc_buffer_unformat(&buffer,
SILC_STR_UI_XNSTRING(&id_data, idlen),
SILC_STR_END);
if (ret == -1)
- return NULL;
+ goto err;
id = silc_id_str2id(id_data, idlen, type);
*ret_type = type;
return id;
+
+ err:
+ SILC_LOG_DEBUG(("Error parsing ID payload"));
+ return NULL;
}
/* Encodes ID Payload */
{
SilcBuffer buffer;
- SILC_LOG_DEBUG(("Encoding %s ID payload",
- type == SILC_ID_CLIENT ? "Client" :
- type == SILC_ID_SERVER ? "Server" : "Channel"));
-
buffer = silc_buffer_alloc_size(4 + id_len);
if (!buffer)
return NULL;
endif
endif
+if SILC_DIST_TOOLKIT
+SILC_DIST_SOURCE = stacktrace.c
+SILC_DIST_HEADERS = stacktrace.h
+else
+SILC_DIST_SOURCE =
+SILC_DIST_HEADERS =
+endif
+
noinst_LIBRARIES = libsilcutil.a
libsilcutil_a_SOURCES = \
+ $(SILC_DIST_SOURCE) \
silcbuffmt.c \
silcconfig.c \
silclog.c \
silcutil.c \
silchashtable.c \
silcsockconn.c \
- silcprotocol.c \
- stacktrace.c
+ silcprotocol.c
if SILC_DIST_TOOLKIT
include_HEADERS = \
+ $(SILC_DIST_SOURCE) \
silcbuffer.h \
silcbuffmt.h \
silcconfig.h \
len = strlen(string);
if (len >= sizeof(silc_log_debug_string))
len = sizeof(silc_log_debug_string) - 1;
+ memset(silc_log_debug_string, 0, sizeof(silc_log_debug_string));
strncpy(silc_log_debug_string, string, len);
silc_free(string);
}
void *silc_memdup(const void *ptr, size_t size);
#else
+#ifndef SILC_DIST_TOOLKIT
+#error "The stack trace is not supported in this distribution"
+#endif
+
#include "stacktrace.h"
#endif /* SILC_STACKTRACE */