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);
385 else if (client->drainleft > 0)
386 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
388 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
391 if (client->drainleft > 0)
392 client->drainleft -= rc;
394 client->rxcount += rc;
395 if (!client->msgsize && client->rxcount >= 6) {
397 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
398 client->msgsize = ntohl(msgLen);
400 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
401 Log_info_client(client, "Too big message received (%d bytes). Discarding.", client->msgsize);
402 client->rxcount = client->msgsize = 0;
403 client->drainleft = client->msgsize;
405 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
406 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
407 /* pass messsage to handler */
409 Mh_handle_message(client, msg);
410 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));
444 int Client_write_fd(int fd)
447 client_t *client = NULL;
449 list_iterate(itr, &clients) {
450 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
451 client = list_get_entry(itr, client_t, node);
456 Log_fatal("No client found for fd %d", fd);
457 Client_write(client);
461 int Client_write(client_t *client)
465 if (client->readBlockedOnWrite) {
466 client->readBlockedOnWrite = false;
467 Log_debug("Client_write: readBlockedOnWrite == true");
468 return Client_read(client);
470 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
472 client->txcount += rc;
473 if (client->txcount == client->txsize)
474 client->txsize = client->txcount = 0;
477 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
478 client->writeBlockedOnRead = true;
481 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
485 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
486 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
488 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
493 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
495 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
496 list_del(list_get_first(&client->txMsgQueue));
497 client->txQueueCount--;
498 Client_send_message(client, msg);
503 int Client_send_message(client_t *client, message_t *msg)
505 if (!client->authenticated && msg->messageType != Version) {
509 if (client->txsize != 0 || !client->SSLready) {
511 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
512 client->txQueueCount > 30) {
516 client->txQueueCount++;
517 list_add_tail(&msg->node, &client->txMsgQueue);
518 Log_debug("Queueing message");
521 len = Msg_messageToNetwork(msg, client->txbuf);
522 doAssert(len < BUFSIZE);
524 client->txsize = len;
526 Client_write(client);
532 client_t *Client_iterate(client_t **client_itr)
534 client_t *c = *client_itr;
536 if (list_empty(&clients))
540 c = list_get_entry(list_get_first(&clients), client_t, node);
542 if (list_get_next(&c->node) == &clients)
545 c = list_get_entry(list_get_next(&c->node), client_t, node);
552 int Client_send_message_except(client_t *client, message_t *msg)
554 client_t *itr = NULL;
557 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
558 while (Client_iterate(&itr) != NULL) {
561 Msg_inc_ref(msg); /* One extra reference for each new copy */
562 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
563 Client_send_message(itr, msg);
566 Msg_free(msg); /* Free our reference to the message */
569 Msg_free(msg); /* If only 1 client is connected then no message is passed
570 * to Client_send_message(). Free it here. */
575 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
577 if (CryptState_isValid(&client->cryptState) &&
578 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
581 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
582 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
584 Timer_restart(&client->cryptState.tLastRequest);
586 sendmsg = Msg_create(CryptSetup);
587 Log_info_client(client, "Requesting voice channel crypt resync");
588 Client_send_message(client, sendmsg);
594 #define UDP_PACKET_SIZE 1024
595 int Client_read_udp()
598 struct sockaddr_in from;
599 socklen_t fromlen = sizeof(struct sockaddr_in);
602 UDPMessageType_t msgType;
604 #if defined(__LP64__)
605 uint8_t encbuff[UDP_PACKET_SIZE + 8];
606 uint8_t *encrypted = encbuff + 4;
608 uint8_t encrypted[UDP_PACKET_SIZE];
610 uint8_t buffer[UDP_PACKET_SIZE];
612 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
615 } else if (len < 0) {
617 } else if (len < 5) {
618 // 4 bytes crypt header + type + session
620 } else if (len > UDP_PACKET_SIZE) {
625 if (len == 12 && *encrypted == 0) {
626 uint32_t *ping = (uint32_t *)encrypted;
627 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
628 // 1 and 2 will be the timestamp, which we return unmodified.
629 ping[3] = htonl((uint32_t)clientcount);
630 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
631 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
633 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
637 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
640 while (Client_iterate(&itr) != NULL) {
641 if (itr->key == key) {
642 if (!checkDecrypt(itr, encrypted, buffer, len))
647 if (itr == NULL) { /* Unknown peer */
648 while (Client_iterate(&itr) != NULL) {
649 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
650 if (checkDecrypt(itr, encrypted, buffer, len)) {
652 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
653 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
656 else Log_warn("Bad cryptstate from peer");
664 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
667 case UDPVoiceCELTAlpha:
668 case UDPVoiceCELTBeta:
670 Client_voiceMsg(itr, buffer, len);
673 Log_debug("UDP Ping reply len %d", len);
674 Client_send_udp(itr, buffer, len);
677 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
684 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
686 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
687 if (poslen > 0 && /* Has positional data */
688 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
689 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
690 Client_send_udp(dst, data, len);
692 Client_send_udp(dst, data, len - poslen);
696 /* Handle decrypted voice message */
697 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
699 uint8_t buffer[UDP_PACKET_SIZE];
700 pds_t *pdi = Pds_create(data + 1, len - 1);
701 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
702 unsigned int type = data[0] & 0xe0;
703 unsigned int target = data[0] & 0x1f;
704 unsigned int poslen, counter;
705 int offset, packetsize;
708 channel_t *ch = (channel_t *)client->channel;
711 if (!client->authenticated || client->mute)
714 packetsize = 20 + 8 + 4 + len;
715 if (client->availableBandwidth - packetsize < 0)
716 goto out; /* Discard */
717 client->availableBandwidth -= packetsize;
719 counter = Pds_get_numval(pdi); /* step past session id */
721 counter = Pds_next8(pdi);
722 offset = Pds_skip(pdi, counter & 0x7f);
723 } while ((counter & 0x80) && offset > 0);
725 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
727 Pds_add_numval(pds, client->sessionId);
728 Pds_append_data_nosize(pds, data + 1, len - 1);
730 if (target == 0x1f) { /* Loopback */
731 buffer[0] = (uint8_t) type;
732 Client_send_udp(client, buffer, pds->offset + 1);
734 else if (target == 0) { /* regular channel speech */
735 buffer[0] = (uint8_t) type;
740 list_iterate(itr, &ch->clients) {
742 c = list_get_entry(itr, client_t, chan_node);
743 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
746 if (!list_empty(&ch->channel_links)) {
747 struct dlist *ch_itr;
748 list_iterate(ch_itr, &ch->channel_links) {
750 ch_link = list_get_entry(ch_itr, channel_t, link_node);
751 list_iterate(itr, &ch_link->clients) {
753 c = list_get_entry(itr, client_t, chan_node);
754 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
755 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
759 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
763 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
764 Log_debug("Whisper channel %d", vt->channels[i]);
765 ch = Chan_fromId(vt->channels[i]);
768 list_iterate(itr, &ch->clients) {
770 c = list_get_entry(itr, client_t, chan_node);
771 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
775 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
777 Log_debug("Whisper session %d", vt->sessions[i]);
778 while (Client_iterate(&c) != NULL) {
779 if (c->sessionId == vt->sessions[i]) {
780 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
794 static int Client_send_udp(client_t *client, uint8_t *data, int len)
798 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
799 #if defined(__LP64__)
800 buf = mbuf = malloc(len + 4 + 16);
803 mbuf = buf = malloc(len + 4);
806 Log_fatal("Out of memory");
808 CryptState_encrypt(&client->cryptState, data, buf, len);
810 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
816 memcpy(buf, data, len);
817 msg = Msg_create(UDPTunnel);
819 msg->payload.UDPTunnel->packet.data = buf;
820 msg->payload.UDPTunnel->packet.len = len;
821 Client_send_message(client, msg);