1 /* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2010, 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"
49 extern char system_string[], version_string[];
51 static int Client_read(client_t *client);
52 static int Client_write(client_t *client);
53 static int Client_send_udp(client_t *client, uint8_t *data, int len);
54 void Client_free(client_t *client);
56 declare_list(clients);
57 static int clientcount; /* = 0 */
58 static int maxBandwidth;
60 int iCodecAlpha, iCodecBeta;
67 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
75 int Client_getfds(struct pollfd *pollfds)
79 list_iterate(itr, &clients) {
81 c = list_get_entry(itr, client_t, node);
82 pollfds[i].fd = c->tcpfd;
83 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
84 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
85 pollfds[i].events |= POLLOUT;
94 int bwTop = maxBandwidth + maxBandwidth / 4;
95 list_iterate(itr, &clients) {
97 c = list_get_entry(itr, client_t, node);
98 Log_debug("Client %s BW available %d", c->username, c->availableBandwidth);
99 c->availableBandwidth += maxBandwidth;
100 if (c->availableBandwidth > bwTop)
101 c->availableBandwidth = bwTop;
103 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
104 /* No activity from client - assume it is lost and close. */
105 Log_info_client(c, "Timeout, closing.");
111 void Client_codec_add(client_t *client, int codec)
113 codec_t *cd = malloc(sizeof(codec_t));
115 Log_fatal("Out of memory");
116 init_list_entry(&cd->node);
118 list_add_tail(&cd->node, &client->codecs);
121 void Client_codec_free(client_t *client)
123 struct dlist *itr, *save;
124 list_iterate_safe(itr, save, &client->codecs) {
125 list_del(&list_get_entry(itr, codec_t, node)->node);
126 free(list_get_entry(itr, codec_t, node));
130 codec_t *Client_codec_iterate(client_t *client, codec_t **codec_itr)
132 codec_t *cd = *codec_itr;
134 if (list_empty(&client->codecs))
138 cd = list_get_entry(list_get_first(&client->codecs), codec_t, node);
140 if (list_get_next(&cd->node) == &client->codecs)
143 cd = list_get_entry(list_get_next(&cd->node), codec_t, node);
149 void recheckCodecVersions()
151 client_t *client_itr = NULL;
152 int max = 0, version, current_version;
154 struct dlist codec_list, *itr, *save;
155 codec_t *codec_itr, *cd;
158 init_list_entry(&codec_list);
160 while (Client_iterate(&client_itr) != NULL) {
162 while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
164 list_iterate(itr, &codec_list) {
165 cd = list_get_entry(itr, codec_t, node);
166 if (cd->codec == codec_itr->codec) {
172 cd = malloc(sizeof(codec_t));
174 Log_fatal("Out of memory");
175 memset(cd, 0, sizeof(codec_t));
176 init_list_entry(&cd->node);
177 cd->codec = codec_itr->codec;
179 list_add_tail(&cd->node, &codec_list);
184 list_iterate(itr, &codec_list) {
185 cd = list_get_entry(itr, codec_t, node);
186 if (cd->count > max) {
191 list_iterate_safe(itr, save, &codec_list) {
192 list_del(&list_get_entry(itr, codec_t, node)->node);
193 free(list_get_entry(itr, codec_t, node));
196 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
197 if (current_version == version)
199 // If we don't already use the compat bitstream version set
200 // it as alpha and announce it. If another codec now got the
201 // majority set it as the opposite of the currently valid bPreferAlpha
203 if (version == (uint32_t)0x8000000b)
206 bPreferAlpha = ! bPreferAlpha;
209 iCodecAlpha = version;
211 iCodecBeta = version;
213 sendmsg = Msg_create(CodecVersion);
214 sendmsg->payload.codecVersion->alpha = version;
215 sendmsg->payload.codecVersion->beta = version;
216 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
217 Client_send_message_except(NULL, sendmsg);
219 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
220 bPreferAlpha ? iCodecAlpha : iCodecBeta);
224 static int findFreeSessionId()
227 client_t *itr = NULL;
229 for (id = 1; id < INT_MAX; id++) {
231 while ((itr = Client_iterate(&itr)) != NULL) {
232 if (itr->sessionId == id)
235 if (itr == NULL) /* Found free id */
241 int Client_add(int fd, struct sockaddr_in *remote)
246 newclient = malloc(sizeof(client_t));
247 if (newclient == NULL)
248 Log_fatal("Out of memory");
249 memset(newclient, 0, sizeof(client_t));
251 newclient->tcpfd = fd;
252 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
253 newclient->ssl = SSLi_newconnection(&newclient->tcpfd, &newclient->SSLready);
254 if (newclient->ssl == NULL) {
255 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
256 ntohs(remote->sin_port));
260 newclient->availableBandwidth = maxBandwidth;
261 Timer_init(&newclient->lastActivity);
262 Timer_init(&newclient->connectTime);
263 Timer_init(&newclient->idleTime);
264 newclient->sessionId = findFreeSessionId();
265 if (newclient->sessionId < 0)
266 Log_fatal("Could not find a free session ID");
268 init_list_entry(&newclient->txMsgQueue);
269 init_list_entry(&newclient->chan_node);
270 init_list_entry(&newclient->node);
271 init_list_entry(&newclient->voicetargets);
272 init_list_entry(&newclient->codecs);
274 list_add_tail(&newclient->node, &clients);
277 /* Send version message to client */
278 sendmsg = Msg_create(Version);
279 sendmsg->payload.version->has_version = true;
280 sendmsg->payload.version->version = PROTOCOL_VERSION;
281 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
282 sendmsg->payload.version->os = strdup(system_string);
283 sendmsg->payload.version->os_version = strdup(version_string);
284 Client_send_message(newclient, sendmsg);
289 void Client_free(client_t *client)
291 struct dlist *itr, *save;
294 if (client->authenticated) {
296 leave_id = Chan_userLeave(client);
297 if (leave_id > 0) { /* Remove temp channel */
298 sendmsg = Msg_create(ChannelRemove);
299 sendmsg->payload.channelRemove->channel_id = leave_id;
300 Client_send_message_except(client, sendmsg);
302 sendmsg = Msg_create(UserRemove);
303 sendmsg->payload.userRemove->session = client->sessionId;
304 Client_send_message_except(client, sendmsg);
306 list_iterate_safe(itr, save, &client->txMsgQueue) {
307 list_del(&list_get_entry(itr, message_t, node)->node);
308 Msg_free(list_get_entry(itr, message_t, node));
310 Client_codec_free(client);
311 Voicetarget_free_all(client);
313 list_del(&client->node);
315 SSLi_free(client->ssl);
316 close(client->tcpfd);
319 free(client->release);
322 if (client->os_version)
323 free(client->os_version);
324 if (client->username)
325 free(client->username);
327 free(client->context);
331 void Client_close(client_t *client)
333 SSLi_shutdown(client->ssl);
334 client->shutdown_wait = true;
337 void Client_disconnect_all()
339 struct dlist *itr, *save;
341 list_iterate_safe(itr, save, &clients) {
342 Client_free(list_get_entry(itr, client_t, node));
346 int Client_read_fd(int fd)
349 client_t *client = NULL;
351 list_iterate(itr, &clients) {
352 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
353 client = list_get_entry(itr, client_t, node);
358 Log_fatal("No client found for fd %d", fd);
360 return Client_read(client);
363 int Client_read(client_t *client)
367 Timer_restart(&client->lastActivity);
369 if (client->writeBlockedOnRead) {
370 client->writeBlockedOnRead = false;
371 Log_debug("Client_read: writeBlockedOnRead == true");
372 return Client_write(client);
375 if (client->shutdown_wait) {
379 if (!client->SSLready) {
381 rc = SSLi_nonblockaccept(client->ssl, &client->SSLready);
390 if (!client->msgsize)
391 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
393 rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
396 client->rxcount += rc;
397 if (!client->msgsize && client->rxcount >= 6) {
399 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
400 client->msgsize = ntohl(msgLen);
402 if (client->msgsize > BUFSIZE - 6) {
403 /* XXX - figure out how to handle this. A large size here can represent two cases:
404 * 1. A valid size. The only message that is this big is UserState message with a big texture
405 * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
407 Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
408 client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
411 /* client->rxcount = client->msgsize = 0; */
413 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
414 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
415 /* pass messsage to handler */
417 Mh_handle_message(client, msg);
418 client->rxcount = client->msgsize = 0;
420 } else /* rc <= 0 */ {
421 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
424 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
425 client->readBlockedOnWrite = true;
428 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN) {
429 Log_info_client(client, "Connection closed by peer");
430 if (!client->shutdown_wait)
431 Client_close(client);
434 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
435 Log_info_client(client, "Connection closed by peer");
438 Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
444 } while (SSLi_data_pending(client->ssl));
449 int Client_write_fd(int fd)
452 client_t *client = NULL;
454 list_iterate(itr, &clients) {
455 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
456 client = list_get_entry(itr, client_t, node);
461 Log_fatal("No client found for fd %d", fd);
462 Client_write(client);
466 int Client_write(client_t *client)
470 if (client->readBlockedOnWrite) {
471 client->readBlockedOnWrite = false;
472 Log_debug("Client_write: readBlockedOnWrite == true");
473 return Client_read(client);
475 rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
477 client->txcount += rc;
478 if (client->txcount == client->txsize)
479 client->txsize = client->txcount = 0;
482 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
483 client->writeBlockedOnRead = true;
486 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
490 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL)
491 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
493 Log_warn("Client_write: SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
498 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
500 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
501 list_del(list_get_first(&client->txMsgQueue));
502 client->txQueueCount--;
503 Client_send_message(client, msg);
508 int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
510 if ((version == 0) || (client->version >= version) ||
511 ((version & 0x80000000) && (client->version < (~version))))
512 return Client_send_message(client, msg);
517 int Client_send_message(client_t *client, message_t *msg)
519 if (!client->authenticated && msg->messageType != Version) {
523 if (client->txsize != 0 || !client->SSLready) {
525 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
526 client->txQueueCount > 30) {
530 client->txQueueCount++;
531 list_add_tail(&msg->node, &client->txMsgQueue);
532 Log_debug("Queueing message");
535 len = Msg_messageToNetwork(msg, client->txbuf);
536 doAssert(len < BUFSIZE);
538 client->txsize = len;
540 Client_write(client);
546 client_t *Client_iterate(client_t **client_itr)
548 client_t *c = *client_itr;
550 if (list_empty(&clients))
554 c = list_get_entry(list_get_first(&clients), client_t, node);
556 if (list_get_next(&c->node) == &clients)
559 c = list_get_entry(list_get_next(&c->node), client_t, node);
566 int Client_send_message_except(client_t *client, message_t *msg)
568 client_t *itr = NULL;
571 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
572 while (Client_iterate(&itr) != NULL) {
575 Msg_inc_ref(msg); /* One extra reference for each new copy */
576 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
577 Client_send_message(itr, msg);
580 Msg_free(msg); /* Free our reference to the message */
583 Msg_free(msg); /* If only 1 client is connected then no message is passed
584 * to Client_send_message(). Free it here. */
589 int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
591 client_t *itr = NULL;
594 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
595 while (Client_iterate(&itr) != NULL) {
598 Msg_inc_ref(msg); /* One extra reference for each new copy */
599 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
600 Client_send_message_ver(itr, msg, version);
603 Msg_free(msg); /* Free our reference to the message */
606 Msg_free(msg); /* If only 1 client is connected then no message is passed
607 * to Client_send_message(). Free it here. */
612 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
614 if (CryptState_isValid(&client->cryptState) &&
615 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
618 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
619 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
621 Timer_restart(&client->cryptState.tLastRequest);
623 sendmsg = Msg_create(CryptSetup);
624 Log_info_client(client, "Requesting voice channel crypt resync");
625 Client_send_message(client, sendmsg);
631 #define UDP_PACKET_SIZE 1024
632 int Client_read_udp()
635 struct sockaddr_in from;
636 socklen_t fromlen = sizeof(struct sockaddr_in);
639 UDPMessageType_t msgType;
641 #if defined(__LP64__)
642 uint8_t encbuff[UDP_PACKET_SIZE + 8];
643 uint8_t *encrypted = encbuff + 4;
645 uint8_t encrypted[UDP_PACKET_SIZE];
647 uint8_t buffer[UDP_PACKET_SIZE];
649 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
652 } else if (len < 0) {
654 } else if (len < 5) {
655 // 4 bytes crypt header + type + session
657 } else if (len > UDP_PACKET_SIZE) {
662 if (len == 12 && *encrypted == 0) {
663 uint32_t *ping = (uint32_t *)encrypted;
664 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
665 // 1 and 2 will be the timestamp, which we return unmodified.
666 ping[3] = htonl((uint32_t)clientcount);
667 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
668 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
670 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
674 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
677 while (Client_iterate(&itr) != NULL) {
678 if (itr->key == key) {
679 if (!checkDecrypt(itr, encrypted, buffer, len))
684 if (itr == NULL) { /* Unknown peer */
685 while (Client_iterate(&itr) != NULL) {
686 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
687 if (checkDecrypt(itr, encrypted, buffer, len)) {
689 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
690 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
693 else Log_warn("Bad cryptstate from peer");
697 if (itr == NULL) { /* Couldn't find this peer among connected clients */
702 len -= 4; /* Adjust for crypt header */
703 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
706 case UDPVoiceCELTAlpha:
707 case UDPVoiceCELTBeta:
708 Client_voiceMsg(itr, buffer, len);
711 Log_debug("UDP Ping reply len %d", len);
712 Client_send_udp(itr, buffer, len);
715 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
723 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
725 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
726 if (poslen > 0 && /* Has positional data */
727 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
728 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
729 Client_send_udp(dst, data, len);
731 Client_send_udp(dst, data, len - poslen);
735 /* Handle decrypted voice message */
736 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
738 uint8_t buffer[UDP_PACKET_SIZE];
739 pds_t *pdi = Pds_create(data + 1, len - 1);
740 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
741 unsigned int type = data[0] & 0xe0;
742 unsigned int target = data[0] & 0x1f;
743 unsigned int poslen, counter;
744 int offset, packetsize;
747 channel_t *ch = (channel_t *)client->channel;
750 if (!client->authenticated || client->mute)
753 packetsize = 20 + 8 + 4 + len;
754 if (client->availableBandwidth - packetsize < 0)
755 goto out; /* Discard */
756 client->availableBandwidth -= packetsize;
758 Timer_restart(&client->idleTime);
760 counter = Pds_get_numval(pdi); /* step past session id */
762 counter = Pds_next8(pdi);
763 offset = Pds_skip(pdi, counter & 0x7f);
764 } while ((counter & 0x80) && offset > 0);
766 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
768 Pds_add_numval(pds, client->sessionId);
769 Pds_append_data_nosize(pds, data + 1, len - 1);
771 if (target == 0x1f) { /* Loopback */
772 buffer[0] = (uint8_t) type;
773 Client_send_udp(client, buffer, pds->offset + 1);
775 else if (target == 0) { /* regular channel speech */
776 buffer[0] = (uint8_t) type;
781 list_iterate(itr, &ch->clients) {
783 c = list_get_entry(itr, client_t, chan_node);
784 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
786 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
790 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
791 buffer[0] = (uint8_t) (type | 1);
792 Log_debug("Whisper channel %d", vt->channels[i]);
793 ch = Chan_fromId(vt->channels[i].channel);
796 list_iterate(itr, &ch->clients) {
798 c = list_get_entry(itr, client_t, chan_node);
799 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
802 if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
803 struct dlist *ch_itr;
804 list_iterate(ch_itr, &ch->channel_links) {
806 ch_link = list_get_entry(ch_itr, channel_t, link_node);
807 list_iterate(itr, &ch_link->clients) {
809 c = list_get_entry(itr, client_t, chan_node);
810 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
811 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
816 if (vt->channels[i].children) {
817 struct dlist chanlist, *ch_itr;
818 init_list_entry(&chanlist);
819 Chan_buildTreeList(ch, &chanlist);
820 list_iterate(ch_itr, &chanlist) {
822 sub = list_get_entry(ch_itr, channellist_t, node)->chan;
823 list_iterate(itr, &sub->clients) {
825 c = list_get_entry(itr, client_t, chan_node);
826 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
827 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
830 Chan_freeTreeList(&chanlist);
834 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
836 buffer[0] = (uint8_t) (type | 2);
837 Log_debug("Whisper session %d", vt->sessions[i]);
838 while (Client_iterate(&c) != NULL) {
839 if (c->sessionId == vt->sessions[i]) {
840 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
854 static int Client_send_udp(client_t *client, uint8_t *data, int len)
858 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
860 #if defined(__LP64__)
861 buf = mbuf = malloc(len + 4 + 16);
864 mbuf = buf = malloc(len + 4);
867 Log_fatal("Out of memory");
869 CryptState_encrypt(&client->cryptState, data, buf, len);
871 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
876 msg = Msg_CreateVoiceMsg(data, len);
877 Client_send_message(client, msg);