1 /* Copyright (C) 2009-2012, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2012, Thorvald Natvig <thorvald@natvig.com>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 - Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15 - Neither the name of the Developers nor the names of its contributors may
16 be used to endorse or promote products derived from this software without
17 specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/socket.h>
43 #include "messagehandler.h"
47 #include "voicetarget.h"
50 extern char system_string[], version_string[];
52 static int Client_read(client_t *client);
53 static int Client_write(client_t *client);
54 static int Client_send_udp(client_t *client, uint8_t *data, int len);
55 void Client_free(client_t *client);
57 declare_list(clients);
58 static int clientcount; /* = 0 */
59 static int maxBandwidth;
61 int iCodecAlpha, iCodecBeta;
68 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
76 int Client_getfds(struct pollfd *pollfds)
80 list_iterate(itr, &clients) {
82 c = list_get_entry(itr, client_t, node);
83 pollfds[i].fd = c->tcpfd;
84 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
85 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
86 pollfds[i].events |= POLLOUT;
95 int bwTop = maxBandwidth + maxBandwidth / 4;
96 list_iterate(itr, &clients) {
98 c = list_get_entry(itr, client_t, node);
99 Log_debug("Client %s BW available %d", c->username, c->availableBandwidth);
100 c->availableBandwidth += maxBandwidth;
101 if (c->availableBandwidth > bwTop)
102 c->availableBandwidth = bwTop;
104 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
105 /* No activity from client - assume it is lost and close. */
106 Log_info_client(c, "Timeout, closing.");
113 void Client_codec_add(client_t *client, int codec)
115 codec_t *cd = malloc(sizeof(codec_t));
117 Log_fatal("Out of memory");
118 init_list_entry(&cd->node);
120 list_add_tail(&cd->node, &client->codecs);
123 void Client_codec_free(client_t *client)
125 struct dlist *itr, *save;
126 list_iterate_safe(itr, save, &client->codecs) {
127 list_del(&list_get_entry(itr, codec_t, node)->node);
128 free(list_get_entry(itr, codec_t, node));
132 codec_t *Client_codec_iterate(client_t *client, codec_t **codec_itr)
134 codec_t *cd = *codec_itr;
136 if (list_empty(&client->codecs))
140 cd = list_get_entry(list_get_first(&client->codecs), codec_t, node);
142 if (list_get_next(&cd->node) == &client->codecs)
145 cd = list_get_entry(list_get_next(&cd->node), codec_t, node);
151 void Client_token_add(client_t *client, char *token_string)
155 if (client->tokencount >= MAX_TOKENS)
157 token = malloc(sizeof(token_t));
159 Log_fatal("Out of memory");
160 init_list_entry(&token->node);
161 token->token = strdup(token_string);
162 if (token->token == NULL)
163 Log_fatal("Out of memory");
164 list_add_tail(&token->node, &client->tokens);
165 client->tokencount++;
168 bool_t Client_token_match(client_t *client, char *str)
173 if (list_empty(&client->tokens))
175 list_iterate(itr, &client->tokens) {
176 token = list_get_entry(itr, token_t, node);
177 if (strncasecmp(token->token, str, MAX_TOKENSIZE) == 0)
183 void Client_token_free(client_t *client)
185 struct dlist *itr, *save;
188 list_iterate_safe(itr, save, &client->tokens) {
189 token = list_get_entry(itr, token_t, node);
190 list_del(&token->node);
194 client->tokencount = 0;
197 void recheckCodecVersions()
199 client_t *client_itr = NULL;
200 int max = 0, version, current_version;
202 struct dlist codec_list, *itr, *save;
203 codec_t *codec_itr, *cd;
206 init_list_entry(&codec_list);
208 while (Client_iterate(&client_itr) != NULL) {
210 while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
212 list_iterate(itr, &codec_list) {
213 cd = list_get_entry(itr, codec_t, node);
214 if (cd->codec == codec_itr->codec) {
220 cd = malloc(sizeof(codec_t));
222 Log_fatal("Out of memory");
223 memset(cd, 0, sizeof(codec_t));
224 init_list_entry(&cd->node);
225 cd->codec = codec_itr->codec;
227 list_add_tail(&cd->node, &codec_list);
232 list_iterate(itr, &codec_list) {
233 cd = list_get_entry(itr, codec_t, node);
234 if (cd->count > max) {
239 list_iterate_safe(itr, save, &codec_list) {
240 list_del(&list_get_entry(itr, codec_t, node)->node);
241 free(list_get_entry(itr, codec_t, node));
244 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
245 if (current_version == version)
247 // If we don't already use the compat bitstream version set
248 // it as alpha and announce it. If another codec now got the
249 // majority set it as the opposite of the currently valid bPreferAlpha
251 if (version == (uint32_t)0x8000000b)
254 bPreferAlpha = ! bPreferAlpha;
257 iCodecAlpha = version;
259 iCodecBeta = version;
261 sendmsg = Msg_create(CodecVersion);
262 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
263 sendmsg->payload.codecVersion->beta = iCodecBeta;
264 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
265 Client_send_message_except(NULL, sendmsg);
267 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
268 bPreferAlpha ? iCodecAlpha : iCodecBeta);
272 static int findFreeSessionId()
275 client_t *itr = NULL;
277 for (id = 1; id < INT_MAX; id++) {
279 while ((itr = Client_iterate(&itr)) != NULL) {
280 if (itr->sessionId == id)
283 if (itr == NULL) /* Found free id */
289 int Client_add(int fd, struct sockaddr_in *remote)
294 if (Ban_isBannedAddr((in_addr_t *)&remote->sin_addr)) {
295 Log_info("Address %s banned. Disconnecting", inet_ntoa(remote->sin_addr));
298 newclient = malloc(sizeof(client_t));
299 if (newclient == NULL)
300 Log_fatal("Out of memory");
301 memset(newclient, 0, sizeof(client_t));
303 newclient->tcpfd = fd;
304 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
305 newclient->ssl = SSLi_newconnection(&newclient->tcpfd, &newclient->SSLready);
306 if (newclient->ssl == NULL) {
307 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
308 ntohs(remote->sin_port));
312 newclient->availableBandwidth = maxBandwidth;
313 Timer_init(&newclient->lastActivity);
314 Timer_init(&newclient->connectTime);
315 Timer_init(&newclient->idleTime);
316 newclient->sessionId = findFreeSessionId();
317 if (newclient->sessionId < 0)
318 Log_fatal("Could not find a free session ID");
320 init_list_entry(&newclient->txMsgQueue);
321 init_list_entry(&newclient->chan_node);
322 init_list_entry(&newclient->node);
323 init_list_entry(&newclient->voicetargets);
324 init_list_entry(&newclient->codecs);
325 init_list_entry(&newclient->tokens);
327 list_add_tail(&newclient->node, &clients);
330 /* Send version message to client */
331 sendmsg = Msg_create(Version);
332 sendmsg->payload.version->has_version = true;
333 sendmsg->payload.version->version = PROTOCOL_VERSION;
334 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
335 sendmsg->payload.version->os = strdup(system_string);
336 sendmsg->payload.version->os_version = strdup(version_string);
337 Client_send_message(newclient, sendmsg);
342 void Client_free(client_t *client)
344 struct dlist *itr, *save;
347 if (client->authenticated) {
349 leave_id = Chan_userLeave(client);
350 if (leave_id > 0) { /* Remove temp channel */
351 sendmsg = Msg_create(ChannelRemove);
352 sendmsg->payload.channelRemove->channel_id = leave_id;
353 Client_send_message_except(client, sendmsg);
355 sendmsg = Msg_create(UserRemove);
356 sendmsg->payload.userRemove->session = client->sessionId;
357 Client_send_message_except(client, sendmsg);
359 list_iterate_safe(itr, save, &client->txMsgQueue) {
360 list_del(&list_get_entry(itr, message_t, node)->node);
361 Msg_free(list_get_entry(itr, message_t, node));
363 Client_codec_free(client);
364 Voicetarget_free_all(client);
365 Client_token_free(client);
367 list_del(&client->node);
369 SSLi_free(client->ssl);
370 close(client->tcpfd);
373 free(client->release);
376 if (client->os_version)
377 free(client->os_version);
378 if (client->username)
379 free(client->username);
381 free(client->context);
385 void Client_close(client_t *client)
387 SSLi_shutdown(client->ssl);
388 client->shutdown_wait = true;
391 void Client_disconnect_all()
393 struct dlist *itr, *save;
395 list_iterate_safe(itr, save, &clients) {
396 Client_free(list_get_entry(itr, client_t, node));
400 int Client_read_fd(int fd)
403 client_t *client = NULL;
405 list_iterate(itr, &clients) {
406 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
407 client = list_get_entry(itr, client_t, node);
412 return Client_read(client);
417 int Client_read(client_t *client)
421 Timer_restart(&client->lastActivity);
423 if (client->writeBlockedOnRead) {
424 client->writeBlockedOnRead = false;
425 Log_debug("Client_read: writeBlockedOnRead == true");
426 return Client_write(client);
429 if (client->shutdown_wait) {
433 if (!client->SSLready) {
435 rc = SSLi_nonblockaccept(client->ssl, &client->SSLready);
444 if (!client->msgsize)
445 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
447 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
450 client->rxcount += rc;
451 if (!client->msgsize && client->rxcount >= 6) {
453 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
454 client->msgsize = ntohl(msgLen);
456 if (client->msgsize > BUFSIZE - 6) {
457 /* XXX - figure out how to handle this. A large size here can represent two cases:
458 * 1. A valid size. The only message that is this big is UserState message with a big texture
459 * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
461 Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
462 client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
465 /* client->rxcount = client->msgsize = 0; */
467 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
468 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
469 /* pass messsage to handler */
471 Mh_handle_message(client, msg);
472 client->rxcount = client->msgsize = 0;
474 } else /* rc <= 0 */ {
475 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
478 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
479 client->readBlockedOnWrite = true;
482 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN) {
483 Log_info_client(client, "Connection closed by peer");
484 if (!client->shutdown_wait)
485 Client_close(client);
488 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
489 Log_info_client(client,"Error: %s - Closing connection", strerror(errno));
491 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
492 Log_info_client(client, "Connection reset by peer");
495 Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
501 } while (SSLi_data_pending(client->ssl));
506 int Client_write_fd(int fd)
509 client_t *client = NULL;
511 list_iterate(itr, &clients) {
512 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
513 client = list_get_entry(itr, client_t, node);
518 return Client_write(client);
523 int Client_write(client_t *client)
527 if (client->readBlockedOnWrite) {
528 client->readBlockedOnWrite = false;
529 Log_debug("Client_write: readBlockedOnWrite == true");
530 return Client_read(client);
532 rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
534 client->txcount += rc;
535 if (client->txcount == client->txsize)
536 client->txsize = client->txcount = 0;
539 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
540 client->writeBlockedOnRead = true;
543 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
547 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
548 Log_info_client(client, "Error: %s - Closing connection", strerror(errno));
550 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
551 Log_info_client(client, "Connection reset by peer");
554 Log_info_client(client, "SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
560 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
562 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
563 list_del(list_get_first(&client->txMsgQueue));
564 client->txQueueCount--;
565 Client_send_message(client, msg);
570 int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
572 if ((version == 0) || (client->version >= version) ||
573 ((version & 0x80000000) && (client->version < (~version))))
574 return Client_send_message(client, msg);
579 int Client_send_message(client_t *client, message_t *msg)
581 if (!client->authenticated && msg->messageType != Version) {
585 if (client->txsize != 0 || !client->SSLready) {
587 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
588 client->txQueueCount > 30) {
592 client->txQueueCount++;
593 list_add_tail(&msg->node, &client->txMsgQueue);
594 Log_debug("Queueing message");
597 len = Msg_messageToNetwork(msg, client->txbuf);
598 doAssert(len < BUFSIZE);
600 client->txsize = len;
602 Client_write(client);
608 client_t *Client_iterate(client_t **client_itr)
610 client_t *c = *client_itr;
612 if (list_empty(&clients))
616 c = list_get_entry(list_get_first(&clients), client_t, node);
618 if (list_get_next(&c->node) == &clients)
621 c = list_get_entry(list_get_next(&c->node), client_t, node);
628 int Client_send_message_except(client_t *client, message_t *msg)
630 client_t *itr = NULL;
633 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
634 while (Client_iterate(&itr) != NULL) {
637 Msg_inc_ref(msg); /* One extra reference for each new copy */
638 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
639 Client_send_message(itr, msg);
642 Msg_free(msg); /* Free our reference to the message */
645 Msg_free(msg); /* If only 1 client is connected then no message is passed
646 * to Client_send_message(). Free it here. */
651 int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
653 client_t *itr = NULL;
656 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
657 while (Client_iterate(&itr) != NULL) {
660 Msg_inc_ref(msg); /* One extra reference for each new copy */
661 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
662 Client_send_message_ver(itr, msg, version);
665 Msg_free(msg); /* Free our reference to the message */
668 Msg_free(msg); /* If only 1 client is connected then no message is passed
669 * to Client_send_message(). Free it here. */
674 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
676 if (CryptState_isValid(&client->cryptState) &&
677 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
680 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
681 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
683 Timer_restart(&client->cryptState.tLastRequest);
685 sendmsg = Msg_create(CryptSetup);
686 Log_info_client(client, "Requesting voice channel crypt resync");
687 Client_send_message(client, sendmsg);
693 #define UDP_PACKET_SIZE 1024
694 int Client_read_udp()
697 struct sockaddr_in from;
698 socklen_t fromlen = sizeof(struct sockaddr_in);
701 UDPMessageType_t msgType;
703 #if defined(__LP64__)
704 uint8_t encbuff[UDP_PACKET_SIZE + 8];
705 uint8_t *encrypted = encbuff + 4;
707 uint8_t encrypted[UDP_PACKET_SIZE];
709 uint8_t buffer[UDP_PACKET_SIZE];
711 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
714 } else if (len < 0) {
716 } else if (len < 5) {
717 // 4 bytes crypt header + type + session
719 } else if (len > UDP_PACKET_SIZE) {
724 if (len == 12 && *encrypted == 0) {
725 uint32_t *ping = (uint32_t *)encrypted;
726 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
727 // 1 and 2 will be the timestamp, which we return unmodified.
728 ping[3] = htonl((uint32_t)clientcount);
729 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
730 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
732 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
736 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
739 while (Client_iterate(&itr) != NULL) {
740 if (itr->key == key) {
741 if (!checkDecrypt(itr, encrypted, buffer, len))
746 if (itr == NULL) { /* Unknown peer */
747 while (Client_iterate(&itr) != NULL) {
748 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
749 if (checkDecrypt(itr, encrypted, buffer, len)) {
751 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
752 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
758 if (itr == NULL) { /* Couldn't find this peer among connected clients */
763 len -= 4; /* Adjust for crypt header */
764 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
767 case UDPVoiceCELTAlpha:
768 case UDPVoiceCELTBeta:
769 Client_voiceMsg(itr, buffer, len);
772 Log_debug("UDP Ping reply len %d", len);
773 Client_send_udp(itr, buffer, len);
776 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
784 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
786 if (IS_AUTH(dst) && dst != src && !dst->deaf && !dst->self_deaf) {
787 if (poslen > 0 && /* Has positional data */
788 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
789 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
790 Client_send_udp(dst, data, len);
792 Client_send_udp(dst, data, len - poslen);
796 /* Handle decrypted voice message */
797 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
799 uint8_t buffer[UDP_PACKET_SIZE];
800 pds_t *pdi = Pds_create(data + 1, len - 1);
801 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
802 unsigned int type = data[0] & 0xe0;
803 unsigned int target = data[0] & 0x1f;
804 unsigned int poslen, counter;
805 int offset, packetsize;
808 channel_t *ch = (channel_t *)client->channel;
811 if (!client->authenticated || client->mute || client->self_mute)
814 packetsize = 20 + 8 + 4 + len;
815 if (client->availableBandwidth - packetsize < 0)
816 goto out; /* Discard */
817 client->availableBandwidth -= packetsize;
819 Timer_restart(&client->idleTime);
821 counter = Pds_get_numval(pdi); /* step past session id */
823 counter = Pds_next8(pdi);
824 offset = Pds_skip(pdi, counter & 0x7f);
825 } while ((counter & 0x80) && offset > 0);
827 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
829 Pds_add_numval(pds, client->sessionId);
830 Pds_append_data_nosize(pds, data + 1, len - 1);
832 if (target == 0x1f) { /* Loopback */
833 buffer[0] = (uint8_t) type;
834 Client_send_udp(client, buffer, pds->offset + 1);
836 else if (target == 0) { /* regular channel speech */
837 buffer[0] = (uint8_t) type;
842 list_iterate(itr, &ch->clients) {
844 c = list_get_entry(itr, client_t, chan_node);
845 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
847 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
851 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
852 buffer[0] = (uint8_t) (type | 1);
853 Log_debug("Whisper channel %d", vt->channels[i]);
854 ch = Chan_fromId(vt->channels[i].channel);
857 list_iterate(itr, &ch->clients) {
859 c = list_get_entry(itr, client_t, chan_node);
860 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
863 if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
864 struct dlist *ch_itr;
865 list_iterate(ch_itr, &ch->channel_links) {
867 ch_link = list_get_entry(ch_itr, channel_t, link_node);
868 list_iterate(itr, &ch_link->clients) {
870 c = list_get_entry(itr, client_t, chan_node);
871 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
872 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
877 if (vt->channels[i].children) {
878 struct dlist chanlist, *ch_itr;
879 init_list_entry(&chanlist);
880 Chan_buildTreeList(ch, &chanlist);
881 list_iterate(ch_itr, &chanlist) {
883 sub = list_get_entry(ch_itr, channellist_t, node)->chan;
884 list_iterate(itr, &sub->clients) {
886 c = list_get_entry(itr, client_t, chan_node);
887 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
888 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
891 Chan_freeTreeList(&chanlist);
895 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
897 buffer[0] = (uint8_t) (type | 2);
898 Log_debug("Whisper session %d", vt->sessions[i]);
899 while (Client_iterate(&c) != NULL) {
900 if (c->sessionId == vt->sessions[i]) {
901 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
915 static int Client_send_udp(client_t *client, uint8_t *data, int len)
919 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
921 #if defined(__LP64__)
922 buf = mbuf = malloc(len + 4 + 16);
925 mbuf = buf = malloc(len + 4);
928 Log_fatal("Out of memory");
930 CryptState_encrypt(&client->cryptState, data, buf, len);
932 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
937 msg = Msg_CreateVoiceMsg(data, len);
938 Client_send_message(client, msg);