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) {
276 Client_textmessage(client_itr, OPUS_WARN);
282 Log_info("OPUS codec is %s", bOpus ? "enabled" : "disabled");
284 sendmsg = Msg_create(CodecVersion);
285 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
286 sendmsg->payload.codecVersion->beta = iCodecBeta;
287 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
288 sendmsg->payload.codecVersion->has_opus = true;
289 sendmsg->payload.codecVersion->opus = bOpus;
291 Client_send_message_except(NULL, sendmsg);
293 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
294 bPreferAlpha ? iCodecAlpha : iCodecBeta);
297 while (Client_iterate(&client_itr) != NULL) {
298 if ((client_itr->authenticated || client_itr == connectingClient) &&
299 !client_itr->bOpus) {
300 Client_textmessage(client_itr, OPUS_WARN);
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);
392 recheckCodecVersions(NULL); /* Can use better codec now? */
394 list_iterate_safe(itr, save, &client->txMsgQueue) {
395 list_del(&list_get_entry(itr, message_t, node)->node);
396 Msg_free(list_get_entry(itr, message_t, node));
398 Client_codec_free(client);
399 Voicetarget_free_all(client);
400 Client_token_free(client);
402 list_del(&client->node);
404 SSLi_free(client->ssl);
405 close(client->tcpfd);
408 free(client->release);
411 if (client->os_version)
412 free(client->os_version);
413 if (client->username)
414 free(client->username);
416 free(client->context);
420 void Client_close(client_t *client)
422 SSLi_shutdown(client->ssl);
423 client->shutdown_wait = true;
426 void Client_disconnect_all()
428 struct dlist *itr, *save;
430 list_iterate_safe(itr, save, &clients) {
431 Client_free(list_get_entry(itr, client_t, node));
435 int Client_read_fd(int fd)
438 client_t *client = NULL;
440 list_iterate(itr, &clients) {
441 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
442 client = list_get_entry(itr, client_t, node);
447 return Client_read(client);
452 int Client_read(client_t *client)
456 Timer_restart(&client->lastActivity);
458 if (client->writeBlockedOnRead) {
459 client->writeBlockedOnRead = false;
460 Log_debug("Client_read: writeBlockedOnRead == true");
461 return Client_write(client);
464 if (client->shutdown_wait) {
468 if (!client->SSLready) {
470 rc = SSLi_nonblockaccept(client->ssl, &client->SSLready);
479 if (!client->msgsize)
480 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
482 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
485 client->rxcount += rc;
486 if (!client->msgsize && client->rxcount >= 6) {
488 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
489 client->msgsize = ntohl(msgLen);
491 if (client->msgsize > BUFSIZE - 6) {
492 /* XXX - figure out how to handle this. A large size here can represent two cases:
493 * 1. A valid size. The only message that is this big is UserState message with a big texture
494 * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
496 Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
497 client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
500 /* client->rxcount = client->msgsize = 0; */
502 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
503 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
504 /* pass messsage to handler */
506 Mh_handle_message(client, msg);
507 client->rxcount = client->msgsize = 0;
509 } else /* rc <= 0 */ {
510 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
513 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
514 client->readBlockedOnWrite = true;
517 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN ||
518 SSLi_get_error(client->ssl, rc) == 0) {
519 Log_info_client(client, "Connection closed by peer");
523 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
525 Log_info_client(client, "Connection closed by peer");
527 Log_info_client(client,"Error: %s - Closing connection (code %d)",
530 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
531 Log_info_client(client, "Connection reset by peer");
534 Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
540 } while (SSLi_data_pending(client->ssl));
545 int Client_write_fd(int fd)
548 client_t *client = NULL;
550 list_iterate(itr, &clients) {
551 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
552 client = list_get_entry(itr, client_t, node);
557 return Client_write(client);
562 int Client_write(client_t *client)
566 if (client->readBlockedOnWrite) {
567 client->readBlockedOnWrite = false;
568 Log_debug("Client_write: readBlockedOnWrite == true");
569 return Client_read(client);
571 rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
573 client->txcount += rc;
574 if (client->txcount == client->txsize)
575 client->txsize = client->txcount = 0;
578 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
579 client->writeBlockedOnRead = true;
582 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
586 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
587 Log_info_client(client, "Error: %s - Closing connection", strerror(errno));
589 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
590 Log_info_client(client, "Connection reset by peer");
593 Log_info_client(client, "SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
599 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
601 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
602 list_del(list_get_first(&client->txMsgQueue));
603 client->txQueueCount--;
604 Client_send_message(client, msg);
609 int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
611 if ((version == 0) || (client->version >= version) ||
612 ((version & 0x80000000) && (client->version < (~version))))
613 return Client_send_message(client, msg);
618 int Client_send_message(client_t *client, message_t *msg)
620 if (!client->authenticated && msg->messageType != Version) {
624 if (client->txsize != 0 || !client->SSLready) {
626 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
627 client->txQueueCount > 30) {
631 client->txQueueCount++;
632 list_add_tail(&msg->node, &client->txMsgQueue);
633 Log_debug("Queueing message");
636 len = Msg_messageToNetwork(msg, client->txbuf);
637 doAssert(len < BUFSIZE);
639 client->txsize = len;
641 Client_write(client);
647 client_t *Client_iterate(client_t **client_itr)
649 client_t *c = *client_itr;
651 if (list_empty(&clients))
655 c = list_get_entry(list_get_first(&clients), client_t, node);
657 if (list_get_next(&c->node) == &clients)
660 c = list_get_entry(list_get_next(&c->node), client_t, node);
666 void Client_textmessage(client_t *client, char *text)
670 message_t *sendmsg = NULL;
672 message = malloc(strlen(text) + 1);
674 Log_fatal("Out of memory");
675 tree_id = malloc(sizeof(uint32_t));
677 Log_fatal("Out of memory");
679 sendmsg = Msg_create(TextMessage);
680 sendmsg->payload.textMessage->message = message;
681 sendmsg->payload.textMessage->n_tree_id = 1;
682 sendmsg->payload.textMessage->tree_id = tree_id;
683 strcpy(message, text);
684 Client_send_message(client, sendmsg);
688 int Client_send_message_except(client_t *client, message_t *msg)
690 client_t *itr = NULL;
693 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
694 while (Client_iterate(&itr) != NULL) {
697 Msg_inc_ref(msg); /* One extra reference for each new copy */
698 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
699 Client_send_message(itr, msg);
702 Msg_free(msg); /* Free our reference to the message */
705 Msg_free(msg); /* If only 1 client is connected then no message is passed
706 * to Client_send_message(). Free it here. */
711 int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
713 client_t *itr = NULL;
716 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
717 while (Client_iterate(&itr) != NULL) {
720 Msg_inc_ref(msg); /* One extra reference for each new copy */
721 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
722 Client_send_message_ver(itr, msg, version);
725 Msg_free(msg); /* Free our reference to the message */
728 Msg_free(msg); /* If only 1 client is connected then no message is passed
729 * to Client_send_message(). Free it here. */
734 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
736 if (CryptState_isValid(&client->cryptState) &&
737 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
740 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
741 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
743 Timer_restart(&client->cryptState.tLastRequest);
745 sendmsg = Msg_create(CryptSetup);
746 Log_info_client(client, "Requesting voice channel crypt resync");
747 Client_send_message(client, sendmsg);
753 #define UDP_PACKET_SIZE 1024
754 int Client_read_udp()
757 struct sockaddr_in from;
758 socklen_t fromlen = sizeof(struct sockaddr_in);
761 UDPMessageType_t msgType;
763 #if defined(__LP64__)
764 uint8_t encbuff[UDP_PACKET_SIZE + 8];
765 uint8_t *encrypted = encbuff + 4;
767 uint8_t encrypted[UDP_PACKET_SIZE];
769 uint8_t buffer[UDP_PACKET_SIZE];
771 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
774 } else if (len < 0) {
776 } else if (len < 5) {
777 // 4 bytes crypt header + type + session
779 } else if (len > UDP_PACKET_SIZE) {
784 if (len == 12 && *encrypted == 0) {
785 uint32_t *ping = (uint32_t *)encrypted;
786 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
787 // 1 and 2 will be the timestamp, which we return unmodified.
788 ping[3] = htonl((uint32_t)clientcount);
789 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
790 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
792 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
796 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
799 while (Client_iterate(&itr) != NULL) {
800 if (itr->key == key) {
801 if (!checkDecrypt(itr, encrypted, buffer, len))
806 if (itr == NULL) { /* Unknown peer */
807 while (Client_iterate(&itr) != NULL) {
808 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
809 if (checkDecrypt(itr, encrypted, buffer, len)) {
811 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
812 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
818 if (itr == NULL) { /* Couldn't find this peer among connected clients */
823 len -= 4; /* Adjust for crypt header */
824 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
827 case UDPVoiceCELTAlpha:
828 case UDPVoiceCELTBeta:
832 Client_voiceMsg(itr, buffer, len);
835 Log_debug("UDP Ping reply len %d", len);
836 Client_send_udp(itr, buffer, len);
839 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
847 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
849 if (IS_AUTH(dst) && dst != src && !dst->deaf && !dst->self_deaf) {
850 if (poslen > 0 && /* Has positional data */
851 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
852 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
853 Client_send_udp(dst, data, len);
855 Client_send_udp(dst, data, len - poslen);
859 /* Handle decrypted voice message */
860 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
862 uint8_t buffer[UDP_PACKET_SIZE];
863 pds_t *pdi = Pds_create(data + 1, len - 1);
864 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
865 unsigned int type = data[0] & 0xe0;
866 unsigned int target = data[0] & 0x1f;
867 unsigned int poslen, counter, size;
868 int offset, packetsize;
871 channel_t *ch = (channel_t *)client->channel;
874 if (!client->authenticated || client->mute || client->self_mute)
877 packetsize = 20 + 8 + 4 + len;
878 if (client->availableBandwidth - packetsize < 0)
879 goto out; /* Discard */
880 client->availableBandwidth -= packetsize;
882 Timer_restart(&client->idleTime);
883 Timer_restart(&client->lastActivity);
885 if ((type >> 5) != UDPVoiceOpus) {
886 counter = Pds_get_numval(pdi); /* step past session id */
888 counter = Pds_next8(pdi);
889 offset = Pds_skip(pdi, counter & 0x7f);
890 } while ((counter & 0x80) && offset > 0);
892 size = Pds_get_numval(pdi);
893 Pds_skip(pdi, size & 0x1fff);
896 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
898 Pds_add_numval(pds, client->sessionId);
899 Pds_append_data_nosize(pds, data + 1, len - 1);
901 if (target == 0x1f) { /* Loopback */
902 buffer[0] = (uint8_t) type;
903 Client_send_udp(client, buffer, pds->offset + 1);
905 else if (target == 0) { /* regular channel speech */
906 buffer[0] = (uint8_t) type;
911 list_iterate(itr, &ch->clients) {
913 c = list_get_entry(itr, client_t, chan_node);
914 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
916 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
920 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
921 buffer[0] = (uint8_t) (type | 1);
922 Log_debug("Whisper channel %d", vt->channels[i]);
923 ch = Chan_fromId(vt->channels[i].channel);
926 list_iterate(itr, &ch->clients) {
928 c = list_get_entry(itr, client_t, chan_node);
929 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
932 if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
933 struct dlist *ch_itr;
934 list_iterate(ch_itr, &ch->channel_links) {
936 ch_link = list_get_entry(ch_itr, channel_t, link_node);
937 list_iterate(itr, &ch_link->clients) {
939 c = list_get_entry(itr, client_t, chan_node);
940 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
941 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
946 if (vt->channels[i].children) {
947 struct dlist chanlist, *ch_itr;
948 init_list_entry(&chanlist);
949 Chan_buildTreeList(ch, &chanlist);
950 list_iterate(ch_itr, &chanlist) {
952 sub = list_get_entry(ch_itr, channellist_t, node)->chan;
953 list_iterate(itr, &sub->clients) {
955 c = list_get_entry(itr, client_t, chan_node);
956 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
957 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
960 Chan_freeTreeList(&chanlist);
964 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
966 buffer[0] = (uint8_t) (type | 2);
967 Log_debug("Whisper session %d", vt->sessions[i]);
968 while (Client_iterate(&c) != NULL) {
969 if (c->sessionId == vt->sessions[i]) {
970 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
984 static int Client_send_udp(client_t *client, uint8_t *data, int len)
988 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
990 #if defined(__LP64__)
991 buf = mbuf = malloc(len + 4 + 16);
994 mbuf = buf = malloc(len + 4);
997 Log_fatal("Out of memory");
999 CryptState_encrypt(&client->cryptState, data, buf, len);
1001 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
1006 msg = Msg_CreateVoiceMsg(data, len);
1007 Client_send_message(client, msg);