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>
40 #include "messagehandler.h"
44 #include "voicetarget.h"
46 extern char system_string[], version_string[];
48 static int Client_read(client_t *client);
49 static int Client_write(client_t *client);
50 static int Client_send_udp(client_t *client, uint8_t *data, int len);
51 void Client_free(client_t *client);
53 declare_list(clients);
54 static int clientcount; /* = 0 */
55 static int maxBandwidth;
57 int iCodecAlpha, iCodecBeta;
64 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
72 int Client_getfds(struct pollfd *pollfds)
76 list_iterate(itr, &clients) {
78 c = list_get_entry(itr, client_t, node);
79 pollfds[i].fd = c->tcpfd;
80 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
81 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
82 pollfds[i].events |= POLLOUT;
91 int bwTop = maxBandwidth + maxBandwidth / 4;
92 list_iterate(itr, &clients) {
94 c = list_get_entry(itr, client_t, node);
95 Log_debug("Client %s BW available %d", c->username, c->availableBandwidth);
96 c->availableBandwidth += maxBandwidth;
97 if (c->availableBandwidth > bwTop)
98 c->availableBandwidth = bwTop;
100 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
101 /* No activity from client - assume it is lost and close. */
102 Log_info_client(c, "Timeout, closing.");
108 void Client_codec_add(client_t *client, int codec)
110 codec_t *cd = malloc(sizeof(codec_t));
112 Log_fatal("Out of memory");
113 init_list_entry(&cd->node);
115 list_add_tail(&cd->node, &client->codecs);
118 void Client_codec_free(client_t *client)
120 struct dlist *itr, *save;
121 list_iterate_safe(itr, save, &client->codecs) {
122 list_del(&list_get_entry(itr, codec_t, node)->node);
123 free(list_get_entry(itr, codec_t, node));
127 codec_t *Client_codec_iterate(client_t *client, codec_t **codec_itr)
129 codec_t *cd = *codec_itr;
131 if (list_empty(&client->codecs))
135 cd = list_get_entry(list_get_first(&client->codecs), codec_t, node);
137 if (list_get_next(&cd->node) == &client->codecs)
140 cd = list_get_entry(list_get_next(&cd->node), codec_t, node);
146 void recheckCodecVersions()
148 client_t *client_itr = NULL;
149 int max = 0, version, current_version;
151 struct dlist codec_list, *itr, *save;
152 codec_t *codec_itr, *cd;
155 init_list_entry(&codec_list);
157 while (Client_iterate(&client_itr) != NULL) {
159 while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
161 list_iterate(itr, &codec_list) {
162 cd = list_get_entry(itr, codec_t, node);
163 if (cd->codec == codec_itr->codec) {
169 cd = malloc(sizeof(codec_t));
171 Log_fatal("Out of memory");
172 memset(cd, 0, sizeof(codec_t));
173 init_list_entry(&cd->node);
174 cd->codec = codec_itr->codec;
176 list_add_tail(&cd->node, &codec_list);
181 list_iterate(itr, &codec_list) {
182 cd = list_get_entry(itr, codec_t, node);
183 if (cd->count > max) {
188 list_iterate_safe(itr, save, &codec_list) {
189 list_del(&list_get_entry(itr, codec_t, node)->node);
190 free(list_get_entry(itr, codec_t, node));
193 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
194 if (current_version == version)
196 // If we don't already use the compat bitstream version set
197 // it as alpha and announce it. If another codec now got the
198 // majority set it as the opposite of the currently valid bPreferAlpha
200 if (version == (uint32_t)0x8000000a)
203 bPreferAlpha = ! bPreferAlpha;
206 iCodecAlpha = version;
208 iCodecBeta = version;
210 sendmsg = Msg_create(CodecVersion);
211 sendmsg->payload.codecVersion->alpha = version;
212 sendmsg->payload.codecVersion->beta = version;
213 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
214 Client_send_message_except(NULL, sendmsg);
216 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
217 bPreferAlpha ? iCodecAlpha : iCodecBeta);
221 static int findFreeSessionId()
224 client_t *itr = NULL;
226 for (id = 1; id < INT_MAX; id++) {
228 while ((itr = Client_iterate(&itr)) != NULL) {
229 if (itr->sessionId == id)
232 if (itr == NULL) /* Found free id */
238 int Client_add(int fd, struct sockaddr_in *remote)
243 newclient = malloc(sizeof(client_t));
244 if (newclient == NULL)
245 Log_fatal("Out of memory");
246 memset(newclient, 0, sizeof(client_t));
248 newclient->tcpfd = fd;
249 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
250 newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
251 if (newclient->ssl == NULL) {
252 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
253 ntohs(remote->sin_port));
257 newclient->availableBandwidth = maxBandwidth;
258 Timer_init(&newclient->lastActivity);
259 newclient->sessionId = findFreeSessionId();
260 if (newclient->sessionId < 0)
261 Log_fatal("Could not find a free session ID");
263 init_list_entry(&newclient->txMsgQueue);
264 init_list_entry(&newclient->chan_node);
265 init_list_entry(&newclient->node);
266 init_list_entry(&newclient->voicetargets);
267 init_list_entry(&newclient->codecs);
269 list_add_tail(&newclient->node, &clients);
272 /* Send version message to client */
273 sendmsg = Msg_create(Version);
274 sendmsg->payload.version->has_version = true;
275 sendmsg->payload.version->version = PROTOCOL_VERSION;
276 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
277 sendmsg->payload.version->os = strdup(system_string);
278 sendmsg->payload.version->os_version = strdup(version_string);
279 Client_send_message(newclient, sendmsg);
284 void Client_free(client_t *client)
286 struct dlist *itr, *save;
289 if (client->authenticated) {
291 leave_id = Chan_userLeave(client);
292 if (leave_id > 0) { /* Remove temp channel */
293 sendmsg = Msg_create(ChannelRemove);
294 sendmsg->payload.channelRemove->channel_id = leave_id;
295 Client_send_message_except(client, sendmsg);
297 sendmsg = Msg_create(UserRemove);
298 sendmsg->payload.userRemove->session = client->sessionId;
299 Client_send_message_except(client, sendmsg);
301 list_iterate_safe(itr, save, &client->txMsgQueue) {
302 list_del(&list_get_entry(itr, message_t, node)->node);
303 Msg_free(list_get_entry(itr, message_t, node));
305 Client_codec_free(client);
306 Voicetarget_free_all(client);
308 list_del(&client->node);
310 SSL_free(client->ssl);
311 close(client->tcpfd);
314 free(client->release);
317 if (client->username)
318 free(client->username);
320 free(client->context);
324 void Client_close(client_t *client)
326 SSL_shutdown(client->ssl);
327 client->shutdown_wait = true;
330 void Client_disconnect_all()
332 struct dlist *itr, *save;
334 list_iterate_safe(itr, save, &clients) {
335 Client_free(list_get_entry(itr, client_t, node));
339 int Client_read_fd(int fd)
342 client_t *client = NULL;
344 list_iterate(itr, &clients) {
345 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
346 client = list_get_entry(itr, client_t, node);
351 Log_fatal("No client found for fd %d", fd);
353 return Client_read(client);
356 int Client_read(client_t *client)
360 Timer_restart(&client->lastActivity);
362 if (client->writeBlockedOnRead) {
363 client->writeBlockedOnRead = false;
364 Log_debug("Client_read: writeBlockedOnRead == true");
365 return Client_write(client);
368 if (client->shutdown_wait) {
372 if (!client->SSLready) {
374 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
383 if (!client->msgsize)
384 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
386 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
389 client->rxcount += rc;
390 if (!client->msgsize && client->rxcount >= 6) {
392 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
393 client->msgsize = ntohl(msgLen);
395 if (client->msgsize > BUFSIZE - 6) {
396 /* XXX - figure out how to handle this. A large size here can represent two cases:
397 * 1. A valid size. The only message that is this big is UserState message with a big texture
398 * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
400 Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
401 client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
404 /* client->rxcount = client->msgsize = 0; */
406 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
407 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
408 /* pass messsage to handler */
410 Mh_handle_message(client, msg);
411 client->rxcount = client->msgsize = 0;
413 } else /* rc <= 0 */ {
414 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
417 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
418 client->readBlockedOnWrite = true;
421 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
422 Log_info_client(client, "Connection closed by peer");
423 if (!client->shutdown_wait)
424 Client_close(client);
427 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
428 /* Hmm. This is where we end up when the client closes its connection.
431 Log_info_client(client, "Connection closed by peer");
434 Log_info_client(client, "SSL error: %d - Closing connection", SSL_get_error(client->ssl, rc));
440 } while (SSL_pending(client->ssl));
445 int Client_write_fd(int fd)
448 client_t *client = NULL;
450 list_iterate(itr, &clients) {
451 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
452 client = list_get_entry(itr, client_t, node);
457 Log_fatal("No client found for fd %d", fd);
458 Client_write(client);
462 int Client_write(client_t *client)
466 if (client->readBlockedOnWrite) {
467 client->readBlockedOnWrite = false;
468 Log_debug("Client_write: readBlockedOnWrite == true");
469 return Client_read(client);
471 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
473 client->txcount += rc;
474 if (client->txcount == client->txsize)
475 client->txsize = client->txcount = 0;
478 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
479 client->writeBlockedOnRead = true;
482 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
486 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
487 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
489 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
494 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
496 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
497 list_del(list_get_first(&client->txMsgQueue));
498 client->txQueueCount--;
499 Client_send_message(client, msg);
504 int Client_send_message(client_t *client, message_t *msg)
506 if (!client->authenticated && msg->messageType != Version) {
510 if (client->txsize != 0 || !client->SSLready) {
512 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
513 client->txQueueCount > 30) {
517 client->txQueueCount++;
518 list_add_tail(&msg->node, &client->txMsgQueue);
519 Log_debug("Queueing message");
522 len = Msg_messageToNetwork(msg, client->txbuf);
523 doAssert(len < BUFSIZE);
525 client->txsize = len;
527 Client_write(client);
533 client_t *Client_iterate(client_t **client_itr)
535 client_t *c = *client_itr;
537 if (list_empty(&clients))
541 c = list_get_entry(list_get_first(&clients), client_t, node);
543 if (list_get_next(&c->node) == &clients)
546 c = list_get_entry(list_get_next(&c->node), client_t, node);
553 int Client_send_message_except(client_t *client, message_t *msg)
555 client_t *itr = NULL;
558 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
559 while (Client_iterate(&itr) != NULL) {
562 Msg_inc_ref(msg); /* One extra reference for each new copy */
563 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
564 Client_send_message(itr, msg);
567 Msg_free(msg); /* Free our reference to the message */
570 Msg_free(msg); /* If only 1 client is connected then no message is passed
571 * to Client_send_message(). Free it here. */
576 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
578 if (CryptState_isValid(&client->cryptState) &&
579 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
582 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
583 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
585 Timer_restart(&client->cryptState.tLastRequest);
587 sendmsg = Msg_create(CryptSetup);
588 Log_info_client(client, "Requesting voice channel crypt resync");
589 Client_send_message(client, sendmsg);
595 #define UDP_PACKET_SIZE 1024
596 int Client_read_udp()
599 struct sockaddr_in from;
600 socklen_t fromlen = sizeof(struct sockaddr_in);
603 UDPMessageType_t msgType;
605 #if defined(__LP64__)
606 uint8_t encbuff[UDP_PACKET_SIZE + 8];
607 uint8_t *encrypted = encbuff + 4;
609 uint8_t encrypted[UDP_PACKET_SIZE];
611 uint8_t buffer[UDP_PACKET_SIZE];
613 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
616 } else if (len < 0) {
618 } else if (len < 5) {
619 // 4 bytes crypt header + type + session
621 } else if (len > UDP_PACKET_SIZE) {
626 if (len == 12 && *encrypted == 0) {
627 uint32_t *ping = (uint32_t *)encrypted;
628 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
629 // 1 and 2 will be the timestamp, which we return unmodified.
630 ping[3] = htonl((uint32_t)clientcount);
631 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
632 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
634 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
638 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
641 while (Client_iterate(&itr) != NULL) {
642 if (itr->key == key) {
643 if (!checkDecrypt(itr, encrypted, buffer, len))
648 if (itr == NULL) { /* Unknown peer */
649 while (Client_iterate(&itr) != NULL) {
650 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
651 if (checkDecrypt(itr, encrypted, buffer, len)) {
653 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
654 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
657 else Log_warn("Bad cryptstate from peer");
665 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
668 case UDPVoiceCELTAlpha:
669 case UDPVoiceCELTBeta:
671 Client_voiceMsg(itr, buffer, len);
674 Log_debug("UDP Ping reply len %d", len);
675 Client_send_udp(itr, buffer, len);
678 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
685 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
687 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
688 if (poslen > 0 && /* Has positional data */
689 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
690 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
691 Client_send_udp(dst, data, len);
693 Client_send_udp(dst, data, len - poslen);
697 /* Handle decrypted voice message */
698 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
700 uint8_t buffer[UDP_PACKET_SIZE];
701 pds_t *pdi = Pds_create(data + 1, len - 1);
702 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
703 unsigned int type = data[0] & 0xe0;
704 unsigned int target = data[0] & 0x1f;
705 unsigned int poslen, counter;
706 int offset, packetsize;
709 channel_t *ch = (channel_t *)client->channel;
712 if (!client->authenticated || client->mute)
715 packetsize = 20 + 8 + 4 + len;
716 if (client->availableBandwidth - packetsize < 0)
717 goto out; /* Discard */
718 client->availableBandwidth -= packetsize;
720 counter = Pds_get_numval(pdi); /* step past session id */
722 counter = Pds_next8(pdi);
723 offset = Pds_skip(pdi, counter & 0x7f);
724 } while ((counter & 0x80) && offset > 0);
726 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
728 Pds_add_numval(pds, client->sessionId);
729 Pds_append_data_nosize(pds, data + 1, len - 1);
731 if (target == 0x1f) { /* Loopback */
732 buffer[0] = (uint8_t) type;
733 Client_send_udp(client, buffer, pds->offset + 1);
735 else if (target == 0) { /* regular channel speech */
736 buffer[0] = (uint8_t) type;
741 list_iterate(itr, &ch->clients) {
743 c = list_get_entry(itr, client_t, chan_node);
744 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
747 if (!list_empty(&ch->channel_links)) {
748 struct dlist *ch_itr;
749 list_iterate(ch_itr, &ch->channel_links) {
751 ch_link = list_get_entry(ch_itr, channel_t, link_node);
752 list_iterate(itr, &ch_link->clients) {
754 c = list_get_entry(itr, client_t, chan_node);
755 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
756 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
760 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
764 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
765 Log_debug("Whisper channel %d", vt->channels[i]);
766 ch = Chan_fromId(vt->channels[i]);
769 list_iterate(itr, &ch->clients) {
771 c = list_get_entry(itr, client_t, chan_node);
772 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
776 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
778 Log_debug("Whisper session %d", vt->sessions[i]);
779 while (Client_iterate(&c) != NULL) {
780 if (c->sessionId == vt->sessions[i]) {
781 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
795 static int Client_send_udp(client_t *client, uint8_t *data, int len)
799 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
800 #if defined(__LP64__)
801 buf = mbuf = malloc(len + 4 + 16);
804 mbuf = buf = malloc(len + 4);
807 Log_fatal("Out of memory");
809 CryptState_encrypt(&client->cryptState, data, buf, len);
811 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
817 memcpy(buf, data, len);
818 msg = Msg_create(UDPTunnel);
820 msg->payload.UDPTunnel->packet.data = buf;
821 msg->payload.UDPTunnel->packet.len = len;
822 Client_send_message(client, msg);