X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fserver.c;h=aff2df5c1aeb8e710d0f852ea536cf2542d677b4;hb=a939f27e19b8084ef2acd25156b19d26d1440ace;hp=944576996af2995b09d11ca593402cc87a884e49;hpb=2a65d397034737650cec5171f03918294ab89c7c;p=silc.git diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 94457699..aff2df5c 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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; } @@ -1512,12 +1511,11 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, /* 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 */ } @@ -1531,12 +1529,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 +1573,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 +1584,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 +1595,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 +1613,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 +1632,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 +1698,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 +1713,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 +1731,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 +2147,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 +2189,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 +2217,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 +2287,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 +2302,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 +2381,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 +2425,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 +2552,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 +2568,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 +2591,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 +2654,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 +2675,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 +2694,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 +2704,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 +2714,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 +2742,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 +2865,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 +2951,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 +3019,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 +3033,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 +3051,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 +3248,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 +3295,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 +3979,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 +3996,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 +4077,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 +4096,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 +4116,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)); @@ -4204,6 +4279,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")); @@ -4240,10 +4316,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)); @@ -4268,10 +4347,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)); @@ -4293,11 +4375,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)); @@ -4339,6 +4424,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")); @@ -4362,11 +4448,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, @@ -4387,15 +4477,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], @@ -4404,18 +4502,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],