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;
60 static bool_t bOpus = true;
62 int iCodecAlpha, iCodecBeta;
69 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
77 int Client_getfds(struct pollfd *pollfds)
81 list_iterate(itr, &clients) {
83 c = list_get_entry(itr, client_t, node);
84 pollfds[i].fd = c->tcpfd;
85 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
86 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
87 pollfds[i].events |= POLLOUT;
95 struct dlist *itr, *save;
96 int bwTop = maxBandwidth + maxBandwidth / 4;
97 list_iterate_safe(itr, save, &clients) {
99 c = list_get_entry(itr, client_t, node);
100 Log_debug("Client %s BW available %d", c->username, c->availableBandwidth);
101 c->availableBandwidth += maxBandwidth;
102 if (c->availableBandwidth > bwTop)
103 c->availableBandwidth = bwTop;
105 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTIVITY_TIMEOUT)) {
106 /* No activity from client - assume it is lost and close. */
107 Log_info_client(c, "Timeout, closing.");
114 void Client_codec_add(client_t *client, int codec)
116 codec_t *cd = malloc(sizeof(codec_t));
118 Log_fatal("Out of memory");
119 init_list_entry(&cd->node);
121 list_add_tail(&cd->node, &client->codecs);
124 void Client_codec_free(client_t *client)
126 struct dlist *itr, *save;
127 list_iterate_safe(itr, save, &client->codecs) {
128 list_del(&list_get_entry(itr, codec_t, node)->node);
129 free(list_get_entry(itr, codec_t, node));
133 codec_t *Client_codec_iterate(client_t *client, codec_t **codec_itr)
135 codec_t *cd = *codec_itr;
137 if (list_empty(&client->codecs))
141 cd = list_get_entry(list_get_first(&client->codecs), codec_t, node);
143 if (list_get_next(&cd->node) == &client->codecs)
146 cd = list_get_entry(list_get_next(&cd->node), codec_t, node);
152 void Client_token_add(client_t *client, char *token_string)
156 if (client->tokencount >= MAX_TOKENS)
158 token = malloc(sizeof(token_t));
160 Log_fatal("Out of memory");
161 init_list_entry(&token->node);
162 token->token = strdup(token_string);
163 if (token->token == NULL)
164 Log_fatal("Out of memory");
165 list_add_tail(&token->node, &client->tokens);
166 client->tokencount++;
169 bool_t Client_token_match(client_t *client, char *str)
174 if (list_empty(&client->tokens))
176 list_iterate(itr, &client->tokens) {
177 token = list_get_entry(itr, token_t, node);
178 if (strncasecmp(token->token, str, MAX_TOKENSIZE) == 0)
184 void Client_token_free(client_t *client)
186 struct dlist *itr, *save;
189 list_iterate_safe(itr, save, &client->tokens) {
190 token = list_get_entry(itr, token_t, node);
191 list_del(&token->node);
195 client->tokencount = 0;
199 #define OPUS_WARN "<strong>WARNING:</strong> Your client doesn't support the Opus codec the server is using, you won't be able to talk or hear anyone. Please upgrade"
200 void recheckCodecVersions(client_t *connectingClient)
202 client_t *client_itr = NULL;
203 int max = 0, version, current_version;
204 int users = 0, opus = 0;
206 struct dlist codec_list, *itr, *save;
207 codec_t *codec_itr, *cd;
211 init_list_entry(&codec_list);
213 while (Client_iterate(&client_itr) != NULL) {
215 while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
217 list_iterate(itr, &codec_list) {
218 cd = list_get_entry(itr, codec_t, node);
219 if (cd->codec == codec_itr->codec) {
225 cd = malloc(sizeof(codec_t));
227 Log_fatal("Out of memory");
228 memset(cd, 0, sizeof(codec_t));
229 init_list_entry(&cd->node);
230 cd->codec = codec_itr->codec;
232 list_add_tail(&cd->node, &codec_list);
235 if (client_itr->bOpus)
240 enableOpus = ((opus * 100 / users) >= getIntConf(OPUS_THRESHOLD));
242 list_iterate(itr, &codec_list) {
243 cd = list_get_entry(itr, codec_t, node);
244 if (cd->count > max) {
249 list_iterate_safe(itr, save, &codec_list) {
250 list_del(&list_get_entry(itr, codec_t, node)->node);
251 free(list_get_entry(itr, codec_t, node));
254 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
255 if (current_version != version) {
256 // If we don't already use the compat bitstream version set
257 // it as alpha and announce it. If another codec now got the
258 // majority set it as the opposite of the currently valid bPreferAlpha
260 if (version == (uint32_t)0x8000000b)
263 bPreferAlpha = !bPreferAlpha;
266 iCodecAlpha = version;
268 iCodecBeta = version;
269 } else if (bOpus == enableOpus) {
270 if (connectingClient && !connectingClient->bOpus) {
273 message_t *sendmsg = NULL;
275 message = malloc(strlen(OPUS_WARN));
277 Log_fatal("Out of memory");
278 tree_id = malloc(sizeof(uint32_t));
280 Log_fatal("Out of memory");
282 sendmsg = Msg_create(TextMessage);
283 sendmsg->payload.textMessage->message = message;
284 sendmsg->payload.textMessage->n_tree_id = 1;
285 sendmsg->payload.textMessage->tree_id = tree_id;
286 sprintf(message, OPUS_WARN);
287 Client_send_message(connectingClient, sendmsg);
295 sendmsg = Msg_create(CodecVersion);
296 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
297 sendmsg->payload.codecVersion->beta = iCodecBeta;
298 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
299 Client_send_message_except(NULL, sendmsg);
301 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
302 bPreferAlpha ? iCodecAlpha : iCodecBeta);
306 static int findFreeSessionId()
309 client_t *itr = NULL;
311 for (id = 1; id < INT_MAX; id++) {
313 while ((itr = Client_iterate(&itr)) != NULL) {
314 if (itr->sessionId == id)
317 if (itr == NULL) /* Found free id */
323 int Client_add(int fd, struct sockaddr_in *remote)
328 if (Ban_isBannedAddr((in_addr_t *)&remote->sin_addr)) {
329 Log_info("Address %s banned. Disconnecting", inet_ntoa(remote->sin_addr));
332 newclient = malloc(sizeof(client_t));
333 if (newclient == NULL)
334 Log_fatal("Out of memory");
335 memset(newclient, 0, sizeof(client_t));
337 newclient->tcpfd = fd;
338 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
339 newclient->ssl = SSLi_newconnection(&newclient->tcpfd, &newclient->SSLready);
340 if (newclient->ssl == NULL) {
341 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
342 ntohs(remote->sin_port));
346 newclient->availableBandwidth = maxBandwidth;
347 Timer_init(&newclient->lastActivity);
348 Timer_init(&newclient->connectTime);
349 Timer_init(&newclient->idleTime);
350 newclient->sessionId = findFreeSessionId();
351 if (newclient->sessionId < 0)
352 Log_fatal("Could not find a free session ID");
354 init_list_entry(&newclient->txMsgQueue);
355 init_list_entry(&newclient->chan_node);
356 init_list_entry(&newclient->node);
357 init_list_entry(&newclient->voicetargets);
358 init_list_entry(&newclient->codecs);
359 init_list_entry(&newclient->tokens);
361 list_add_tail(&newclient->node, &clients);
364 /* Send version message to client */
365 sendmsg = Msg_create(Version);
366 sendmsg->payload.version->has_version = true;
367 sendmsg->payload.version->version = PROTOCOL_VERSION;
368 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
369 sendmsg->payload.version->os = strdup(system_string);
370 sendmsg->payload.version->os_version = strdup(version_string);
371 Client_send_message(newclient, sendmsg);
376 void Client_free(client_t *client)
378 struct dlist *itr, *save;
381 if (client->authenticated) {
383 leave_id = Chan_userLeave(client);
384 if (leave_id > 0) { /* Remove temp channel */
385 sendmsg = Msg_create(ChannelRemove);
386 sendmsg->payload.channelRemove->channel_id = leave_id;
387 Client_send_message_except(client, sendmsg);
389 sendmsg = Msg_create(UserRemove);
390 sendmsg->payload.userRemove->session = client->sessionId;
391 Client_send_message_except(client, sendmsg);
393 list_iterate_safe(itr, save, &client->txMsgQueue) {
394 list_del(&list_get_entry(itr, message_t, node)->node);
395 Msg_free(list_get_entry(itr, message_t, node));
397 Client_codec_free(client);
398 Voicetarget_free_all(client);
399 Client_token_free(client);
401 list_del(&client->node);
403 SSLi_free(client->ssl);
404 close(client->tcpfd);
407 free(client->release);
410 if (client->os_version)
411 free(client->os_version);
412 if (client->username)
413 free(client->username);
415 free(client->context);
419 void Client_close(client_t *client)
421 SSLi_shutdown(client->ssl);
422 client->shutdown_wait = true;
425 void Client_disconnect_all()
427 struct dlist *itr, *save;
429 list_iterate_safe(itr, save, &clients) {
430 Client_free(list_get_entry(itr, client_t, node));
434 int Client_read_fd(int fd)
437 client_t *client = NULL;
439 list_iterate(itr, &clients) {
440 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
441 client = list_get_entry(itr, client_t, node);
446 return Client_read(client);
451 int Client_read(client_t *client)
455 Timer_restart(&client->lastActivity);
457 if (client->writeBlockedOnRead) {
458 client->writeBlockedOnRead = false;
459 Log_debug("Client_read: writeBlockedOnRead == true");
460 return Client_write(client);
463 if (client->shutdown_wait) {
467 if (!client->SSLready) {
469 rc = SSLi_nonblockaccept(client->ssl, &client->SSLready);
478 if (!client->msgsize)
479 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
481 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
484 client->rxcount += rc;
485 if (!client->msgsize && client->rxcount >= 6) {
487 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
488 client->msgsize = ntohl(msgLen);
490 if (client->msgsize > BUFSIZE - 6) {
491 /* XXX - figure out how to handle this. A large size here can represent two cases:
492 * 1. A valid size. The only message that is this big is UserState message with a big texture
493 * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
495 Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
496 client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
499 /* client->rxcount = client->msgsize = 0; */
501 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
502 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
503 /* pass messsage to handler */
505 Mh_handle_message(client, msg);
506 client->rxcount = client->msgsize = 0;
508 } else /* rc <= 0 */ {
509 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
512 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
513 client->readBlockedOnWrite = true;
516 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN) {
517 Log_info_client(client, "Connection closed by peer");
518 if (!client->shutdown_wait)
519 Client_close(client);
522 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
523 Log_info_client(client,"Error: %s - Closing connection", strerror(errno));
525 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
526 Log_info_client(client, "Connection reset by peer");
529 Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
535 } while (SSLi_data_pending(client->ssl));
540 int Client_write_fd(int fd)
543 client_t *client = NULL;
545 list_iterate(itr, &clients) {
546 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
547 client = list_get_entry(itr, client_t, node);
552 return Client_write(client);
557 int Client_write(client_t *client)
561 if (client->readBlockedOnWrite) {
562 client->readBlockedOnWrite = false;
563 Log_debug("Client_write: readBlockedOnWrite == true");
564 return Client_read(client);
566 rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
568 client->txcount += rc;
569 if (client->txcount == client->txsize)
570 client->txsize = client->txcount = 0;
573 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
574 client->writeBlockedOnRead = true;
577 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
581 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
582 Log_info_client(client, "Error: %s - Closing connection", strerror(errno));
584 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
585 Log_info_client(client, "Connection reset by peer");
588 Log_info_client(client, "SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
594 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
596 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
597 list_del(list_get_first(&client->txMsgQueue));
598 client->txQueueCount--;
599 Client_send_message(client, msg);
604 int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
606 if ((version == 0) || (client->version >= version) ||
607 ((version & 0x80000000) && (client->version < (~version))))
608 return Client_send_message(client, msg);
613 int Client_send_message(client_t *client, message_t *msg)
615 if (!client->authenticated && msg->messageType != Version) {
619 if (client->txsize != 0 || !client->SSLready) {
621 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
622 client->txQueueCount > 30) {
626 client->txQueueCount++;
627 list_add_tail(&msg->node, &client->txMsgQueue);
628 Log_debug("Queueing message");
631 len = Msg_messageToNetwork(msg, client->txbuf);
632 doAssert(len < BUFSIZE);
634 client->txsize = len;
636 Client_write(client);
642 client_t *Client_iterate(client_t **client_itr)
644 client_t *c = *client_itr;
646 if (list_empty(&clients))
650 c = list_get_entry(list_get_first(&clients), client_t, node);
652 if (list_get_next(&c->node) == &clients)
655 c = list_get_entry(list_get_next(&c->node), client_t, node);
662 int Client_send_message_except(client_t *client, message_t *msg)
664 client_t *itr = NULL;
667 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
668 while (Client_iterate(&itr) != NULL) {
671 Msg_inc_ref(msg); /* One extra reference for each new copy */
672 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
673 Client_send_message(itr, msg);
676 Msg_free(msg); /* Free our reference to the message */
679 Msg_free(msg); /* If only 1 client is connected then no message is passed
680 * to Client_send_message(). Free it here. */
685 int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
687 client_t *itr = NULL;
690 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
691 while (Client_iterate(&itr) != NULL) {
694 Msg_inc_ref(msg); /* One extra reference for each new copy */
695 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
696 Client_send_message_ver(itr, msg, version);
699 Msg_free(msg); /* Free our reference to the message */
702 Msg_free(msg); /* If only 1 client is connected then no message is passed
703 * to Client_send_message(). Free it here. */
708 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
710 if (CryptState_isValid(&client->cryptState) &&
711 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
714 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
715 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
717 Timer_restart(&client->cryptState.tLastRequest);
719 sendmsg = Msg_create(CryptSetup);
720 Log_info_client(client, "Requesting voice channel crypt resync");
721 Client_send_message(client, sendmsg);
727 #define UDP_PACKET_SIZE 1024
728 int Client_read_udp()
731 struct sockaddr_in from;
732 socklen_t fromlen = sizeof(struct sockaddr_in);
735 UDPMessageType_t msgType;
737 #if defined(__LP64__)
738 uint8_t encbuff[UDP_PACKET_SIZE + 8];
739 uint8_t *encrypted = encbuff + 4;
741 uint8_t encrypted[UDP_PACKET_SIZE];
743 uint8_t buffer[UDP_PACKET_SIZE];
745 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
748 } else if (len < 0) {
750 } else if (len < 5) {
751 // 4 bytes crypt header + type + session
753 } else if (len > UDP_PACKET_SIZE) {
758 if (len == 12 && *encrypted == 0) {
759 uint32_t *ping = (uint32_t *)encrypted;
760 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
761 // 1 and 2 will be the timestamp, which we return unmodified.
762 ping[3] = htonl((uint32_t)clientcount);
763 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
764 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
766 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
770 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
773 while (Client_iterate(&itr) != NULL) {
774 if (itr->key == key) {
775 if (!checkDecrypt(itr, encrypted, buffer, len))
780 if (itr == NULL) { /* Unknown peer */
781 while (Client_iterate(&itr) != NULL) {
782 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
783 if (checkDecrypt(itr, encrypted, buffer, len)) {
785 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
786 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
792 if (itr == NULL) { /* Couldn't find this peer among connected clients */
797 len -= 4; /* Adjust for crypt header */
798 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
801 case UDPVoiceCELTAlpha:
802 case UDPVoiceCELTBeta:
806 Client_voiceMsg(itr, buffer, len);
809 Log_debug("UDP Ping reply len %d", len);
810 Client_send_udp(itr, buffer, len);
813 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
821 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
823 if (IS_AUTH(dst) && dst != src && !dst->deaf && !dst->self_deaf) {
824 if (poslen > 0 && /* Has positional data */
825 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
826 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
827 Client_send_udp(dst, data, len);
829 Client_send_udp(dst, data, len - poslen);
833 /* Handle decrypted voice message */
834 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
836 uint8_t buffer[UDP_PACKET_SIZE];
837 pds_t *pdi = Pds_create(data + 1, len - 1);
838 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
839 unsigned int type = data[0] & 0xe0;
840 unsigned int target = data[0] & 0x1f;
841 unsigned int poslen, counter, size;
842 int offset, packetsize;
845 channel_t *ch = (channel_t *)client->channel;
848 if (!client->authenticated || client->mute || client->self_mute)
851 packetsize = 20 + 8 + 4 + len;
852 if (client->availableBandwidth - packetsize < 0)
853 goto out; /* Discard */
854 client->availableBandwidth -= packetsize;
856 Timer_restart(&client->idleTime);
857 Timer_restart(&client->lastActivity);
859 if ((type >> 5) != UDPVoiceOpus) {
860 counter = Pds_get_numval(pdi); /* step past session id */
862 counter = Pds_next8(pdi);
863 offset = Pds_skip(pdi, counter & 0x7f);
864 } while ((counter & 0x80) && offset > 0);
866 size = Pds_get_numval(pdi);
867 Pds_skip(pdi, size & 0x1fff);
870 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
872 Pds_add_numval(pds, client->sessionId);
873 Pds_append_data_nosize(pds, data + 1, len - 1);
875 if (target == 0x1f) { /* Loopback */
876 buffer[0] = (uint8_t) type;
877 Client_send_udp(client, buffer, pds->offset + 1);
879 else if (target == 0) { /* regular channel speech */
880 buffer[0] = (uint8_t) type;
885 list_iterate(itr, &ch->clients) {
887 c = list_get_entry(itr, client_t, chan_node);
888 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
890 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
894 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
895 buffer[0] = (uint8_t) (type | 1);
896 Log_debug("Whisper channel %d", vt->channels[i]);
897 ch = Chan_fromId(vt->channels[i].channel);
900 list_iterate(itr, &ch->clients) {
902 c = list_get_entry(itr, client_t, chan_node);
903 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
906 if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
907 struct dlist *ch_itr;
908 list_iterate(ch_itr, &ch->channel_links) {
910 ch_link = list_get_entry(ch_itr, channel_t, link_node);
911 list_iterate(itr, &ch_link->clients) {
913 c = list_get_entry(itr, client_t, chan_node);
914 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
915 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
920 if (vt->channels[i].children) {
921 struct dlist chanlist, *ch_itr;
922 init_list_entry(&chanlist);
923 Chan_buildTreeList(ch, &chanlist);
924 list_iterate(ch_itr, &chanlist) {
926 sub = list_get_entry(ch_itr, channellist_t, node)->chan;
927 list_iterate(itr, &sub->clients) {
929 c = list_get_entry(itr, client_t, chan_node);
930 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
931 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
934 Chan_freeTreeList(&chanlist);
938 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
940 buffer[0] = (uint8_t) (type | 2);
941 Log_debug("Whisper session %d", vt->sessions[i]);
942 while (Client_iterate(&c) != NULL) {
943 if (c->sessionId == vt->sessions[i]) {
944 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
958 static int Client_send_udp(client_t *client, uint8_t *data, int len)
962 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
964 #if defined(__LP64__)
965 buf = mbuf = malloc(len + 4 + 16);
968 mbuf = buf = malloc(len + 4);
971 Log_fatal("Out of memory");
973 CryptState_encrypt(&client->cryptState, data, buf, len);
975 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
980 msg = Msg_CreateVoiceMsg(data, len);
981 Client_send_message(client, msg);