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 extern char system_string[], version_string[];
47 static int Client_read(client_t *client);
48 static int Client_write(client_t *client);
49 static int Client_send_udp(client_t *client, uint8_t *data, int len);
50 void Client_free(client_t *client);
52 declare_list(clients);
53 static int clientcount; /* = 0 */
54 static int maxBandwidth;
56 int iCodecAlpha, iCodecBeta;
63 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
71 int Client_getfds(struct pollfd *pollfds)
75 list_iterate(itr, &clients) {
77 c = list_get_entry(itr, client_t, node);
78 pollfds[i].fd = c->tcpfd;
79 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
80 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
81 pollfds[i].events |= POLLOUT;
90 int bwTop = maxBandwidth + maxBandwidth / 4;
91 list_iterate(itr, &clients) {
93 c = list_get_entry(itr, client_t, node);
94 Log_debug("Client %s BW available %d", c->playerName, c->availableBandwidth);
95 c->availableBandwidth += maxBandwidth;
96 if (c->availableBandwidth > bwTop)
97 c->availableBandwidth = bwTop;
99 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
100 /* No activity from client - assume it is lost and close. */
101 Log_info_client(c, "Timeout, closing.");
107 void recheckCodecVersions()
109 int codec_map[MAX_CODECS][2];
110 client_t *itr = NULL;
111 int i, codecindex, max = 0, version, current_version;
114 memset(codec_map, 0, MAX_CODECS * 2 * sizeof(int));
115 while (Client_iterate(&itr) != NULL) {
116 for (i = 0; i < itr->codec_count; i++) {
117 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
118 if (codec_map[codecindex][0] == 0) {
119 codec_map[codecindex][0] = itr->codecs[i];
120 codec_map[codecindex][1] = 1;
123 if (itr->codecs[i] == codec_map[codecindex][0])
124 codec_map[codecindex][1]++;
128 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
129 if (codec_map[codecindex][0] == 0)
131 if (codec_map[codecindex][1] > max) {
132 max = codec_map[codecindex][1];
133 version = codec_map[codecindex][0];
136 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
137 if (current_version == version)
139 // If we don't already use the compat bitstream version set
140 // it as alpha and announce it. If another codec now got the
141 // majority set it as the opposite of the currently valid bPreferAlpha
143 if (version == (uint32_t)0x8000000a)
146 bPreferAlpha = ! bPreferAlpha;
149 iCodecAlpha = version;
151 iCodecBeta = version;
153 sendmsg = Msg_create(CodecVersion);
154 sendmsg->payload.codecVersion->alpha = version;
155 sendmsg->payload.codecVersion->beta = version;
156 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
157 Client_send_message_except(NULL, sendmsg);
159 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
160 bPreferAlpha ? iCodecAlpha : iCodecBeta);
164 static int findFreeSessionId()
167 client_t *itr = NULL;
169 for (id = 1; id < INT_MAX; id++) {
171 while ((itr = Client_iterate(&itr)) != NULL) {
172 if (itr->sessionId == id)
175 if (itr == NULL) /* Found free id */
181 int Client_add(int fd, struct sockaddr_in *remote)
186 newclient = malloc(sizeof(client_t));
187 if (newclient == NULL)
188 Log_fatal("Out of memory");
189 memset(newclient, 0, sizeof(client_t));
191 newclient->tcpfd = fd;
192 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
193 newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
194 if (newclient->ssl == NULL) {
195 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
196 ntohs(remote->sin_port));
200 newclient->availableBandwidth = maxBandwidth;
201 Timer_init(&newclient->lastActivity);
202 newclient->sessionId = findFreeSessionId();
203 if (newclient->sessionId < 0)
204 Log_fatal("Could not find a free session ID");
206 init_list_entry(&newclient->txMsgQueue);
207 init_list_entry(&newclient->chan_node);
208 init_list_entry(&newclient->node);
209 init_list_entry(&newclient->voicetargets);
211 list_add_tail(&newclient->node, &clients);
214 /* Send version message to client */
215 sendmsg = Msg_create(Version);
216 sendmsg->payload.version->has_version = true;
217 sendmsg->payload.version->version = PROTOCOL_VERSION;
218 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
219 sendmsg->payload.version->os = strdup(system_string);
220 sendmsg->payload.version->os_version = strdup(version_string);
221 Client_send_message(newclient, sendmsg);
226 void Client_free(client_t *client)
228 struct dlist *itr, *save;
231 if (client->authenticated) {
233 leave_id = Chan_playerLeave(client);
234 if (leave_id > 0) { /* Remove temp channel */
235 sendmsg = Msg_create(ChannelRemove);
236 sendmsg->payload.channelRemove->channel_id = leave_id;
237 Client_send_message_except(client, sendmsg);
239 sendmsg = Msg_create(UserRemove);
240 sendmsg->payload.userRemove->session = client->sessionId;
241 Client_send_message_except(client, sendmsg);
243 list_iterate_safe(itr, save, &client->txMsgQueue) {
244 list_del(&list_get_entry(itr, message_t, node)->node);
245 Msg_free(list_get_entry(itr, message_t, node));
247 Voicetarget_free_all(client);
249 list_del(&client->node);
251 SSL_free(client->ssl);
252 close(client->tcpfd);
255 free(client->release);
258 if (client->playerName)
259 free(client->playerName);
261 free(client->context);
265 void Client_close(client_t *client)
267 SSL_shutdown(client->ssl);
268 client->shutdown_wait = true;
271 void Client_disconnect_all()
273 struct dlist *itr, *save;
275 list_iterate_safe(itr, save, &clients) {
276 Client_free(list_get_entry(itr, client_t, node));
280 int Client_read_fd(int fd)
283 client_t *client = NULL;
285 list_iterate(itr, &clients) {
286 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
287 client = list_get_entry(itr, client_t, node);
292 Log_fatal("No client found for fd %d", fd);
294 return Client_read(client);
297 int Client_read(client_t *client)
301 Timer_restart(&client->lastActivity);
303 if (client->writeBlockedOnRead) {
304 client->writeBlockedOnRead = false;
305 Log_debug("Client_read: writeBlockedOnRead == true");
306 return Client_write(client);
309 if (client->shutdown_wait) {
313 if (!client->SSLready) {
315 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
324 if (!client->msgsize)
325 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
326 else if (client->drainleft > 0)
327 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
329 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
332 if (client->drainleft > 0)
333 client->drainleft -= rc;
335 client->rxcount += rc;
336 if (!client->msgsize && client->rxcount >= 6) {
338 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
339 client->msgsize = ntohl(msgLen);
341 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
342 Log_info_client(client, "Too big message received (%d bytes). Discarding.", client->msgsize);
343 client->rxcount = client->msgsize = 0;
344 client->drainleft = client->msgsize;
346 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
347 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
348 /* pass messsage to handler */
350 Mh_handle_message(client, msg);
351 client->rxcount = client->msgsize = 0;
354 } else /* rc <= 0 */ {
355 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
358 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
359 client->readBlockedOnWrite = true;
362 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
363 Log_info_client(client, "Connection closed by peer");
364 if (!client->shutdown_wait)
365 Client_close(client);
368 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
369 /* Hmm. This is where we end up when the client closes its connection.
372 Log_info_client(client, "Connection closed by peer");
375 Log_info_client(client, "SSL error: %d - Closing connection", SSL_get_error(client->ssl, rc));
381 } while (SSL_pending(client->ssl));
385 int Client_write_fd(int fd)
388 client_t *client = NULL;
390 list_iterate(itr, &clients) {
391 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
392 client = list_get_entry(itr, client_t, node);
397 Log_fatal("No client found for fd %d", fd);
398 Client_write(client);
402 int Client_write(client_t *client)
406 if (client->readBlockedOnWrite) {
407 client->readBlockedOnWrite = false;
408 Log_debug("Client_write: readBlockedOnWrite == true");
409 return Client_read(client);
411 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
413 client->txcount += rc;
414 if (client->txcount == client->txsize)
415 client->txsize = client->txcount = 0;
418 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
419 client->writeBlockedOnRead = true;
422 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
426 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
427 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
429 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
434 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
436 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
437 list_del(list_get_first(&client->txMsgQueue));
438 client->txQueueCount--;
439 Client_send_message(client, msg);
444 int Client_send_message(client_t *client, message_t *msg)
446 if (!client->authenticated && msg->messageType != Version) {
450 if (client->txsize != 0 || !client->SSLready) {
452 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
453 client->txQueueCount > 30) {
457 client->txQueueCount++;
458 list_add_tail(&msg->node, &client->txMsgQueue);
459 Log_debug("Queueing message");
462 memset(client->txbuf, 0, BUFSIZE);
463 len = Msg_messageToNetwork(msg, client->txbuf);
464 doAssert(len < BUFSIZE);
466 client->txsize = len;
468 Client_write(client);
474 client_t *Client_iterate(client_t **client_itr)
476 client_t *c = *client_itr;
478 if (list_empty(&clients))
482 c = list_get_entry(list_get_first(&clients), client_t, node);
484 if (list_get_next(&c->node) == &clients)
487 c = list_get_entry(list_get_next(&c->node), client_t, node);
494 int Client_send_message_except(client_t *client, message_t *msg)
496 client_t *itr = NULL;
499 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
500 while (Client_iterate(&itr) != NULL) {
503 Msg_inc_ref(msg); /* One extra reference for each new copy */
504 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
505 Client_send_message(itr, msg);
508 Msg_free(msg); /* Free our reference to the message */
511 Msg_free(msg); /* If only 1 client is connected then no message is passed
512 * to Client_send_message(). Free it here. */
517 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
519 if (CryptState_isValid(&client->cryptState) &&
520 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
523 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
524 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
526 Timer_restart(&client->cryptState.tLastRequest);
528 sendmsg = Msg_create(CryptSetup);
529 Log_info_client(client, "Requesting voice channel crypt resync");
530 Client_send_message(client, sendmsg);
536 #define UDP_PACKET_SIZE 1024
537 int Client_read_udp()
540 struct sockaddr_in from;
541 socklen_t fromlen = sizeof(struct sockaddr_in);
544 UDPMessageType_t msgType;
546 #if defined(__LP64__)
547 uint8_t encbuff[UDP_PACKET_SIZE + 8];
548 uint8_t *encrypted = encbuff + 4;
550 uint8_t encrypted[UDP_PACKET_SIZE];
552 uint8_t buffer[UDP_PACKET_SIZE];
554 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
557 } else if (len < 0) {
559 } else if (len < 5) {
560 // 4 bytes crypt header + type + session
562 } else if (len > UDP_PACKET_SIZE) {
567 if (len == 12 && *encrypted == 0) {
568 uint32_t *ping = (uint32_t *)encrypted;
569 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
570 // 1 and 2 will be the timestamp, which we return unmodified.
571 ping[3] = htonl((uint32_t)clientcount);
572 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
573 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
575 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
579 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
582 while (Client_iterate(&itr) != NULL) {
583 if (itr->key == key) {
584 if (!checkDecrypt(itr, encrypted, buffer, len))
589 if (itr == NULL) { /* Unknown peer */
590 while (Client_iterate(&itr) != NULL) {
591 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
592 if (checkDecrypt(itr, encrypted, buffer, len)) {
594 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
595 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
598 else Log_warn("Bad cryptstate from peer");
606 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
609 case UDPVoiceCELTAlpha:
610 case UDPVoiceCELTBeta:
612 Client_voiceMsg(itr, buffer, len);
615 Log_debug("UDP Ping reply len %d", len);
616 Client_send_udp(itr, buffer, len);
619 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
626 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
628 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
629 if (poslen > 0 && /* Has positional data */
630 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
631 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
632 Client_send_udp(dst, data, len);
634 Client_send_udp(dst, data, len - poslen);
638 /* Handle decrypted voice message */
639 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
641 uint8_t buffer[UDP_PACKET_SIZE];
642 pds_t *pdi = Pds_create(data + 1, len - 1);
643 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
644 unsigned int type = data[0] & 0xe0;
645 unsigned int target = data[0] & 0x1f;
646 unsigned int poslen, counter;
647 int offset, packetsize;
650 channel_t *ch = (channel_t *)client->channel;
653 if (!client->authenticated || client->mute)
656 packetsize = 20 + 8 + 4 + len;
657 if (client->availableBandwidth - packetsize < 0)
658 goto out; /* Discard */
659 client->availableBandwidth -= packetsize;
661 counter = Pds_get_numval(pdi); /* step past session id */
663 counter = Pds_next8(pdi);
664 offset = Pds_skip(pdi, counter & 0x7f);
665 } while ((counter & 0x80) && offset > 0);
667 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
669 Pds_add_numval(pds, client->sessionId);
670 Pds_append_data_nosize(pds, data + 1, len - 1);
672 if (target == 0x1f) { /* Loopback */
673 buffer[0] = (uint8_t) type;
674 Client_send_udp(client, buffer, pds->offset + 1);
676 else if (target == 0) { /* regular channel speech */
677 buffer[0] = (uint8_t) type;
682 list_iterate(itr, &ch->clients) {
684 c = list_get_entry(itr, client_t, chan_node);
685 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
688 if (!list_empty(&ch->channel_links)) {
689 struct dlist *ch_itr;
690 list_iterate(ch_itr, &ch->channel_links) {
692 ch_link = list_get_entry(ch_itr, channel_t, link_node);
693 list_iterate(itr, &ch_link->clients) {
695 c = list_get_entry(itr, client_t, chan_node);
696 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
697 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
701 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
705 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
706 Log_debug("Whisper channel %d", vt->channels[i]);
707 ch = Chan_fromId(vt->channels[i]);
710 list_iterate(itr, &ch->clients) {
712 c = list_get_entry(itr, client_t, chan_node);
713 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
717 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
719 Log_debug("Whisper session %d", vt->sessions[i]);
720 while (Client_iterate(&c) != NULL) {
721 if (c->sessionId == vt->sessions[i]) {
722 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
736 static int Client_send_udp(client_t *client, uint8_t *data, int len)
740 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
741 #if defined(__LP64__)
742 buf = mbuf = malloc(len + 4 + 16);
745 mbuf = buf = malloc(len + 4);
748 Log_fatal("Out of memory");
750 CryptState_encrypt(&client->cryptState, data, buf, len);
752 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
758 memcpy(buf, data, len);
759 msg = Msg_create(UDPTunnel);
761 msg->payload.UDPTunnel->packet.data = buf;
762 msg->payload.UDPTunnel->packet.len = len;
763 Client_send_message(client, msg);