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, "Connection closed by peer");
492 Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
498 } while (SSLi_data_pending(client->ssl));
503 int Client_write_fd(int fd)
506 client_t *client = NULL;
508 list_iterate(itr, &clients) {
509 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
510 client = list_get_entry(itr, client_t, node);
515 return Client_write(client);
520 int Client_write(client_t *client)
524 if (client->readBlockedOnWrite) {
525 client->readBlockedOnWrite = false;
526 Log_debug("Client_write: readBlockedOnWrite == true");
527 return Client_read(client);
529 rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
531 client->txcount += rc;
532 if (client->txcount == client->txsize)
533 client->txsize = client->txcount = 0;
536 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
537 client->writeBlockedOnRead = true;
540 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
544 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL)
545 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
547 Log_warn("Client_write: SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
552 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
554 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
555 list_del(list_get_first(&client->txMsgQueue));
556 client->txQueueCount--;
557 Client_send_message(client, msg);
562 int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
564 if ((version == 0) || (client->version >= version) ||
565 ((version & 0x80000000) && (client->version < (~version))))
566 return Client_send_message(client, msg);
571 int Client_send_message(client_t *client, message_t *msg)
573 if (!client->authenticated && msg->messageType != Version) {
577 if (client->txsize != 0 || !client->SSLready) {
579 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
580 client->txQueueCount > 30) {
584 client->txQueueCount++;
585 list_add_tail(&msg->node, &client->txMsgQueue);
586 Log_debug("Queueing message");
589 len = Msg_messageToNetwork(msg, client->txbuf);
590 doAssert(len < BUFSIZE);
592 client->txsize = len;
594 Client_write(client);
600 client_t *Client_iterate(client_t **client_itr)
602 client_t *c = *client_itr;
604 if (list_empty(&clients))
608 c = list_get_entry(list_get_first(&clients), client_t, node);
610 if (list_get_next(&c->node) == &clients)
613 c = list_get_entry(list_get_next(&c->node), client_t, node);
620 int Client_send_message_except(client_t *client, message_t *msg)
622 client_t *itr = NULL;
625 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
626 while (Client_iterate(&itr) != NULL) {
629 Msg_inc_ref(msg); /* One extra reference for each new copy */
630 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
631 Client_send_message(itr, msg);
634 Msg_free(msg); /* Free our reference to the message */
637 Msg_free(msg); /* If only 1 client is connected then no message is passed
638 * to Client_send_message(). Free it here. */
643 int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
645 client_t *itr = NULL;
648 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
649 while (Client_iterate(&itr) != NULL) {
652 Msg_inc_ref(msg); /* One extra reference for each new copy */
653 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
654 Client_send_message_ver(itr, msg, version);
657 Msg_free(msg); /* Free our reference to the message */
660 Msg_free(msg); /* If only 1 client is connected then no message is passed
661 * to Client_send_message(). Free it here. */
666 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
668 if (CryptState_isValid(&client->cryptState) &&
669 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
672 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
673 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
675 Timer_restart(&client->cryptState.tLastRequest);
677 sendmsg = Msg_create(CryptSetup);
678 Log_info_client(client, "Requesting voice channel crypt resync");
679 Client_send_message(client, sendmsg);
685 #define UDP_PACKET_SIZE 1024
686 int Client_read_udp()
689 struct sockaddr_in from;
690 socklen_t fromlen = sizeof(struct sockaddr_in);
693 UDPMessageType_t msgType;
695 #if defined(__LP64__)
696 uint8_t encbuff[UDP_PACKET_SIZE + 8];
697 uint8_t *encrypted = encbuff + 4;
699 uint8_t encrypted[UDP_PACKET_SIZE];
701 uint8_t buffer[UDP_PACKET_SIZE];
703 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
706 } else if (len < 0) {
708 } else if (len < 5) {
709 // 4 bytes crypt header + type + session
711 } else if (len > UDP_PACKET_SIZE) {
716 if (len == 12 && *encrypted == 0) {
717 uint32_t *ping = (uint32_t *)encrypted;
718 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
719 // 1 and 2 will be the timestamp, which we return unmodified.
720 ping[3] = htonl((uint32_t)clientcount);
721 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
722 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
724 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
728 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
731 while (Client_iterate(&itr) != NULL) {
732 if (itr->key == key) {
733 if (!checkDecrypt(itr, encrypted, buffer, len))
738 if (itr == NULL) { /* Unknown peer */
739 while (Client_iterate(&itr) != NULL) {
740 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
741 if (checkDecrypt(itr, encrypted, buffer, len)) {
743 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
744 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
750 if (itr == NULL) { /* Couldn't find this peer among connected clients */
755 len -= 4; /* Adjust for crypt header */
756 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
759 case UDPVoiceCELTAlpha:
760 case UDPVoiceCELTBeta:
761 Client_voiceMsg(itr, buffer, len);
764 Log_debug("UDP Ping reply len %d", len);
765 Client_send_udp(itr, buffer, len);
768 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
776 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
778 if (IS_AUTH(dst) && dst != src && !dst->deaf && !dst->self_deaf) {
779 if (poslen > 0 && /* Has positional data */
780 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
781 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
782 Client_send_udp(dst, data, len);
784 Client_send_udp(dst, data, len - poslen);
788 /* Handle decrypted voice message */
789 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
791 uint8_t buffer[UDP_PACKET_SIZE];
792 pds_t *pdi = Pds_create(data + 1, len - 1);
793 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
794 unsigned int type = data[0] & 0xe0;
795 unsigned int target = data[0] & 0x1f;
796 unsigned int poslen, counter;
797 int offset, packetsize;
800 channel_t *ch = (channel_t *)client->channel;
803 if (!client->authenticated || client->mute || client->self_mute)
806 packetsize = 20 + 8 + 4 + len;
807 if (client->availableBandwidth - packetsize < 0)
808 goto out; /* Discard */
809 client->availableBandwidth -= packetsize;
811 Timer_restart(&client->idleTime);
813 counter = Pds_get_numval(pdi); /* step past session id */
815 counter = Pds_next8(pdi);
816 offset = Pds_skip(pdi, counter & 0x7f);
817 } while ((counter & 0x80) && offset > 0);
819 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
821 Pds_add_numval(pds, client->sessionId);
822 Pds_append_data_nosize(pds, data + 1, len - 1);
824 if (target == 0x1f) { /* Loopback */
825 buffer[0] = (uint8_t) type;
826 Client_send_udp(client, buffer, pds->offset + 1);
828 else if (target == 0) { /* regular channel speech */
829 buffer[0] = (uint8_t) type;
834 list_iterate(itr, &ch->clients) {
836 c = list_get_entry(itr, client_t, chan_node);
837 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
839 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
843 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
844 buffer[0] = (uint8_t) (type | 1);
845 Log_debug("Whisper channel %d", vt->channels[i]);
846 ch = Chan_fromId(vt->channels[i].channel);
849 list_iterate(itr, &ch->clients) {
851 c = list_get_entry(itr, client_t, chan_node);
852 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
855 if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
856 struct dlist *ch_itr;
857 list_iterate(ch_itr, &ch->channel_links) {
859 ch_link = list_get_entry(ch_itr, channel_t, link_node);
860 list_iterate(itr, &ch_link->clients) {
862 c = list_get_entry(itr, client_t, chan_node);
863 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
864 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
869 if (vt->channels[i].children) {
870 struct dlist chanlist, *ch_itr;
871 init_list_entry(&chanlist);
872 Chan_buildTreeList(ch, &chanlist);
873 list_iterate(ch_itr, &chanlist) {
875 sub = list_get_entry(ch_itr, channellist_t, node)->chan;
876 list_iterate(itr, &sub->clients) {
878 c = list_get_entry(itr, client_t, chan_node);
879 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
880 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
883 Chan_freeTreeList(&chanlist);
887 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
889 buffer[0] = (uint8_t) (type | 2);
890 Log_debug("Whisper session %d", vt->sessions[i]);
891 while (Client_iterate(&c) != NULL) {
892 if (c->sessionId == vt->sessions[i]) {
893 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
907 static int Client_send_udp(client_t *client, uint8_t *data, int len)
911 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
913 #if defined(__LP64__)
914 buf = mbuf = malloc(len + 4 + 16);
917 mbuf = buf = malloc(len + 4);
920 Log_fatal("Out of memory");
922 CryptState_encrypt(&client->cryptState, data, buf, len);
924 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
929 msg = Msg_CreateVoiceMsg(data, len);
930 Client_send_message(client, msg);