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)0x8000000a)
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(client_t *client, message_t *msg)
510 if (!client->authenticated && msg->messageType != Version) {
514 if (client->txsize != 0 || !client->SSLready) {
516 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
517 client->txQueueCount > 30) {
521 client->txQueueCount++;
522 list_add_tail(&msg->node, &client->txMsgQueue);
523 Log_debug("Queueing message");
526 len = Msg_messageToNetwork(msg, client->txbuf);
527 doAssert(len < BUFSIZE);
529 client->txsize = len;
531 Client_write(client);
537 client_t *Client_iterate(client_t **client_itr)
539 client_t *c = *client_itr;
541 if (list_empty(&clients))
545 c = list_get_entry(list_get_first(&clients), client_t, node);
547 if (list_get_next(&c->node) == &clients)
550 c = list_get_entry(list_get_next(&c->node), client_t, node);
557 int Client_send_message_except(client_t *client, message_t *msg)
559 client_t *itr = NULL;
562 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
563 while (Client_iterate(&itr) != NULL) {
566 Msg_inc_ref(msg); /* One extra reference for each new copy */
567 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
568 Client_send_message(itr, msg);
571 Msg_free(msg); /* Free our reference to the message */
574 Msg_free(msg); /* If only 1 client is connected then no message is passed
575 * to Client_send_message(). Free it here. */
580 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
582 if (CryptState_isValid(&client->cryptState) &&
583 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
586 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
587 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
589 Timer_restart(&client->cryptState.tLastRequest);
591 sendmsg = Msg_create(CryptSetup);
592 Log_info_client(client, "Requesting voice channel crypt resync");
593 Client_send_message(client, sendmsg);
599 #define UDP_PACKET_SIZE 1024
600 int Client_read_udp()
603 struct sockaddr_in from;
604 socklen_t fromlen = sizeof(struct sockaddr_in);
607 UDPMessageType_t msgType;
609 #if defined(__LP64__)
610 uint8_t encbuff[UDP_PACKET_SIZE + 8];
611 uint8_t *encrypted = encbuff + 4;
613 uint8_t encrypted[UDP_PACKET_SIZE];
615 uint8_t buffer[UDP_PACKET_SIZE];
617 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
620 } else if (len < 0) {
622 } else if (len < 5) {
623 // 4 bytes crypt header + type + session
625 } else if (len > UDP_PACKET_SIZE) {
630 if (len == 12 && *encrypted == 0) {
631 uint32_t *ping = (uint32_t *)encrypted;
632 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
633 // 1 and 2 will be the timestamp, which we return unmodified.
634 ping[3] = htonl((uint32_t)clientcount);
635 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
636 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
638 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
642 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
645 while (Client_iterate(&itr) != NULL) {
646 if (itr->key == key) {
647 if (!checkDecrypt(itr, encrypted, buffer, len))
652 if (itr == NULL) { /* Unknown peer */
653 while (Client_iterate(&itr) != NULL) {
654 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
655 if (checkDecrypt(itr, encrypted, buffer, len)) {
657 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
658 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
661 else Log_warn("Bad cryptstate from peer");
665 if (itr == NULL) { /* Couldn't find this peer among connected clients */
670 len -= 4; /* Adjust for crypt header */
671 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
674 case UDPVoiceCELTAlpha:
675 case UDPVoiceCELTBeta:
676 Client_voiceMsg(itr, buffer, len);
679 Log_debug("UDP Ping reply len %d", len);
680 Client_send_udp(itr, buffer, len);
683 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
691 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
693 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
694 if (poslen > 0 && /* Has positional data */
695 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
696 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
697 Client_send_udp(dst, data, len);
699 Client_send_udp(dst, data, len - poslen);
703 /* Handle decrypted voice message */
704 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
706 uint8_t buffer[UDP_PACKET_SIZE];
707 pds_t *pdi = Pds_create(data + 1, len - 1);
708 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
709 unsigned int type = data[0] & 0xe0;
710 unsigned int target = data[0] & 0x1f;
711 unsigned int poslen, counter;
712 int offset, packetsize;
715 channel_t *ch = (channel_t *)client->channel;
718 if (!client->authenticated || client->mute)
721 packetsize = 20 + 8 + 4 + len;
722 if (client->availableBandwidth - packetsize < 0)
723 goto out; /* Discard */
724 client->availableBandwidth -= packetsize;
726 Timer_restart(&client->idleTime);
728 counter = Pds_get_numval(pdi); /* step past session id */
730 counter = Pds_next8(pdi);
731 offset = Pds_skip(pdi, counter & 0x7f);
732 } while ((counter & 0x80) && offset > 0);
734 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
736 Pds_add_numval(pds, client->sessionId);
737 Pds_append_data_nosize(pds, data + 1, len - 1);
739 if (target == 0x1f) { /* Loopback */
740 buffer[0] = (uint8_t) type;
741 Client_send_udp(client, buffer, pds->offset + 1);
743 else if (target == 0) { /* regular channel speech */
744 buffer[0] = (uint8_t) type;
749 list_iterate(itr, &ch->clients) {
751 c = list_get_entry(itr, client_t, chan_node);
752 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
754 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
758 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
759 buffer[0] = (uint8_t) (type | 1);
760 Log_debug("Whisper channel %d", vt->channels[i]);
761 ch = Chan_fromId(vt->channels[i].channel);
764 list_iterate(itr, &ch->clients) {
766 c = list_get_entry(itr, client_t, chan_node);
767 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
770 if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
771 struct dlist *ch_itr;
772 list_iterate(ch_itr, &ch->channel_links) {
774 ch_link = list_get_entry(ch_itr, channel_t, link_node);
775 list_iterate(itr, &ch_link->clients) {
777 c = list_get_entry(itr, client_t, chan_node);
778 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
779 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
784 if (vt->channels[i].children) {
785 struct dlist chanlist, *ch_itr;
786 init_list_entry(&chanlist);
787 Chan_buildTreeList(ch, &chanlist);
788 list_iterate(ch_itr, &chanlist) {
790 sub = list_get_entry(ch_itr, channellist_t, node)->chan;
791 list_iterate(itr, &sub->clients) {
793 c = list_get_entry(itr, client_t, chan_node);
794 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
795 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
798 Chan_freeTreeList(&chanlist);
802 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
804 buffer[0] = (uint8_t) (type | 2);
805 Log_debug("Whisper session %d", vt->sessions[i]);
806 while (Client_iterate(&c) != NULL) {
807 if (c->sessionId == vt->sessions[i]) {
808 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
822 static int Client_send_udp(client_t *client, uint8_t *data, int len)
826 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
828 #if defined(__LP64__)
829 buf = mbuf = malloc(len + 4 + 16);
832 mbuf = buf = malloc(len + 4);
835 Log_fatal("Out of memory");
837 CryptState_encrypt(&client->cryptState, data, buf, len);
839 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
844 msg = Msg_CreateVoiceMsg(data, len);
845 Client_send_message(client, msg);