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>
39 #include "messagehandler.h"
43 #include "voicetarget.h"
45 static int Client_read(client_t *client);
46 static int Client_write(client_t *client);
47 static int Client_send_udp(client_t *client, uint8_t *data, int len);
48 void Client_free(client_t *client);
50 declare_list(clients);
51 static int clientcount; /* = 0 */
52 static int session = 1;
53 static int maxBandwidth;
55 int iCodecAlpha, iCodecBeta;
62 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
70 int Client_getfds(struct pollfd *pollfds)
74 list_iterate(itr, &clients) {
76 c = list_get_entry(itr, client_t, node);
77 pollfds[i].fd = c->tcpfd;
78 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
79 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
80 pollfds[i].events |= POLLOUT;
89 int bwTop = maxBandwidth + maxBandwidth / 4;
90 list_iterate(itr, &clients) {
92 c = list_get_entry(itr, client_t, node);
93 Log_debug("Client %s BW available %d", c->playerName, c->availableBandwidth);
94 c->availableBandwidth += maxBandwidth;
95 if (c->availableBandwidth > bwTop)
96 c->availableBandwidth = bwTop;
98 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
99 /* No activity from client - assume it is lost and close. */
100 Log_info("Timeout, closing session %d - %s@%s:%d",
103 inet_ntoa(c->remote_tcp.sin_addr),
104 ntohs(c->remote_tcp.sin_port));
110 void recheckCodecVersions()
112 int codec_map[MAX_CODECS][2];
113 client_t *itr = NULL;
114 int i, codecindex, max = 0, version, current_version;
117 memset(codec_map, 0, MAX_CODECS * 2 * sizeof(int));
118 while (Client_iterate(&itr) != NULL) {
119 for (i = 0; i < itr->codec_count; i++) {
120 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
121 if (codec_map[codecindex][0] == 0) {
122 codec_map[codecindex][0] = itr->codecs[i];
123 codec_map[codecindex][1] = 1;
126 if (itr->codecs[i] == codec_map[codecindex][0])
127 codec_map[codecindex][1]++;
131 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
132 if (codec_map[codecindex][0] == 0)
134 if (codec_map[codecindex][1] > max) {
135 max = codec_map[codecindex][1];
136 version = codec_map[codecindex][0];
139 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
140 if (current_version == version)
142 // If we don't already use the compat bitstream version set
143 // it as alpha and announce it. If another codec now got the
144 // majority set it as the opposite of the currently valid bPreferAlpha
146 if (version == (uint32_t)0x8000000a)
149 bPreferAlpha = ! bPreferAlpha;
152 iCodecAlpha = version;
154 iCodecBeta = version;
156 sendmsg = Msg_create(CodecVersion);
157 sendmsg->payload.codecVersion->alpha = version;
158 sendmsg->payload.codecVersion->beta = version;
159 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
160 Client_send_message_except(NULL, sendmsg);
162 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
163 bPreferAlpha ? iCodecAlpha : iCodecBeta);
167 int Client_add(int fd, struct sockaddr_in *remote)
172 newclient = malloc(sizeof(client_t));
173 if (newclient == NULL)
174 Log_fatal("Out of memory");
175 memset(newclient, 0, sizeof(client_t));
177 newclient->tcpfd = fd;
178 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
179 newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
180 if (newclient->ssl == NULL) {
181 Log_warn("SSL negotiation failed");
185 newclient->availableBandwidth = maxBandwidth;
186 Timer_init(&newclient->lastActivity);
187 newclient->sessionId = session++; /* XXX - more elaborate? */
189 init_list_entry(&newclient->txMsgQueue);
190 init_list_entry(&newclient->chan_node);
191 init_list_entry(&newclient->node);
192 init_list_entry(&newclient->voicetargets);
194 list_add_tail(&newclient->node, &clients);
197 /* Send version message to client */
198 sendmsg = Msg_create(Version);
199 sendmsg->payload.version->has_version = true;
200 sendmsg->payload.version->version = PROTOCOL_VERSION;
201 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
202 /* XXX - set OS to something relevant? */
203 /* sendmsg->payload.version->os = strdup("Linux/OpenWRT"); */
205 Client_send_message(newclient, sendmsg);
210 void Client_free(client_t *client)
212 struct dlist *itr, *save;
215 Log_info("Disconnect session %d - %s@%s:%d",
218 inet_ntoa(client->remote_tcp.sin_addr),
219 ntohs(client->remote_tcp.sin_port));
221 if (client->authenticated) {
222 sendmsg = Msg_create(UserRemove);
223 sendmsg->payload.userRemove->session = client->sessionId;
224 Client_send_message_except(client, sendmsg);
226 list_iterate_safe(itr, save, &client->txMsgQueue) {
227 list_del(&list_get_entry(itr, message_t, node)->node);
228 Msg_free(list_get_entry(itr, message_t, node));
230 Voicetarget_free_all(client);
232 list_del(&client->node);
233 list_del(&client->chan_node);
235 SSL_free(client->ssl);
236 close(client->tcpfd);
239 free(client->release);
242 if (client->playerName)
243 free(client->playerName);
245 free(client->context);
249 void Client_close(client_t *client)
251 SSL_shutdown(client->ssl);
252 client->shutdown_wait = true;
255 void Client_disconnect_all()
257 struct dlist *itr, *save;
259 list_iterate_safe(itr, save, &clients) {
260 Client_free(list_get_entry(itr, client_t, node));
264 int Client_read_fd(int fd)
267 client_t *client = NULL;
269 list_iterate(itr, &clients) {
270 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
271 client = list_get_entry(itr, client_t, node);
276 Log_fatal("No client found for fd %d", fd);
278 return Client_read(client);
281 int Client_read(client_t *client)
285 Timer_restart(&client->lastActivity);
287 if (client->writeBlockedOnRead) {
288 client->writeBlockedOnRead = false;
289 Log_debug("Client_read: writeBlockedOnRead == true");
290 return Client_write(client);
293 if (client->shutdown_wait) {
297 if (!client->SSLready) {
299 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
308 if (!client->msgsize)
309 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
310 else if (client->drainleft > 0)
311 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
313 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
316 if (client->drainleft > 0)
317 client->drainleft -= rc;
319 client->rxcount += rc;
320 if (!client->msgsize && client->rxcount >= 6) {
322 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
323 client->msgsize = ntohl(msgLen);
325 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
326 Log_warn("Too big message received (%d). Discarding.", client->msgsize);
327 client->rxcount = client->msgsize = 0;
328 client->drainleft = client->msgsize;
330 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
331 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
332 /* pass messsage to handler */
334 Mh_handle_message(client, msg);
335 client->rxcount = client->msgsize = 0;
338 } else /* rc <= 0 */ {
339 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
342 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
343 client->readBlockedOnWrite = true;
346 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
347 Log_warn("Error: Zero return - closing");
348 if (!client->shutdown_wait)
349 Client_close(client);
352 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
353 /* Hmm. This is where we end up when the client closes its connection.
356 Log_info("Connection closed by peer. Session %d - %s@%s:%d",
359 inet_ntoa(client->remote_tcp.sin_addr),
360 ntohs(client->remote_tcp.sin_port));
363 Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
369 } while (SSL_pending(client->ssl));
373 int Client_write_fd(int fd)
376 client_t *client = NULL;
378 list_iterate(itr, &clients) {
379 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
380 client = list_get_entry(itr, client_t, node);
385 Log_fatal("No client found for fd %d", fd);
386 Client_write(client);
390 int Client_write(client_t *client)
394 if (client->readBlockedOnWrite) {
395 client->readBlockedOnWrite = false;
396 Log_debug("Client_write: readBlockedOnWrite == true");
397 return Client_read(client);
399 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
401 client->txcount += rc;
402 if (client->txcount == client->txsize)
403 client->txsize = client->txcount = 0;
406 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
407 client->writeBlockedOnRead = true;
410 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
414 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
415 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
417 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
422 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
424 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
425 list_del(list_get_first(&client->txMsgQueue));
426 client->txQueueCount--;
427 Client_send_message(client, msg);
432 int Client_send_message(client_t *client, message_t *msg)
434 if (!client->authenticated && msg->messageType != Version) {
438 if (client->txsize != 0 || !client->SSLready) {
440 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
441 client->txQueueCount > 30) {
445 client->txQueueCount++;
446 list_add_tail(&msg->node, &client->txMsgQueue);
447 Log_debug("Queueing message");
450 memset(client->txbuf, 0, BUFSIZE);
451 len = Msg_messageToNetwork(msg, client->txbuf);
452 doAssert(len < BUFSIZE);
454 client->txsize = len;
456 Client_write(client);
462 client_t *Client_iterate(client_t **client_itr)
464 client_t *c = *client_itr;
466 if (list_empty(&clients))
470 c = list_get_entry(list_get_first(&clients), client_t, node);
472 if (list_get_next(&c->node) == &clients)
475 c = list_get_entry(list_get_next(&c->node), client_t, node);
482 int Client_send_message_except(client_t *client, message_t *msg)
484 client_t *itr = NULL;
487 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
488 while (Client_iterate(&itr) != NULL) {
491 Msg_inc_ref(msg); /* One extra reference for each new copy */
492 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
493 Client_send_message(itr, msg);
496 Msg_free(msg); /* Free our reference to the message */
499 Msg_free(msg); /* If only 1 client is connected then no message is passed
500 * to Client_send_message(). Free it here. */
505 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
507 if (CryptState_isValid(&client->cryptState) &&
508 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
511 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
512 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
514 Timer_restart(&client->cryptState.tLastRequest);
516 sendmsg = Msg_create(CryptSetup);
517 Log_info("Requesting voice channel crypt resync. Session %d - %s@%s:%d",
520 inet_ntoa(client->remote_tcp.sin_addr),
521 ntohs(client->remote_tcp.sin_port));
523 Client_send_message(client, sendmsg);
529 #define UDP_PACKET_SIZE 1024
530 int Client_read_udp()
533 struct sockaddr_in from;
534 socklen_t fromlen = sizeof(struct sockaddr_in);
537 UDPMessageType_t msgType;
539 #if defined(__LP64__)
540 uint8_t encbuff[UDP_PACKET_SIZE + 8];
541 uint8_t *encrypted = encbuff + 4;
543 uint8_t encrypted[UDP_PACKET_SIZE];
545 uint8_t buffer[UDP_PACKET_SIZE];
547 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
550 } else if (len < 0) {
552 } else if (len < 5) {
553 // 4 bytes crypt header + type + session
555 } else if (len > UDP_PACKET_SIZE) {
560 if (len == 12 && *encrypted == 0) {
561 uint32_t *ping = (uint32_t *)encrypted;
562 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
563 // 1 and 2 will be the timestamp, which we return unmodified.
564 ping[3] = htonl((uint32_t)clientcount);
565 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
566 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
568 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
572 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
575 while (Client_iterate(&itr) != NULL) {
576 if (itr->key == key) {
577 if (!checkDecrypt(itr, encrypted, buffer, len))
582 if (itr == NULL) { /* Unknown peer */
583 while (Client_iterate(&itr) != NULL) {
584 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
585 if (checkDecrypt(itr, encrypted, buffer, len)) {
587 Log_info("New UDP connection from session %d - %s@%s:%d",
590 inet_ntoa(from.sin_addr),
591 ntohs(from.sin_port));
592 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
595 else Log_warn("Bad cryptstate from peer");
603 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
606 case UDPVoiceCELTAlpha:
607 case UDPVoiceCELTBeta:
609 Client_voiceMsg(itr, buffer, len);
612 Log_debug("UDP Ping reply len %d", len);
613 Client_send_udp(itr, buffer, len);
616 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
623 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
625 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
626 if (poslen > 0 && strcmp(src->context, dst->context) == 0)
627 Client_send_udp(dst, data, len);
629 Client_send_udp(dst, data, len - poslen);
633 /* Handle decrypted voice message */
634 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
636 uint8_t buffer[UDP_PACKET_SIZE];
637 pds_t *pdi = Pds_create(data + 1, len - 1);
638 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
639 unsigned int type = data[0] & 0xe0;
640 unsigned int target = data[0] & 0x1f;
641 unsigned int poslen, counter;
642 int offset, packetsize;
645 channel_t *ch = (channel_t *)client->channel;
648 if (!client->authenticated || client->mute)
651 packetsize = 20 + 8 + 4 + len;
652 if (client->availableBandwidth - packetsize < 0)
653 goto out; /* Discard */
654 client->availableBandwidth -= packetsize;
656 counter = Pds_get_numval(pdi); /* step past session id */
658 counter = Pds_next8(pdi);
659 offset = Pds_skip(pdi, counter & 0x7f);
660 } while ((counter & 0x80) && offset > 0);
662 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
664 Pds_add_numval(pds, client->sessionId);
665 Pds_append_data_nosize(pds, data + 1, len - 1);
667 if (target == 0x1f) { /* Loopback */
668 buffer[0] = (uint8_t) type;
669 Client_send_udp(client, buffer, pds->offset + 1);
671 else if (target == 0) { /* regular channel speech */
672 buffer[0] = (uint8_t) type;
677 list_iterate(itr, &ch->clients) {
679 c = list_get_entry(itr, client_t, chan_node);
680 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
683 if (!list_empty(&ch->channel_links)) {
684 struct dlist *ch_itr;
685 list_iterate(ch_itr, &ch->channel_links) {
687 ch_link = list_get_entry(ch_itr, channel_t, link_node);
688 list_iterate(itr, &ch_link->clients) {
690 c = list_get_entry(itr, client_t, chan_node);
691 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
692 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
696 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
700 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
701 Log_debug("Whisper channel %d", vt->channels[i]);
702 ch = Chan_fromId(vt->channels[i]);
705 list_iterate(itr, &ch->clients) {
707 c = list_get_entry(itr, client_t, chan_node);
708 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
712 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
714 Log_debug("Whisper session %d", vt->sessions[i]);
715 while (Client_iterate(&c) != NULL) {
716 if (c->sessionId == vt->sessions[i]) {
717 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
731 static int Client_send_udp(client_t *client, uint8_t *data, int len)
735 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
736 #if defined(__LP64__)
737 buf = mbuf = malloc(len + 4 + 16);
740 mbuf = buf = malloc(len + 4);
743 Log_fatal("Out of memory");
745 CryptState_encrypt(&client->cryptState, data, buf, len);
747 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
753 memcpy(buf, data, len);
754 msg = Msg_create(UDPTunnel);
756 msg->payload.UDPTunnel->packet.data = buf;
757 msg->payload.UDPTunnel->packet.len = len;
758 Client_send_message(client, msg);