X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fserver.c;h=45231d05708ba94b80d3a4cdf0ba614e047d846b;hp=7d5ce4edb2a1fd4c925d638aa73ea537b3513066;hb=e9dff3f0119c0f38cb2504037e6e7ce2665a5eee;hpb=8b11d3c1627f1dc3c7966bb51901bcdcf1f8a9fb diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 7d5ce4ed..45231d05 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -194,7 +194,7 @@ static void silc_server_packet_eos(SilcPacketEngine engine, SilcServer server = callback_context; SilcIDListData idata = silc_packet_get_context(stream); - SILC_LOG_DEBUG(("End of stream received")); + SILC_LOG_DEBUG(("End of stream received, sock %p", stream)); if (!idata) return; @@ -259,6 +259,8 @@ static void silc_server_packet_error(SilcPacketEngine engine, const char *ip; SilcUInt16 port; + SILC_LOG_DEBUG(("Packet error, sock %p", stream)); + if (!idata || !sock) return; @@ -1261,13 +1263,10 @@ SILC_TASK_CALLBACK(silc_server_purge_expired_clients) silc_dlist_start(server->expired_clients); while ((client = silc_dlist_get(server->expired_clients))) { - if (client->data.status & SILC_IDLIST_STATUS_REGISTERED) - continue; - /* For unregistered clients the created timestamp is actually unregistered timestamp. Make sure client remains in history at least 500 seconds. */ - if (curtime - client->data.created < 500) + if (client->data.created && curtime - client->data.created < 500) continue; id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ? @@ -1290,6 +1289,8 @@ SILC_TASK_CALLBACK(silc_server_purge_expired_clients) void silc_server_connection_free(SilcServerConnection sconn) { + if (!sconn) + return; SILC_LOG_DEBUG(("Free connection %p", sconn)); silc_dlist_del(sconn->server->conns, sconn); silc_server_config_unref(&sconn->conn); @@ -1345,7 +1346,8 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SilcID remote_id; const char *ip; - SILC_LOG_DEBUG(("Connection %p authentication completed", sconn)); + SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p", + sconn, entry)); entry->op = NULL; @@ -1353,11 +1355,11 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, /* Authentication failed */ /* XXX retry connecting */ - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_AUTH_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_AUTH_FAILED, NULL); return; } @@ -1379,12 +1381,11 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, strdup(sconn->remote_host), SILC_SERVER, NULL, NULL, sconn->sock); if (!id_entry) { - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); return; } @@ -1409,12 +1410,11 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STR_DATA(server->server_name, strlen(server->server_name)), SILC_STR_END)) { - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); return; } @@ -1448,12 +1448,11 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_ID_SERVER), NULL, sconn->sock); if (!id_entry) { - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); return; } @@ -1507,20 +1506,20 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, silc_server_backup_add(server, server->id_entry, ip, sconn->remote_port, TRUE); } + } #if 0 - } else { + else { /* We already have primary router. Disconnect this connection */ SILC_LOG_DEBUG(("We already have primary router, disconnect")); silc_idlist_del_server(server->global_list, id_entry); - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); return; -#endif /* 0 */ } +#endif /* 0 */ } else { /* Add this server to be our backup router */ id_entry->server_type = SILC_BACKUP_ROUTER; @@ -1531,12 +1530,11 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, break; default: - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_AUTH_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_AUTH_FAILED, NULL); return; } @@ -1576,7 +1574,7 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, { SilcPacketStream sock = context; SilcUnknownEntry entry = silc_packet_get_context(sock); - SilcServerConnection sconn = silc_ske_get_context(ske); + SilcServerConnection sconn = entry->data.sconn; SilcServer server = entry->server; SilcServerConfigRouter *conn = sconn->conn.ref_ptr; SilcAuthMethod auth_meth = SILC_AUTH_NONE; @@ -1587,7 +1585,7 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, SilcHmac hmac_send, hmac_receive; SilcHash hash; - SILC_LOG_DEBUG(("Connection %p, SKE completed", sconn)); + SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry)); entry->op = NULL; @@ -1598,11 +1596,11 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, /* XXX retry connecting */ silc_ske_free(ske); - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); return; } @@ -1616,11 +1614,11 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, /* Error setting keys */ silc_ske_free(ske); - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); return; } silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send, @@ -1635,11 +1633,11 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, /** Error allocating auth protocol */ silc_ske_free(ske); - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); return; } @@ -1701,9 +1699,9 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) /* Set source ID to packet stream */ if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id, 0, NULL)) { - silc_packet_stream_destroy(sconn->sock); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_packet_stream_destroy(sconn->sock); silc_server_connection_free(sconn); return; } @@ -1716,8 +1714,11 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) return; } entry->server = server; + entry->data.sconn = sconn; silc_packet_set_context(sconn->sock, entry); + SILC_LOG_DEBUG(("Created unknown connection %p", entry)); + /* Set Key Exchange flags from configuration, but fall back to global settings too. */ memset(¶ms, 0, sizeof(params)); @@ -1731,9 +1732,9 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) server->public_key, server->private_key, sconn); if (!ske) { silc_free(entry); - silc_packet_stream_destroy(sconn->sock); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_packet_stream_destroy(sconn->sock); silc_server_connection_free(sconn); return; } @@ -2147,6 +2148,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server->stat.auth_failures++; silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); goto out; } @@ -2185,6 +2190,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to backup " "router established, try later"); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; /* From here on, wait 20 seconds for the backup router to appear. */ @@ -2209,6 +2218,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server->stat.auth_failures++; silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); goto out; } entry->data.status |= SILC_IDLIST_STATUS_LOCAL; @@ -2275,6 +2288,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to primary " "router established, try later"); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; goto out; } @@ -2286,6 +2303,9 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, &server->config->param, rconn ? rconn->param : NULL, silc_connauth_get_ske(connauth))) { + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); server->stat.auth_failures++; goto out; } @@ -2362,6 +2382,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to backup " "router established, try later"); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; /* From here on, wait 20 seconds for the backup router to appear. */ @@ -2402,6 +2426,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_LOG_ERROR(("Could not add new server to cache")); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; goto out; } @@ -2525,6 +2553,10 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); return; } @@ -2537,6 +2569,7 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); return; } silc_packet_set_keys(sock, send_key, receive_key, hmac_send, @@ -2559,6 +2592,10 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); return; } @@ -2618,6 +2655,8 @@ static void silc_server_accept_new_connection(SilcNetStatus status, } server->stat.conn_num++; + SILC_LOG_DEBUG(("Created packet stream %p", packet_stream)); + /* Set source ID to packet stream */ if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id, 0, NULL)) { @@ -2637,6 +2676,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_BANNED_FROM_SERVER, deny->reason); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } @@ -2655,6 +2695,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } @@ -2664,6 +2705,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } entry->hostname = hostname; @@ -2673,6 +2715,8 @@ static void silc_server_accept_new_connection(SilcNetStatus status, entry->data.conn_type = SILC_CONN_UNKNOWN; silc_packet_set_context(packet_stream, entry); + SILC_LOG_DEBUG(("Created unknown connection %p", entry)); + silc_server_config_ref(&entry->cconfig, server->config, cconfig); silc_server_config_ref(&entry->sconfig, server->config, sconfig); silc_server_config_ref(&entry->rconfig, server->config, rconfig); @@ -2699,6 +2743,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } silc_ske_set_callbacks(ske, silc_server_verify_key, @@ -2821,9 +2866,9 @@ static void silc_server_rekey(SilcServer server, SilcPacketStream sock, SilcIDListData idata = silc_packet_get_context(sock); SilcSKE ske; - SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]", + SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p", idata->sconn->remote_host, idata->sconn->remote_port, - SILC_CONNTYPE_STRING(idata->conn_type))); + SILC_CONNTYPE_STRING(idata->conn_type), sock)); /* Allocate SKE */ ske = silc_ske_alloc(server->rng, server->schedule, NULL, @@ -2907,7 +2952,7 @@ void silc_server_disconnect_remote(SilcServer server, if (!sock) return; - SILC_LOG_DEBUG(("Disconnecting remote host")); + SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock)); va_start(ap, status); cp = va_arg(ap, char *); @@ -2975,8 +3020,10 @@ void silc_server_free_client_data(SilcServer server, SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); silc_schedule_task_del_by_context(server->schedule, client); - if (client->data.sconn) + if (client->data.sconn) { silc_server_connection_free(client->data.sconn); + client->data.sconn = NULL; + } /* We will not delete the client entry right away. We will take it into history (for WHOWAS command) for 5 minutes, unless we're @@ -2987,6 +3034,7 @@ void silc_server_free_client_data(SilcServer server, 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); } else { /* Delete directly since we're shutting down server */ @@ -3004,16 +3052,21 @@ void silc_server_free_sock_user_data(SilcServer server, SilcPacketStream sock, const char *signoff_message) { - SilcIDListData idata = silc_packet_get_context(sock); + SilcIDListData idata; const char *ip; SilcUInt16 port; - SILC_LOG_DEBUG(("Start")); + if (!sock) + return; + SILC_LOG_DEBUG(("Start, sock %p", sock)); + + idata = silc_packet_get_context(sock); if (!idata) return; - silc_schedule_task_del_by_context(server->schedule, sock); + silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey, + sock); /* Cancel active protocols */ if (idata) { @@ -3196,8 +3249,10 @@ void silc_server_free_sock_user_data(SilcServer server, } server->backup_noswitch = FALSE; - if (idata->sconn) + if (idata->sconn) { silc_server_connection_free(idata->sconn); + idata->sconn = NULL; + } /* Statistics */ if (idata->conn_type == SILC_CONN_SERVER) { @@ -3241,10 +3296,18 @@ void silc_server_free_sock_user_data(SilcServer server, { SilcUnknownEntry entry = (SilcUnknownEntry)idata; - SILC_LOG_DEBUG(("Freeing unknown connection data")); + SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry)); + + if (idata->sconn) { + if (server->router_conn == idata->sconn) { + if (!server->no_reconnect) + silc_server_create_connections(server); + server->router_conn = NULL; + } - if (idata->sconn) silc_server_connection_free(idata->sconn); + idata->sconn = NULL; + } silc_idlist_del_data(idata); silc_free(entry); silc_packet_set_context(sock, NULL); @@ -3917,6 +3980,7 @@ static void silc_server_announce_get_servers(SilcServer server, SilcIDCacheEntry id_cache; SilcServerEntry entry; SilcBuffer idp; + void *tmp; /* Go through all clients in the list */ if (silc_idcache_get_all(id_list->servers, &list)) { @@ -3933,11 +3997,14 @@ static void silc_server_announce_get_servers(SilcServer server, idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER); - *servers = silc_buffer_realloc(*servers, - (*servers ? - silc_buffer_truelen((*servers)) + - silc_buffer_len(idp) : - silc_buffer_len(idp))); + tmp = silc_buffer_realloc(*servers, + (*servers ? + silc_buffer_truelen((*servers)) + + silc_buffer_len(idp) : + silc_buffer_len(idp))); + if (!tmp) + return; + *servers = tmp; silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data)); silc_buffer_put(*servers, idp->data, silc_buffer_len(idp)); silc_buffer_pull(*servers, silc_buffer_len(idp)); @@ -4011,6 +4078,7 @@ static void silc_server_announce_get_clients(SilcServer server, SilcBuffer idp; SilcBuffer tmp; unsigned char mode[4]; + void *tmp2; /* Go through all clients in the list */ if (silc_idcache_get_all(id_list->clients, &list)) { @@ -4029,12 +4097,17 @@ static void silc_server_announce_get_clients(SilcServer server, silc_id_render(client->id, SILC_ID_CLIENT))); idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); + if (!idp) + return; - *clients = silc_buffer_realloc(*clients, - (*clients ? - silc_buffer_truelen((*clients)) + - silc_buffer_len(idp) : - silc_buffer_len(idp))); + tmp2 = silc_buffer_realloc(*clients, + (*clients ? + silc_buffer_truelen((*clients)) + + silc_buffer_len(idp) : + silc_buffer_len(idp))); + if (!tmp2) + return; + *clients = tmp2; silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data)); silc_buffer_put(*clients, idp->data, silc_buffer_len(idp)); silc_buffer_pull(*clients, silc_buffer_len(idp)); @@ -4044,11 +4117,14 @@ static void silc_server_announce_get_clients(SilcServer server, silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE, 2, idp->data, silc_buffer_len(idp), mode, 4); - *umodes = silc_buffer_realloc(*umodes, - (*umodes ? - silc_buffer_truelen((*umodes)) + - silc_buffer_len(tmp) : - silc_buffer_len(tmp))); + tmp2 = silc_buffer_realloc(*umodes, + (*umodes ? + silc_buffer_truelen((*umodes)) + + silc_buffer_len(tmp) : + silc_buffer_len(tmp))); + if (!tmp2) + return; + *umodes = tmp2; silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data)); silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp)); silc_buffer_pull(*umodes, silc_buffer_len(tmp)); @@ -4135,6 +4211,7 @@ void silc_server_announce_get_inviteban(SilcServer server, { SilcBuffer list, idp, idp2, tmp2; SilcUInt32 type; + void *ptype; SilcHashTableList htl; const unsigned char a[1] = { 0x03 }; @@ -4146,9 +4223,10 @@ void silc_server_announce_get_inviteban(SilcServer server, type = silc_hash_table_count(channel->invite_list); SILC_PUT16_MSB(type, list->data); silc_hash_table_list(channel->invite_list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) - list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2), - type); + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, + silc_buffer_len(tmp2), + SILC_PTR_TO_32(ptype)); silc_hash_table_list_reset(&htl); idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER); @@ -4170,9 +4248,10 @@ void silc_server_announce_get_inviteban(SilcServer server, type = silc_hash_table_count(channel->ban_list); SILC_PUT16_MSB(type, list->data); silc_hash_table_list(channel->ban_list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) - list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2), - type); + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, + silc_buffer_len(tmp2), + SILC_PTR_TO_32(ptype)); silc_hash_table_list_reset(&htl); *ban = @@ -4201,6 +4280,7 @@ void silc_server_announce_get_channel_users(SilcServer server, int len; unsigned char mode[4], ulimit[4]; char *hmac; + void *tmp2; SILC_LOG_DEBUG(("Start")); @@ -4237,10 +4317,13 @@ void silc_server_announce_get_channel_users(SilcServer server, SILC_CHANNEL_MODE_ULIMIT ? sizeof(ulimit) : 0)); len = silc_buffer_len(tmp); - *channel_modes = + tmp2 = silc_buffer_realloc(*channel_modes, (*channel_modes ? silc_buffer_truelen((*channel_modes)) + len : len)); + if (!tmp2) + return; + *channel_modes = tmp2; silc_buffer_pull_tail(*channel_modes, ((*channel_modes)->end - (*channel_modes)->data)); @@ -4265,10 +4348,13 @@ void silc_server_announce_get_channel_users(SilcServer server, chidp->data, silc_buffer_len(chidp)); len = silc_buffer_len(tmp); - *channel_users = + tmp2 = silc_buffer_realloc(*channel_users, (*channel_users ? silc_buffer_truelen((*channel_users)) + len : len)); + if (!tmp2) + return; + *channel_users = tmp2; silc_buffer_pull_tail(*channel_users, ((*channel_users)->end - (*channel_users)->data)); @@ -4290,11 +4376,14 @@ void silc_server_announce_get_channel_users(SilcServer server, fkey ? fkey->data : NULL, fkey ? silc_buffer_len(fkey) : 0); len = silc_buffer_len(tmp); - *channel_users_modes = + tmp2 = silc_buffer_realloc(*channel_users_modes, (*channel_users_modes ? silc_buffer_truelen((*channel_users_modes)) + len : len)); + if (!tmp2) + return; + *channel_users_modes = tmp2; silc_buffer_pull_tail(*channel_users_modes, ((*channel_users_modes)->end - (*channel_users_modes)->data)); @@ -4336,6 +4425,7 @@ void silc_server_announce_get_channels(SilcServer server, SilcUInt16 name_len; int len; int i = *channel_users_modes_c; + void *tmp; SilcBool announce; SILC_LOG_DEBUG(("Start")); @@ -4359,11 +4449,15 @@ void silc_server_announce_get_channels(SilcServer server, if (announce) { len = 4 + name_len + id_len + 4; - *channels = + tmp = silc_buffer_realloc(*channels, (*channels ? silc_buffer_truelen((*channels)) + len : len)); + if (!tmp) + break; + *channels = tmp; + silc_buffer_pull_tail(*channels, ((*channels)->end - (*channels)->data)); silc_buffer_format(*channels, @@ -4384,15 +4478,23 @@ void silc_server_announce_get_channels(SilcServer server, if (announce) { /* Channel user modes */ - *channel_users_modes = silc_realloc(*channel_users_modes, - sizeof(**channel_users_modes) * - (i + 1)); + tmp = silc_realloc(*channel_users_modes, + sizeof(**channel_users_modes) * (i + 1)); + if (!tmp) + break; + *channel_users_modes = tmp; (*channel_users_modes)[i] = NULL; - *channel_modes = silc_realloc(*channel_modes, - sizeof(**channel_modes) * (i + 1)); + tmp = silc_realloc(*channel_modes, + sizeof(**channel_modes) * (i + 1)); + if (!tmp) + break; + *channel_modes = tmp; (*channel_modes)[i] = NULL; - *channel_ids = silc_realloc(*channel_ids, - sizeof(**channel_ids) * (i + 1)); + tmp = silc_realloc(*channel_ids, + sizeof(**channel_ids) * (i + 1)); + if (!tmp) + break; + *channel_ids = tmp; (*channel_ids)[i] = NULL; silc_server_announce_get_channel_users(server, channel, &(*channel_modes)[i], @@ -4401,18 +4503,27 @@ void silc_server_announce_get_channels(SilcServer server, (*channel_ids)[i] = channel->id; /* Channel's topic */ - *channel_topics = silc_realloc(*channel_topics, - sizeof(**channel_topics) * (i + 1)); + tmp = silc_realloc(*channel_topics, + sizeof(**channel_topics) * (i + 1)); + if (!tmp) + break; + *channel_topics = tmp; (*channel_topics)[i] = NULL; silc_server_announce_get_channel_topic(server, channel, &(*channel_topics)[i]); /* Channel's invite and ban list */ - *channel_invites = silc_realloc(*channel_invites, - sizeof(**channel_invites) * (i + 1)); + tmp = silc_realloc(*channel_invites, + sizeof(**channel_invites) * (i + 1)); + if (!tmp) + break; + *channel_invites = tmp; (*channel_invites)[i] = NULL; - *channel_bans = silc_realloc(*channel_bans, - sizeof(**channel_bans) * (i + 1)); + tmp = silc_realloc(*channel_bans, + sizeof(**channel_bans) * (i + 1)); + if (!tmp) + break; + *channel_bans = tmp; (*channel_bans)[i] = NULL; silc_server_announce_get_inviteban(server, channel, &(*channel_invites)[i],