X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fpacket_send.c;h=a5366eab918d410f404ad3b595fa7224f9e9d390;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=a73493608c4acd0a77abecc4c4a7d09b3bf2a8b8;hpb=9c4f7f18c31afa9dbaf4540c30cafd980b29c318;p=silc.git diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index a7349360..a5366eab 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -78,7 +78,7 @@ void silc_server_packet_send(SilcServer server, SilcPacketType type, SilcPacketFlags flags, unsigned char *data, - uint32 data_len, + SilcUInt32 data_len, bool force_send) { void *dst_id = NULL; @@ -133,15 +133,17 @@ void silc_server_packet_send_dest(SilcServer server, void *dst_id, SilcIdType dst_id_type, unsigned char *data, - uint32 data_len, + SilcUInt32 data_len, bool force_send) { SilcPacketContext packetdata; SilcIDListData idata = (SilcIDListData)sock->user_data; SilcCipher cipher = NULL; SilcHmac hmac = NULL; + SilcUInt32 sequence = 0; unsigned char *dst_id_data = NULL; - uint32 dst_id_len = 0; + SilcUInt32 dst_id_len = 0; + int block_len = 0; /* If disconnecting, ignore the data */ if (SILC_IS_DISCONNECTING(sock)) @@ -158,6 +160,13 @@ void silc_server_packet_send_dest(SilcServer server, dst_id_len = silc_id_get_len(dst_id, dst_id_type); } + if (idata) { + cipher = idata->send_key; + hmac = idata->hmac_send; + sequence = idata->psn_send++; + block_len = silc_cipher_get_block_len(cipher); + } + /* Set the packet context pointers */ packetdata.type = type; packetdata.flags = flags; @@ -169,7 +178,7 @@ void silc_server_packet_send_dest(SilcServer server, packetdata.dst_id_type = dst_id_type; packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + packetdata.src_id_len + dst_id_len; - packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen); + packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len); /* Prepare outgoing data buffer for packet sending */ silc_packet_send_prepare(sock, @@ -188,17 +197,13 @@ void silc_server_packet_send_dest(SilcServer server, silc_buffer_put(sock->outbuf, data, data_len); /* Create the outgoing packet */ - silc_packet_assemble(&packetdata); - - if (idata) { - cipher = idata->send_key; - hmac = idata->hmac_send; - } + silc_packet_assemble(&packetdata, cipher); /* Encrypt the packet */ - silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len); + silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, sock->outbuf->len); - SILC_LOG_HEXDUMP(("Outgoing packet, len %d", sock->outbuf->len), + SILC_LOG_HEXDUMP(("Outgoing packet (%d), len %d", sequence, + sock->outbuf->len), sock->outbuf->data, sock->outbuf->len); /* Now actually send the packet */ @@ -227,17 +232,19 @@ void silc_server_packet_send_srcdest(SilcServer server, void *dst_id, SilcIdType dst_id_type, unsigned char *data, - uint32 data_len, + SilcUInt32 data_len, bool force_send) { SilcPacketContext packetdata; SilcIDListData idata; SilcCipher cipher = NULL; SilcHmac hmac = NULL; + SilcUInt32 sequence = 0; unsigned char *dst_id_data = NULL; - uint32 dst_id_len = 0; + SilcUInt32 dst_id_len = 0; unsigned char *src_id_data = NULL; - uint32 src_id_len = 0; + SilcUInt32 src_id_len = 0; + int block_len = 0; SILC_LOG_DEBUG(("Sending packet, type %d", type)); @@ -254,6 +261,13 @@ void silc_server_packet_send_srcdest(SilcServer server, src_id_len = silc_id_get_len(src_id, src_id_type); } + if (idata) { + cipher = idata->send_key; + hmac = idata->hmac_send; + sequence = idata->psn_send++; + block_len = silc_cipher_get_block_len(cipher); + } + /* Set the packet context pointers */ packetdata.type = type; packetdata.flags = flags; @@ -265,7 +279,7 @@ void silc_server_packet_send_srcdest(SilcServer server, packetdata.dst_id_type = dst_id_type; packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + packetdata.src_id_len + dst_id_len; - packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen); + packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len); /* Prepare outgoing data buffer for packet sending */ silc_packet_send_prepare(sock, @@ -284,17 +298,13 @@ void silc_server_packet_send_srcdest(SilcServer server, silc_buffer_put(sock->outbuf, data, data_len); /* Create the outgoing packet */ - silc_packet_assemble(&packetdata); - - if (idata) { - cipher = idata->send_key; - hmac = idata->hmac_send; - } + silc_packet_assemble(&packetdata, cipher); /* Encrypt the packet */ - silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len); + silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, sock->outbuf->len); - SILC_LOG_HEXDUMP(("Outgoing packet, len %d", sock->outbuf->len), + SILC_LOG_HEXDUMP(("Outgoing packet (%d), len %d", sequence, + sock->outbuf->len), sock->outbuf->data, sock->outbuf->len); /* Now actually send the packet */ @@ -330,10 +340,11 @@ void silc_server_packet_broadcast(SilcServer server, silc_buffer_push(buffer, buffer->data - buffer->head); silc_packet_send_prepare(sock, 0, 0, buffer->len); silc_buffer_put(sock->outbuf, buffer->data, buffer->len); - silc_packet_encrypt(idata->send_key, idata->hmac_send, + silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++, sock->outbuf, sock->outbuf->len); - SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", sock->outbuf->len), + SILC_LOG_HEXDUMP(("Broadcasted packet (%d), len %d", idata->psn_send - 1, + sock->outbuf->len), sock->outbuf->data, sock->outbuf->len); /* Now actually send the packet */ @@ -364,16 +375,89 @@ void silc_server_packet_route(SilcServer server, silc_buffer_push(buffer, buffer->data - buffer->head); silc_packet_send_prepare(sock, 0, 0, buffer->len); silc_buffer_put(sock->outbuf, buffer->data, buffer->len); - silc_packet_encrypt(idata->send_key, idata->hmac_send, + silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++, sock->outbuf, sock->outbuf->len); - SILC_LOG_HEXDUMP(("Routed packet, len %d", sock->outbuf->len), + SILC_LOG_HEXDUMP(("Routed packet (%d), len %d", idata->psn_send - 1, + sock->outbuf->len), sock->outbuf->data, sock->outbuf->len); /* Now actually send the packet */ silc_server_packet_send_real(server, sock, TRUE); } +/* This routine can be used to send a packet to table of clients provided + in `clients'. If `route' is FALSE the packet is routed only to local + clients (for server locally connected, and for router local cell). */ + +void silc_server_packet_send_clients(SilcServer server, + SilcClientEntry *clients, + SilcUInt32 clients_count, + SilcPacketType type, + SilcPacketFlags flags, + bool route, + unsigned char *data, + SilcUInt32 data_len, + bool force_send) +{ + SilcSocketConnection sock = NULL; + SilcClientEntry client = NULL; + SilcServerEntry *routed = NULL; + SilcUInt32 routed_count = 0; + bool gone = FALSE; + int i, 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]; + + /* 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. */ + if (server->server_type == SILC_ROUTER && client->router && + ((!route && client->router->router == server->id_entry) || route)) { + + /* Check if we have sent the packet to this route already */ + for (k = 0; k < routed_count; k++) + if (routed[k] == client->router) + break; + if (k < routed_count) + continue; + + /* Route only once to router */ + sock = (SilcSocketConnection)client->router->connection; + if (sock->type == SILC_SOCKET_TYPE_ROUTER) { + if (gone) + continue; + gone = TRUE; + } + + /* Send the packet */ + silc_server_packet_send_dest(server, sock, type, flags, + client->router->id, SILC_ID_SERVER, + data, data_len, force_send); + + /* Mark this route routed already */ + routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1)); + routed[routed_count++] = client->router; + continue; + } + + if (client->router) + continue; + + /* Send to locally connected client */ + sock = (SilcSocketConnection)client->connection; + silc_server_packet_send_dest(server, sock, type, flags, + client->id, SILC_ID_CLIENT, + data, data_len, force_send); + } + + silc_free(routed); +} + /* Internal routine to actually create the channel packet and send it to network. This is common function in channel message sending. If `channel_message' is TRUE this encrypts the message as it is strictly @@ -385,14 +469,28 @@ silc_server_packet_send_to_channel_real(SilcServer server, SilcPacketContext *packet, SilcCipher cipher, SilcHmac hmac, + SilcUInt32 sequence, unsigned char *data, - uint32 data_len, - int channel_message, + SilcUInt32 data_len, + bool channel_message, bool force_send) { + int block_len; + + if (!sock) + return; + packet->truelen = data_len + SILC_PACKET_HEADER_LEN + packet->src_id_len + packet->dst_id_len; + block_len = cipher ? silc_cipher_get_block_len(cipher) : 0; + if (channel_message) + packet->padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN + + packet->src_id_len + + packet->dst_id_len), block_len); + else + packet->padlen = SILC_PACKET_PADLEN(packet->truelen, block_len); + /* Prepare outgoing data buffer for packet sending */ silc_packet_send_prepare(sock, SILC_PACKET_HEADER_LEN + @@ -407,15 +505,17 @@ silc_server_packet_send_to_channel_real(SilcServer server, is encrypted with normal session key shared with the client, unless the `channel_message' is TRUE. */ silc_buffer_put(sock->outbuf, data, data_len); - silc_packet_assemble(packet); + silc_packet_assemble(packet, cipher); if (channel_message) - silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN + - packet->src_id_len + packet->dst_id_len + - packet->padlen); + silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, + SILC_PACKET_HEADER_LEN + packet->src_id_len + + packet->dst_id_len + packet->padlen); else - silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len); + silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, + sock->outbuf->len); - SILC_LOG_HEXDUMP(("Channel packet, len %d", sock->outbuf->len), + SILC_LOG_HEXDUMP(("Channel packet (%d), len %d", sequence, + sock->outbuf->len), sock->outbuf->data, sock->outbuf->len); /* Now actually send the packet */ @@ -429,7 +529,8 @@ silc_server_packet_send_to_channel_real(SilcServer server, If `route' is FALSE then the packet is sent only locally and will not be routed anywhere (for router locally means cell wide). If `sender' is provided then the packet is not sent to that connection since it - originally came from it. */ + originally came from it. If `send_to_clients' is FALSE then the + packet is not sent clients, only servers. */ void silc_server_packet_send_to_channel(SilcServer server, SilcSocketConnection sender, @@ -437,7 +538,7 @@ void silc_server_packet_send_to_channel(SilcServer server, SilcPacketType type, bool route, unsigned char *data, - uint32 data_len, + SilcUInt32 data_len, bool force_send) { SilcSocketConnection sock = NULL; @@ -447,7 +548,7 @@ void silc_server_packet_send_to_channel(SilcServer server, SilcChannelClientEntry chl; SilcHashTableList htl; SilcIDListData idata; - uint32 routed_count = 0; + SilcUInt32 routed_count = 0; bool gone = FALSE; int k; @@ -465,9 +566,6 @@ void silc_server_packet_send_to_channel(SilcServer server, packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL); packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL); packetdata.dst_id_type = SILC_ID_CHANNEL; - packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + - packetdata.src_id_len + packetdata.dst_id_len; - packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen); /* If there are global users in the channel we will send the message first to our router for further routing. */ @@ -481,11 +579,12 @@ void silc_server_packet_send_to_channel(SilcServer server, idata = (SilcIDListData)router; if (sock != sender) { - SILC_LOG_DEBUG(("Sending channel message to router for routing")); + SILC_LOG_DEBUG(("Sending packet to router for routing")); silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, FALSE, force_send); } @@ -532,6 +631,7 @@ void silc_server_packet_send_to_channel(SilcServer server, silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, FALSE, force_send); @@ -552,14 +652,16 @@ void silc_server_packet_send_to_channel(SilcServer server, if (sender && sock == sender) continue; - /* Send the packet */ + /* Send the packet */ silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, FALSE, force_send); } + silc_hash_table_list_reset(&htl); silc_free(routed); silc_free(packetdata.src_id); silc_free(packetdata.dst_id); @@ -586,8 +688,8 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server, !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->channel_key) { SilcBuffer chp; - uint32 iv_len, i; - uint16 dlen, flags; + SilcUInt32 iv_len, i; + SilcUInt16 dlen, flags; iv_len = silc_cipher_get_block_len(channel->channel_key); if (channel->iv[0] == '\0') @@ -632,7 +734,7 @@ void silc_server_packet_relay_to_channel(SilcServer server, SilcIdType sender_type, void *sender_entry, unsigned char *data, - uint32 data_len, + SilcUInt32 data_len, bool force_send) { bool found = FALSE; @@ -641,7 +743,7 @@ void silc_server_packet_relay_to_channel(SilcServer server, SilcClientEntry client = NULL; SilcServerEntry *routed = NULL; SilcChannelClientEntry chl; - uint32 routed_count = 0; + SilcUInt32 routed_count = 0; SilcIDListData idata; SilcHashTableList htl; bool gone = FALSE; @@ -667,9 +769,6 @@ void silc_server_packet_relay_to_channel(SilcServer server, packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL); packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL); packetdata.dst_id_type = SILC_ID_CHANNEL; - packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN + - packetdata.src_id_len + - packetdata.dst_id_len)); /* If there are global users in the channel we will send the message first to our router for further routing. */ @@ -689,6 +788,7 @@ void silc_server_packet_relay_to_channel(SilcServer server, silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, TRUE, force_send); } @@ -775,8 +875,7 @@ void silc_server_packet_relay_to_channel(SilcServer server, /* If private key mode is not set then decrypt the packet and re-encrypt it */ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { - unsigned char *tmp = silc_calloc(data_len, sizeof(*data)); - memcpy(tmp, data, data_len); + unsigned char *tmp = silc_memdup(data, data_len); /* Decrypt the channel message (we don't check the MAC) */ if (channel->channel_key && @@ -814,6 +913,7 @@ void silc_server_packet_relay_to_channel(SilcServer server, silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, TRUE, force_send); @@ -838,10 +938,12 @@ void silc_server_packet_relay_to_channel(SilcServer server, silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, TRUE, force_send); } + silc_hash_table_list_reset(&htl); silc_free(routed); silc_free(packetdata.src_id); silc_free(packetdata.dst_id); @@ -859,7 +961,7 @@ void silc_server_packet_send_local_channel(SilcServer server, SilcPacketType type, SilcPacketFlags flags, unsigned char *data, - uint32 data_len, + SilcUInt32 data_len, bool force_send) { SilcChannelClientEntry chl; @@ -880,6 +982,7 @@ void silc_server_packet_send_local_channel(SilcServer server, force_send); } } + silc_hash_table_list_reset(&htl); } /* Routine used to send (relay, route) private messages to some destination. @@ -892,6 +995,7 @@ void silc_server_send_private_message(SilcServer server, SilcSocketConnection dst_sock, SilcCipher cipher, SilcHmac hmac, + SilcUInt32 sequence, SilcPacketContext *packet) { SilcBuffer buffer = packet->buffer; @@ -905,7 +1009,7 @@ void silc_server_send_private_message(SilcServer server, silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len); /* Re-encrypt packet */ - silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, buffer->len); + silc_packet_encrypt(cipher, hmac, sequence, dst_sock->outbuf, buffer->len); /* Send the packet */ silc_server_packet_send_real(server, dst_sock, FALSE); @@ -918,7 +1022,7 @@ void silc_server_send_private_message(SilcServer server, silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len); /* Encrypt header */ - silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, + silc_packet_encrypt(cipher, hmac, sequence, dst_sock->outbuf, SILC_PACKET_HEADER_LEN + packet->src_id_len + packet->dst_id_len + packet->padlen); @@ -931,13 +1035,14 @@ void silc_server_send_private_message(SilcServer server, void silc_server_send_motd(SilcServer server, SilcSocketConnection sock) { - char *motd; - uint32 motd_len; + char *motd, *motd_file = NULL; + SilcUInt32 motd_len; - if (server->config && server->config->motd && - server->config->motd->motd_file) { + if (server->config) + motd_file = server->config->server_info->motd_file; - motd = silc_file_read(server->config->motd->motd_file, &motd_len); + if (motd_file) { + motd = silc_file_readfile(motd_file, &motd_len); if (!motd) return; @@ -975,7 +1080,7 @@ void silc_server_send_notify(SilcServer server, SilcSocketConnection sock, bool broadcast, SilcNotifyType type, - uint32 argc, ...) + SilcUInt32 argc, ...) { va_list ap; SilcBuffer packet; @@ -1005,7 +1110,7 @@ void silc_server_send_notify_args(SilcServer server, SilcSocketConnection sock, bool broadcast, SilcNotifyType type, - uint32 argc, + SilcUInt32 argc, SilcBuffer args) { SilcBuffer packet; @@ -1105,9 +1210,10 @@ void silc_server_send_notify_cmode(SilcServer server, SilcSocketConnection sock, bool broadcast, SilcChannelEntry channel, - uint32 mode_mask, + SilcUInt32 mode_mask, void *id, SilcIdType id_type, - char *cipher, char *hmac) + char *cipher, char *hmac, + char *passphrase) { SilcBuffer idp; unsigned char mode[4]; @@ -1117,22 +1223,24 @@ void silc_server_send_notify_cmode(SilcServer server, silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE, - 4, idp->data, idp->len, + 5, idp->data, idp->len, mode, 4, cipher, cipher ? strlen(cipher) : 0, - hmac, hmac ? strlen(hmac) : 0); + hmac, hmac ? strlen(hmac) : 0, + passphrase, passphrase ? + strlen(passphrase) : 0); silc_buffer_free(idp); } /* Sends CUMODE_CHANGE notify type. This tells that `client_id' changed the - `target' client's mode on `channel'. The Notify packet is always + `target' client's mode on `channel'. The notify packet is always destined to the channel. */ void silc_server_send_notify_cumode(SilcServer server, SilcSocketConnection sock, bool broadcast, SilcChannelEntry channel, - uint32 mode_mask, + SilcUInt32 mode_mask, void *id, SilcIdType id_type, SilcClientID *target) { @@ -1162,7 +1270,7 @@ void silc_server_send_notify_signoff(SilcServer server, SilcSocketConnection sock, bool broadcast, SilcClientID *client_id, - char *message) + const char *message) { SilcBuffer idp; @@ -1174,7 +1282,7 @@ void silc_server_send_notify_signoff(SilcServer server, silc_buffer_free(idp); } -/* Sends TOPIC_SET notify type. This tells that `client_id' changed +/* Sends TOPIC_SET notify type. This tells that `id' changed the `channel's topic to `topic'. The Notify packet is always destined to the channel. This function is used to send the topic set notifies between routers. */ @@ -1183,17 +1291,18 @@ void silc_server_send_notify_topic_set(SilcServer server, SilcSocketConnection sock, bool broadcast, SilcChannelEntry channel, - SilcClientID *client_id, + void *id, SilcIdType id_type, char *topic) { SilcBuffer idp; - idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); - silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_TOPIC_SET, - topic ? 2 : 1, - idp->data, idp->len, - topic, topic ? strlen(topic) : 0); + idp = silc_id_payload_encode(id, id_type); + silc_server_send_notify_dest(server, sock, broadcast, + (void *)channel->id, SILC_ID_CHANNEL, + SILC_NOTIFY_TYPE_TOPIC_SET, + topic ? 2 : 1, + idp->data, idp->len, + topic, topic ? strlen(topic) : 0); silc_buffer_free(idp); } @@ -1207,16 +1316,21 @@ void silc_server_send_notify_kicked(SilcServer server, bool broadcast, SilcChannelEntry channel, SilcClientID *client_id, + SilcClientID *kicker, char *comment) { - SilcBuffer idp; + SilcBuffer idp1; + SilcBuffer idp2; - idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); + idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); + idp2 = silc_id_payload_encode((void *)kicker, SILC_ID_CLIENT); silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, - SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, - comment ? 2 : 1, idp->data, idp->len, - comment, comment ? strlen(comment) : 0); - silc_buffer_free(idp); + SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, 3, + idp1->data, idp1->len, + comment, comment ? strlen(comment) : 0, + idp2->data, idp2->len); + silc_buffer_free(idp1); + silc_buffer_free(idp2); } /* Send KILLED notify type. This tells that the `client_id' client was @@ -1247,7 +1361,7 @@ void silc_server_send_notify_umode(SilcServer server, SilcSocketConnection sock, bool broadcast, SilcClientID *client_id, - uint32 mode_mask) + SilcUInt32 mode_mask) { SilcBuffer idp; unsigned char mode[4]; @@ -1318,7 +1432,7 @@ void silc_server_send_notify_dest(SilcServer server, void *dest_id, SilcIdType dest_id_type, SilcNotifyType type, - uint32 argc, ...) + SilcUInt32 argc, ...) { va_list ap; SilcBuffer packet; @@ -1344,9 +1458,9 @@ void silc_server_send_notify_dest(SilcServer server, void silc_server_send_notify_to_channel(SilcServer server, SilcSocketConnection sender, SilcChannelEntry channel, - unsigned char route_notify, + bool route_notify, SilcNotifyType type, - uint32 argc, ...) + SilcUInt32 argc, ...) { va_list ap; SilcBuffer packet; @@ -1372,23 +1486,23 @@ void silc_server_send_notify_on_channels(SilcServer server, SilcClientEntry sender, SilcClientEntry client, SilcNotifyType type, - uint32 argc, ...) + SilcUInt32 argc, ...) { int k; SilcSocketConnection sock = NULL; SilcPacketContext packetdata; SilcClientEntry c; SilcClientEntry *sent_clients = NULL; - uint32 sent_clients_count = 0; + SilcUInt32 sent_clients_count = 0; SilcServerEntry *routed = NULL; - uint32 routed_count = 0; + SilcUInt32 routed_count = 0; SilcHashTableList htl, htl2; SilcChannelEntry channel; SilcChannelClientEntry chl, chl2; SilcIDListData idata; SilcBuffer packet; unsigned char *data; - uint32 data_len; + SilcUInt32 data_len; bool force_send = FALSE; va_list ap; @@ -1442,18 +1556,24 @@ void silc_server_send_notify_on_channels(SilcServer server, /* Get data used in packet header encryption, keys and stuff. */ sock = (SilcSocketConnection)c->router->connection; idata = (SilcIDListData)c->router; - + + { + SILC_LOG_DEBUG(("*****************")); + SILC_LOG_DEBUG(("client->router->id %s", + silc_id_render(c->router->id, SILC_ID_SERVER))); + SILC_LOG_DEBUG(("client->router->connection->user_data->id %s", + silc_id_render(((SilcServerEntry)sock->user_data)->id, SILC_ID_SERVER))); + } + packetdata.dst_id = silc_id_id2str(c->router->id, SILC_ID_SERVER); packetdata.dst_id_len = silc_id_get_len(c->router->id, SILC_ID_SERVER); packetdata.dst_id_type = SILC_ID_SERVER; - packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + - packetdata.src_id_len + packetdata.dst_id_len; - packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen); /* Send the packet */ silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, FALSE, force_send); @@ -1479,14 +1599,12 @@ void silc_server_send_notify_on_channels(SilcServer server, packetdata.dst_id = silc_id_id2str(c->id, SILC_ID_CLIENT); packetdata.dst_id_len = silc_id_get_len(c->id, SILC_ID_CLIENT); packetdata.dst_id_type = SILC_ID_CLIENT; - packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + - packetdata.src_id_len + packetdata.dst_id_len; - packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen); /* Send the packet */ silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, idata->hmac_send, + idata->psn_send++, data, data_len, FALSE, force_send); @@ -1498,11 +1616,14 @@ void silc_server_send_notify_on_channels(SilcServer server, sent_clients[sent_clients_count++] = c; } } + silc_hash_table_list_reset(&htl2); } + silc_hash_table_list_reset(&htl); silc_free(routed); silc_free(sent_clients); silc_free(packetdata.src_id); + silc_buffer_free(packet); va_end(ap); } @@ -1516,7 +1637,7 @@ void silc_server_send_new_id(SilcServer server, SilcSocketConnection sock, bool broadcast, void *id, SilcIdType id_type, - uint32 id_len) + SilcUInt32 id_len) { SilcBuffer idp; @@ -1538,21 +1659,20 @@ void silc_server_send_new_id(SilcServer server, } /* Send New Channel Payload to notify about newly created channel in the - SILC network. Normal server nevers sends this packet. Router uses this - to notify other routers in the network about new channel. This packet - is broadcasted. */ + SILC network. Router uses this to notify other routers in the network + about new channel. This packet is broadcasted by router. */ void silc_server_send_new_channel(SilcServer server, SilcSocketConnection sock, bool broadcast, char *channel_name, void *channel_id, - uint32 channel_id_len, - uint32 mode) + SilcUInt32 channel_id_len, + SilcUInt32 mode) { SilcBuffer packet; unsigned char *cid; - uint32 name_len = strlen(channel_name); + SilcUInt32 name_len = strlen(channel_name); SILC_LOG_DEBUG(("Start")); @@ -1570,7 +1690,8 @@ void silc_server_send_new_channel(SilcServer server, /* Send to backup routers if this is being broadcasted to primary router. */ - if (server->router && server->router->connection && + if (server->server_type == SILC_ROUTER && + server->router && server->router->connection && sock == server->router->connection && broadcast) silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0, packet->data, packet->len, FALSE, TRUE); @@ -1595,9 +1716,9 @@ void silc_server_send_channel_key(SilcServer server, { SilcBuffer packet; unsigned char *chid; - uint32 tmp_len; + SilcUInt32 tmp_len; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Sending key to channel %s", channel->channel_name)); chid = silc_id_id2str(channel->id, SILC_ID_CHANNEL); if (!chid) @@ -1612,7 +1733,8 @@ void silc_server_send_channel_key(SilcServer server, channel->key_len / 8, channel->key); silc_server_packet_send_to_channel(server, sender, channel, SILC_PACKET_CHANNEL_KEY, - route, packet->data, packet->len, FALSE); + route, packet->data, packet->len, + FALSE); silc_buffer_free(packet); silc_free(chid); } @@ -1623,8 +1745,8 @@ void silc_server_send_channel_key(SilcServer server, void silc_server_send_command(SilcServer server, SilcSocketConnection sock, SilcCommand command, - uint16 ident, - uint32 argc, ...) + SilcUInt16 ident, + SilcUInt32 argc, ...) { SilcBuffer packet; va_list ap; @@ -1638,6 +1760,55 @@ void silc_server_send_command(SilcServer server, va_end(ap); } +/* Generic function to send any command reply. The arguments must be sent + already encoded into correct form in correct order. */ + +void silc_server_send_command_reply(SilcServer server, + SilcSocketConnection sock, + SilcCommand command, + SilcCommandStatus status, + SilcUInt16 ident, + SilcUInt32 argc, ...) +{ + SilcBuffer packet; + va_list ap; + + va_start(ap, argc); + + packet = silc_command_reply_payload_encode_vap(command, status, ident, + argc, ap); + silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, + packet->data, packet->len, TRUE); + silc_buffer_free(packet); + va_end(ap); +} + +/* Generic function to send any command reply. The arguments must be sent + already encoded into correct form in correct order. */ + +void silc_server_send_dest_command_reply(SilcServer server, + SilcSocketConnection sock, + void *dst_id, + SilcIdType dst_id_type, + SilcCommand command, + SilcCommandStatus status, + SilcUInt16 ident, + SilcUInt32 argc, ...) +{ + SilcBuffer packet; + va_list ap; + + va_start(ap, argc); + + packet = silc_command_reply_payload_encode_vap(command, status, ident, + argc, ap); + silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0, + dst_id, dst_id_type, packet->data, + packet->len, TRUE); + silc_buffer_free(packet); + va_end(ap); +} + /* Send the heartbeat packet. */ void silc_server_send_heartbeat(SilcServer server, @@ -1654,6 +1825,7 @@ void silc_server_relay_packet(SilcServer server, SilcSocketConnection dst_sock, SilcCipher cipher, SilcHmac hmac, + SilcUInt32 sequence, SilcPacketContext *packet, bool force_send) { @@ -1664,7 +1836,8 @@ void silc_server_relay_packet(SilcServer server, silc_buffer_put(dst_sock->outbuf, packet->buffer->data, packet->buffer->len); /* Re-encrypt packet */ - silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, packet->buffer->len); + silc_packet_encrypt(cipher, hmac, sequence, dst_sock->outbuf, + packet->buffer->len); /* Send the packet */ silc_server_packet_send_real(server, dst_sock, force_send); @@ -1677,7 +1850,7 @@ void silc_server_relay_packet(SilcServer server, void silc_server_send_connection_auth_request(SilcServer server, SilcSocketConnection sock, - uint16 conn_type, + SilcUInt16 conn_type, SilcAuthMethod auth_meth) { SilcBuffer packet;