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;
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 if (client_itr->codec_count == 0 && !client_itr->bOpus)
217 while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
219 list_iterate(itr, &codec_list) {
220 cd = list_get_entry(itr, codec_t, node);
221 if (cd->codec == codec_itr->codec) {
227 cd = malloc(sizeof(codec_t));
229 Log_fatal("Out of memory");
230 memset(cd, 0, sizeof(codec_t));
231 init_list_entry(&cd->node);
232 cd->codec = codec_itr->codec;
234 list_add_tail(&cd->node, &codec_list);
238 if (client_itr->bOpus)
245 enableOpus = ((opus * 100 / users) >= getIntConf(OPUS_THRESHOLD));
247 list_iterate(itr, &codec_list) {
248 cd = list_get_entry(itr, codec_t, node);
249 if (cd->count > max) {
254 list_iterate_safe(itr, save, &codec_list) {
255 list_del(&list_get_entry(itr, codec_t, node)->node);
256 free(list_get_entry(itr, codec_t, node));
259 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
260 if (current_version != version) {
261 // If we don't already use the compat bitstream version set
262 // it as alpha and announce it. If another codec now got the
263 // majority set it as the opposite of the currently valid bPreferAlpha
265 if (version == (uint32_t)0x8000000b)
268 bPreferAlpha = !bPreferAlpha;
271 iCodecAlpha = version;
273 iCodecBeta = version;
274 } else if (bOpus == enableOpus) {
275 if (connectingClient && !connectingClient->bOpus) {
278 message_t *sendmsg = NULL;
280 message = malloc(strlen(OPUS_WARN) + 1);
282 Log_fatal("Out of memory");
283 tree_id = malloc(sizeof(uint32_t));
285 Log_fatal("Out of memory");
287 sendmsg = Msg_create(TextMessage);
288 sendmsg->payload.textMessage->message = message;
289 sendmsg->payload.textMessage->n_tree_id = 1;
290 sendmsg->payload.textMessage->tree_id = tree_id;
291 sprintf(message, OPUS_WARN);
292 Client_send_message(connectingClient, sendmsg);
299 Log_info("OPUS codec is %s", bOpus ? "enabled" : "disabled");
301 sendmsg = Msg_create(CodecVersion);
302 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
303 sendmsg->payload.codecVersion->beta = iCodecBeta;
304 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
305 sendmsg->payload.codecVersion->has_opus = true;
306 sendmsg->payload.codecVersion->opus = bOpus;
308 Client_send_message_except(NULL, sendmsg);
310 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
311 bPreferAlpha ? iCodecAlpha : iCodecBeta);
314 while (Client_iterate(&client_itr) != NULL) {
315 if ((client_itr->authenticated || client_itr == connectingClient) &&
316 !client_itr->bOpus) {
319 message_t *sendmsg = NULL;
321 message = malloc(strlen(OPUS_WARN) + 1);
323 Log_fatal("Out of memory");
324 tree_id = malloc(sizeof(uint32_t));
326 Log_fatal("Out of memory");
328 sendmsg = Msg_create(TextMessage);
329 sendmsg->payload.textMessage->message = message;
330 sendmsg->payload.textMessage->n_tree_id = 1;
331 sendmsg->payload.textMessage->tree_id = tree_id;
332 sprintf(message, OPUS_WARN);
333 Client_send_message(client_itr, sendmsg);
340 static int findFreeSessionId()
343 client_t *itr = NULL;
345 for (id = 1; id < INT_MAX; id++) {
347 while ((itr = Client_iterate(&itr)) != NULL) {
348 if (itr->sessionId == id)
351 if (itr == NULL) /* Found free id */
357 int Client_add(int fd, struct sockaddr_in *remote)
362 if (Ban_isBannedAddr((in_addr_t *)&remote->sin_addr)) {
363 Log_info("Address %s banned. Disconnecting", inet_ntoa(remote->sin_addr));
366 newclient = malloc(sizeof(client_t));
367 if (newclient == NULL)
368 Log_fatal("Out of memory");
369 memset(newclient, 0, sizeof(client_t));
371 newclient->tcpfd = fd;
372 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
373 newclient->ssl = SSLi_newconnection(&newclient->tcpfd, &newclient->SSLready);
374 if (newclient->ssl == NULL) {
375 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
376 ntohs(remote->sin_port));
380 newclient->availableBandwidth = maxBandwidth;
381 Timer_init(&newclient->lastActivity);
382 Timer_init(&newclient->connectTime);
383 Timer_init(&newclient->idleTime);
384 newclient->sessionId = findFreeSessionId();
385 if (newclient->sessionId < 0)
386 Log_fatal("Could not find a free session ID");
388 init_list_entry(&newclient->txMsgQueue);
389 init_list_entry(&newclient->chan_node);
390 init_list_entry(&newclient->node);
391 init_list_entry(&newclient->voicetargets);
392 init_list_entry(&newclient->codecs);
393 init_list_entry(&newclient->tokens);
395 list_add_tail(&newclient->node, &clients);
398 /* Send version message to client */
399 sendmsg = Msg_create(Version);
400 sendmsg->payload.version->has_version = true;
401 sendmsg->payload.version->version = PROTOCOL_VERSION;
402 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
403 sendmsg->payload.version->os = strdup(system_string);
404 sendmsg->payload.version->os_version = strdup(version_string);
405 Client_send_message(newclient, sendmsg);
410 void Client_free(client_t *client)
412 struct dlist *itr, *save;
415 if (client->authenticated) {
417 leave_id = Chan_userLeave(client);
418 if (leave_id > 0) { /* Remove temp channel */
419 sendmsg = Msg_create(ChannelRemove);
420 sendmsg->payload.channelRemove->channel_id = leave_id;
421 Client_send_message_except(client, sendmsg);
423 sendmsg = Msg_create(UserRemove);
424 sendmsg->payload.userRemove->session = client->sessionId;
425 Client_send_message_except(client, sendmsg);
426 recheckCodecVersions(NULL); /* Can use better codec now? */
428 list_iterate_safe(itr, save, &client->txMsgQueue) {
429 list_del(&list_get_entry(itr, message_t, node)->node);
430 Msg_free(list_get_entry(itr, message_t, node));
432 Client_codec_free(client);
433 Voicetarget_free_all(client);
434 Client_token_free(client);
436 list_del(&client->node);
438 SSLi_free(client->ssl);
439 close(client->tcpfd);
442 free(client->release);
445 if (client->os_version)
446 free(client->os_version);
447 if (client->username)
448 free(client->username);
450 free(client->context);
454 void Client_close(client_t *client)
456 SSLi_shutdown(client->ssl);
457 client->shutdown_wait = true;
460 void Client_disconnect_all()
462 struct dlist *itr, *save;
464 list_iterate_safe(itr, save, &clients) {
465 Client_free(list_get_entry(itr, client_t, node));
469 int Client_read_fd(int fd)
472 client_t *client = NULL;
474 list_iterate(itr, &clients) {
475 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
476 client = list_get_entry(itr, client_t, node);
481 return Client_read(client);
486 int Client_read(client_t *client)
490 Timer_restart(&client->lastActivity);
492 if (client->writeBlockedOnRead) {
493 client->writeBlockedOnRead = false;
494 Log_debug("Client_read: writeBlockedOnRead == true");
495 return Client_write(client);
498 if (client->shutdown_wait) {
502 if (!client->SSLready) {
504 rc = SSLi_nonblockaccept(client->ssl, &client->SSLready);
513 if (!client->msgsize)
514 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
516 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
519 client->rxcount += rc;
520 if (!client->msgsize && client->rxcount >= 6) {
522 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
523 client->msgsize = ntohl(msgLen);
525 if (client->msgsize > BUFSIZE - 6) {
526 /* XXX - figure out how to handle this. A large size here can represent two cases:
527 * 1. A valid size. The only message that is this big is UserState message with a big texture
528 * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
530 Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
531 client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
534 /* client->rxcount = client->msgsize = 0; */
536 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
537 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
538 /* pass messsage to handler */
540 Mh_handle_message(client, msg);
541 client->rxcount = client->msgsize = 0;
543 } else /* rc <= 0 */ {
544 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
547 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
548 client->readBlockedOnWrite = true;
551 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN) {
552 Log_info_client(client, "Connection closed by peer");
553 if (!client->shutdown_wait)
554 Client_close(client);
557 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
558 Log_info_client(client,"Error: %s - Closing connection", strerror(errno));
560 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
561 Log_info_client(client, "Connection reset by peer");
564 Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
570 } while (SSLi_data_pending(client->ssl));
575 int Client_write_fd(int fd)
578 client_t *client = NULL;
580 list_iterate(itr, &clients) {
581 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
582 client = list_get_entry(itr, client_t, node);
587 return Client_write(client);
592 int Client_write(client_t *client)
596 if (client->readBlockedOnWrite) {
597 client->readBlockedOnWrite = false;
598 Log_debug("Client_write: readBlockedOnWrite == true");
599 return Client_read(client);
601 rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
603 client->txcount += rc;
604 if (client->txcount == client->txsize)
605 client->txsize = client->txcount = 0;
608 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
609 client->writeBlockedOnRead = true;
612 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
616 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
617 Log_info_client(client, "Error: %s - Closing connection", strerror(errno));
619 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
620 Log_info_client(client, "Connection reset by peer");
623 Log_info_client(client, "SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
629 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
631 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
632 list_del(list_get_first(&client->txMsgQueue));
633 client->txQueueCount--;
634 Client_send_message(client, msg);
639 int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
641 if ((version == 0) || (client->version >= version) ||
642 ((version & 0x80000000) && (client->version < (~version))))
643 return Client_send_message(client, msg);
648 int Client_send_message(client_t *client, message_t *msg)
650 if (!client->authenticated && msg->messageType != Version) {
654 if (client->txsize != 0 || !client->SSLready) {
656 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
657 client->txQueueCount > 30) {
661 client->txQueueCount++;
662 list_add_tail(&msg->node, &client->txMsgQueue);
663 Log_debug("Queueing message");
666 len = Msg_messageToNetwork(msg, client->txbuf);
667 doAssert(len < BUFSIZE);
669 client->txsize = len;
671 Client_write(client);
677 client_t *Client_iterate(client_t **client_itr)
679 client_t *c = *client_itr;
681 if (list_empty(&clients))
685 c = list_get_entry(list_get_first(&clients), client_t, node);
687 if (list_get_next(&c->node) == &clients)
690 c = list_get_entry(list_get_next(&c->node), client_t, node);
697 int Client_send_message_except(client_t *client, message_t *msg)
699 client_t *itr = NULL;
702 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
703 while (Client_iterate(&itr) != NULL) {
706 Msg_inc_ref(msg); /* One extra reference for each new copy */
707 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
708 Client_send_message(itr, msg);
711 Msg_free(msg); /* Free our reference to the message */
714 Msg_free(msg); /* If only 1 client is connected then no message is passed
715 * to Client_send_message(). Free it here. */
720 int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
722 client_t *itr = NULL;
725 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
726 while (Client_iterate(&itr) != NULL) {
729 Msg_inc_ref(msg); /* One extra reference for each new copy */
730 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
731 Client_send_message_ver(itr, msg, version);
734 Msg_free(msg); /* Free our reference to the message */
737 Msg_free(msg); /* If only 1 client is connected then no message is passed
738 * to Client_send_message(). Free it here. */
743 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
745 if (CryptState_isValid(&client->cryptState) &&
746 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
749 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
750 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
752 Timer_restart(&client->cryptState.tLastRequest);
754 sendmsg = Msg_create(CryptSetup);
755 Log_info_client(client, "Requesting voice channel crypt resync");
756 Client_send_message(client, sendmsg);
762 #define UDP_PACKET_SIZE 1024
763 int Client_read_udp()
766 struct sockaddr_in from;
767 socklen_t fromlen = sizeof(struct sockaddr_in);
770 UDPMessageType_t msgType;
772 #if defined(__LP64__)
773 uint8_t encbuff[UDP_PACKET_SIZE + 8];
774 uint8_t *encrypted = encbuff + 4;
776 uint8_t encrypted[UDP_PACKET_SIZE];
778 uint8_t buffer[UDP_PACKET_SIZE];
780 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
783 } else if (len < 0) {
785 } else if (len < 5) {
786 // 4 bytes crypt header + type + session
788 } else if (len > UDP_PACKET_SIZE) {
793 if (len == 12 && *encrypted == 0) {
794 uint32_t *ping = (uint32_t *)encrypted;
795 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
796 // 1 and 2 will be the timestamp, which we return unmodified.
797 ping[3] = htonl((uint32_t)clientcount);
798 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
799 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
801 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
805 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
808 while (Client_iterate(&itr) != NULL) {
809 if (itr->key == key) {
810 if (!checkDecrypt(itr, encrypted, buffer, len))
815 if (itr == NULL) { /* Unknown peer */
816 while (Client_iterate(&itr) != NULL) {
817 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
818 if (checkDecrypt(itr, encrypted, buffer, len)) {
820 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
821 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
827 if (itr == NULL) { /* Couldn't find this peer among connected clients */
832 len -= 4; /* Adjust for crypt header */
833 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
836 case UDPVoiceCELTAlpha:
837 case UDPVoiceCELTBeta:
841 Client_voiceMsg(itr, buffer, len);
844 Log_debug("UDP Ping reply len %d", len);
845 Client_send_udp(itr, buffer, len);
848 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
856 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
858 if (IS_AUTH(dst) && dst != src && !dst->deaf && !dst->self_deaf) {
859 if (poslen > 0 && /* Has positional data */
860 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
861 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
862 Client_send_udp(dst, data, len);
864 Client_send_udp(dst, data, len - poslen);
868 /* Handle decrypted voice message */
869 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
871 uint8_t buffer[UDP_PACKET_SIZE];
872 pds_t *pdi = Pds_create(data + 1, len - 1);
873 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
874 unsigned int type = data[0] & 0xe0;
875 unsigned int target = data[0] & 0x1f;
876 unsigned int poslen, counter, size;
877 int offset, packetsize;
880 channel_t *ch = (channel_t *)client->channel;
883 if (!client->authenticated || client->mute || client->self_mute)
886 packetsize = 20 + 8 + 4 + len;
887 if (client->availableBandwidth - packetsize < 0)
888 goto out; /* Discard */
889 client->availableBandwidth -= packetsize;
891 Timer_restart(&client->idleTime);
892 Timer_restart(&client->lastActivity);
894 if ((type >> 5) != UDPVoiceOpus) {
895 counter = Pds_get_numval(pdi); /* step past session id */
897 counter = Pds_next8(pdi);
898 offset = Pds_skip(pdi, counter & 0x7f);
899 } while ((counter & 0x80) && offset > 0);
901 size = Pds_get_numval(pdi);
902 Pds_skip(pdi, size & 0x1fff);
905 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
907 Pds_add_numval(pds, client->sessionId);
908 Pds_append_data_nosize(pds, data + 1, len - 1);
910 if (target == 0x1f) { /* Loopback */
911 buffer[0] = (uint8_t) type;
912 Client_send_udp(client, buffer, pds->offset + 1);
914 else if (target == 0) { /* regular channel speech */
915 buffer[0] = (uint8_t) type;
920 list_iterate(itr, &ch->clients) {
922 c = list_get_entry(itr, client_t, chan_node);
923 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
925 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
929 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
930 buffer[0] = (uint8_t) (type | 1);
931 Log_debug("Whisper channel %d", vt->channels[i]);
932 ch = Chan_fromId(vt->channels[i].channel);
935 list_iterate(itr, &ch->clients) {
937 c = list_get_entry(itr, client_t, chan_node);
938 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
941 if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
942 struct dlist *ch_itr;
943 list_iterate(ch_itr, &ch->channel_links) {
945 ch_link = list_get_entry(ch_itr, channel_t, link_node);
946 list_iterate(itr, &ch_link->clients) {
948 c = list_get_entry(itr, client_t, chan_node);
949 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
950 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
955 if (vt->channels[i].children) {
956 struct dlist chanlist, *ch_itr;
957 init_list_entry(&chanlist);
958 Chan_buildTreeList(ch, &chanlist);
959 list_iterate(ch_itr, &chanlist) {
961 sub = list_get_entry(ch_itr, channellist_t, node)->chan;
962 list_iterate(itr, &sub->clients) {
964 c = list_get_entry(itr, client_t, chan_node);
965 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
966 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
969 Chan_freeTreeList(&chanlist);
973 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
975 buffer[0] = (uint8_t) (type | 2);
976 Log_debug("Whisper session %d", vt->sessions[i]);
977 while (Client_iterate(&c) != NULL) {
978 if (c->sessionId == vt->sessions[i]) {
979 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
993 static int Client_send_udp(client_t *client, uint8_t *data, int len)
997 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
999 #if defined(__LP64__)
1000 buf = mbuf = malloc(len + 4 + 16);
1003 mbuf = buf = malloc(len + 4);
1006 Log_fatal("Out of memory");
1008 CryptState_encrypt(&client->cryptState, data, buf, len);
1010 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
1015 msg = Msg_CreateVoiceMsg(data, len);
1016 Client_send_message(client, msg);