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 session = 1;
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->playerName, 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("Timeout, closing session %d - %s@%s:%d",
105 inet_ntoa(c->remote_tcp.sin_addr),
106 ntohs(c->remote_tcp.sin_port));
112 void recheckCodecVersions()
114 int codec_map[MAX_CODECS][2];
115 client_t *itr = NULL;
116 int i, codecindex, max = 0, version, current_version;
119 memset(codec_map, 0, MAX_CODECS * 2 * sizeof(int));
120 while (Client_iterate(&itr) != NULL) {
121 for (i = 0; i < itr->codec_count; i++) {
122 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
123 if (codec_map[codecindex][0] == 0) {
124 codec_map[codecindex][0] = itr->codecs[i];
125 codec_map[codecindex][1] = 1;
128 if (itr->codecs[i] == codec_map[codecindex][0])
129 codec_map[codecindex][1]++;
133 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
134 if (codec_map[codecindex][0] == 0)
136 if (codec_map[codecindex][1] > max) {
137 max = codec_map[codecindex][1];
138 version = codec_map[codecindex][0];
141 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
142 if (current_version == version)
144 // If we don't already use the compat bitstream version set
145 // it as alpha and announce it. If another codec now got the
146 // majority set it as the opposite of the currently valid bPreferAlpha
148 if (version == (uint32_t)0x8000000a)
151 bPreferAlpha = ! bPreferAlpha;
154 iCodecAlpha = version;
156 iCodecBeta = version;
158 sendmsg = Msg_create(CodecVersion);
159 sendmsg->payload.codecVersion->alpha = version;
160 sendmsg->payload.codecVersion->beta = version;
161 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
162 Client_send_message_except(NULL, sendmsg);
164 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
165 bPreferAlpha ? iCodecAlpha : iCodecBeta);
169 int Client_add(int fd, struct sockaddr_in *remote)
174 newclient = malloc(sizeof(client_t));
175 if (newclient == NULL)
176 Log_fatal("Out of memory");
177 memset(newclient, 0, sizeof(client_t));
179 newclient->tcpfd = fd;
180 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
181 newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
182 if (newclient->ssl == NULL) {
183 Log_warn("SSL negotiation failed");
187 newclient->availableBandwidth = maxBandwidth;
188 Timer_init(&newclient->lastActivity);
189 newclient->sessionId = session++; /* XXX - more elaborate? */
191 init_list_entry(&newclient->txMsgQueue);
192 init_list_entry(&newclient->chan_node);
193 init_list_entry(&newclient->node);
194 init_list_entry(&newclient->voicetargets);
196 list_add_tail(&newclient->node, &clients);
199 /* Send version message to client */
200 sendmsg = Msg_create(Version);
201 sendmsg->payload.version->has_version = true;
202 sendmsg->payload.version->version = PROTOCOL_VERSION;
203 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
204 sendmsg->payload.version->os = strdup(system_string);
205 sendmsg->payload.version->os_version = strdup(version_string);
206 Client_send_message(newclient, sendmsg);
211 void Client_free(client_t *client)
213 struct dlist *itr, *save;
216 Log_info("Disconnect session %d - %s@%s:%d",
219 inet_ntoa(client->remote_tcp.sin_addr),
220 ntohs(client->remote_tcp.sin_port));
222 if (client->authenticated) {
224 leave_id = Chan_playerLeave(client);
225 if (leave_id > 0) { /* Remove temp channel */
226 sendmsg = Msg_create(ChannelRemove);
227 sendmsg->payload.channelRemove->channel_id = leave_id;
228 Client_send_message_except(client, sendmsg);
230 sendmsg = Msg_create(UserRemove);
231 sendmsg->payload.userRemove->session = client->sessionId;
232 Client_send_message_except(client, sendmsg);
234 list_iterate_safe(itr, save, &client->txMsgQueue) {
235 list_del(&list_get_entry(itr, message_t, node)->node);
236 Msg_free(list_get_entry(itr, message_t, node));
238 Voicetarget_free_all(client);
240 list_del(&client->node);
242 SSL_free(client->ssl);
243 close(client->tcpfd);
246 free(client->release);
249 if (client->playerName)
250 free(client->playerName);
252 free(client->context);
256 void Client_close(client_t *client)
258 SSL_shutdown(client->ssl);
259 client->shutdown_wait = true;
262 void Client_disconnect_all()
264 struct dlist *itr, *save;
266 list_iterate_safe(itr, save, &clients) {
267 Client_free(list_get_entry(itr, client_t, node));
271 int Client_read_fd(int fd)
274 client_t *client = NULL;
276 list_iterate(itr, &clients) {
277 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
278 client = list_get_entry(itr, client_t, node);
283 Log_fatal("No client found for fd %d", fd);
285 return Client_read(client);
288 int Client_read(client_t *client)
292 Timer_restart(&client->lastActivity);
294 if (client->writeBlockedOnRead) {
295 client->writeBlockedOnRead = false;
296 Log_debug("Client_read: writeBlockedOnRead == true");
297 return Client_write(client);
300 if (client->shutdown_wait) {
304 if (!client->SSLready) {
306 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
315 if (!client->msgsize)
316 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
317 else if (client->drainleft > 0)
318 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
320 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
323 if (client->drainleft > 0)
324 client->drainleft -= rc;
326 client->rxcount += rc;
327 if (!client->msgsize && client->rxcount >= 6) {
329 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
330 client->msgsize = ntohl(msgLen);
332 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
333 Log_warn("Too big message received (%d). Discarding.", client->msgsize);
334 client->rxcount = client->msgsize = 0;
335 client->drainleft = client->msgsize;
337 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
338 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
339 /* pass messsage to handler */
341 Mh_handle_message(client, msg);
342 client->rxcount = client->msgsize = 0;
345 } else /* rc <= 0 */ {
346 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
349 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
350 client->readBlockedOnWrite = true;
353 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
354 Log_warn("Error: Zero return - closing");
355 if (!client->shutdown_wait)
356 Client_close(client);
359 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
360 /* Hmm. This is where we end up when the client closes its connection.
363 Log_info("Connection closed by peer. Session %d - %s@%s:%d",
366 inet_ntoa(client->remote_tcp.sin_addr),
367 ntohs(client->remote_tcp.sin_port));
370 Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
376 } while (SSL_pending(client->ssl));
380 int Client_write_fd(int fd)
383 client_t *client = NULL;
385 list_iterate(itr, &clients) {
386 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
387 client = list_get_entry(itr, client_t, node);
392 Log_fatal("No client found for fd %d", fd);
393 Client_write(client);
397 int Client_write(client_t *client)
401 if (client->readBlockedOnWrite) {
402 client->readBlockedOnWrite = false;
403 Log_debug("Client_write: readBlockedOnWrite == true");
404 return Client_read(client);
406 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
408 client->txcount += rc;
409 if (client->txcount == client->txsize)
410 client->txsize = client->txcount = 0;
413 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
414 client->writeBlockedOnRead = true;
417 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
421 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
422 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
424 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
429 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
431 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
432 list_del(list_get_first(&client->txMsgQueue));
433 client->txQueueCount--;
434 Client_send_message(client, msg);
439 int Client_send_message(client_t *client, message_t *msg)
441 if (!client->authenticated && msg->messageType != Version) {
445 if (client->txsize != 0 || !client->SSLready) {
447 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
448 client->txQueueCount > 30) {
452 client->txQueueCount++;
453 list_add_tail(&msg->node, &client->txMsgQueue);
454 Log_debug("Queueing message");
457 memset(client->txbuf, 0, BUFSIZE);
458 len = Msg_messageToNetwork(msg, client->txbuf);
459 doAssert(len < BUFSIZE);
461 client->txsize = len;
463 Client_write(client);
469 client_t *Client_iterate(client_t **client_itr)
471 client_t *c = *client_itr;
473 if (list_empty(&clients))
477 c = list_get_entry(list_get_first(&clients), client_t, node);
479 if (list_get_next(&c->node) == &clients)
482 c = list_get_entry(list_get_next(&c->node), client_t, node);
489 int Client_send_message_except(client_t *client, message_t *msg)
491 client_t *itr = NULL;
494 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
495 while (Client_iterate(&itr) != NULL) {
498 Msg_inc_ref(msg); /* One extra reference for each new copy */
499 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
500 Client_send_message(itr, msg);
503 Msg_free(msg); /* Free our reference to the message */
506 Msg_free(msg); /* If only 1 client is connected then no message is passed
507 * to Client_send_message(). Free it here. */
512 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
514 if (CryptState_isValid(&client->cryptState) &&
515 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
518 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
519 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
521 Timer_restart(&client->cryptState.tLastRequest);
523 sendmsg = Msg_create(CryptSetup);
524 Log_info("Requesting voice channel crypt resync. Session %d - %s@%s:%d",
527 inet_ntoa(client->remote_tcp.sin_addr),
528 ntohs(client->remote_tcp.sin_port));
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("New UDP connection from session %d - %s@%s:%d",
597 inet_ntoa(from.sin_addr),
598 ntohs(from.sin_port));
599 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
602 else Log_warn("Bad cryptstate from peer");
610 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
613 case UDPVoiceCELTAlpha:
614 case UDPVoiceCELTBeta:
616 Client_voiceMsg(itr, buffer, len);
619 Log_debug("UDP Ping reply len %d", len);
620 Client_send_udp(itr, buffer, len);
623 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
630 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
632 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
633 if (poslen > 0 && strcmp(src->context, dst->context) == 0)
634 Client_send_udp(dst, data, len);
636 Client_send_udp(dst, data, len - poslen);
640 /* Handle decrypted voice message */
641 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
643 uint8_t buffer[UDP_PACKET_SIZE];
644 pds_t *pdi = Pds_create(data + 1, len - 1);
645 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
646 unsigned int type = data[0] & 0xe0;
647 unsigned int target = data[0] & 0x1f;
648 unsigned int poslen, counter;
649 int offset, packetsize;
652 channel_t *ch = (channel_t *)client->channel;
655 if (!client->authenticated || client->mute)
658 packetsize = 20 + 8 + 4 + len;
659 if (client->availableBandwidth - packetsize < 0)
660 goto out; /* Discard */
661 client->availableBandwidth -= packetsize;
663 counter = Pds_get_numval(pdi); /* step past session id */
665 counter = Pds_next8(pdi);
666 offset = Pds_skip(pdi, counter & 0x7f);
667 } while ((counter & 0x80) && offset > 0);
669 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
671 Pds_add_numval(pds, client->sessionId);
672 Pds_append_data_nosize(pds, data + 1, len - 1);
674 if (target == 0x1f) { /* Loopback */
675 buffer[0] = (uint8_t) type;
676 Client_send_udp(client, buffer, pds->offset + 1);
678 else if (target == 0) { /* regular channel speech */
679 buffer[0] = (uint8_t) type;
684 list_iterate(itr, &ch->clients) {
686 c = list_get_entry(itr, client_t, chan_node);
687 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
690 if (!list_empty(&ch->channel_links)) {
691 struct dlist *ch_itr;
692 list_iterate(ch_itr, &ch->channel_links) {
694 ch_link = list_get_entry(ch_itr, channel_t, link_node);
695 list_iterate(itr, &ch_link->clients) {
697 c = list_get_entry(itr, client_t, chan_node);
698 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
699 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
703 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
707 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
708 Log_debug("Whisper channel %d", vt->channels[i]);
709 ch = Chan_fromId(vt->channels[i]);
712 list_iterate(itr, &ch->clients) {
714 c = list_get_entry(itr, client_t, chan_node);
715 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
719 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
721 Log_debug("Whisper session %d", vt->sessions[i]);
722 while (Client_iterate(&c) != NULL) {
723 if (c->sessionId == vt->sessions[i]) {
724 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
738 static int Client_send_udp(client_t *client, uint8_t *data, int len)
742 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
743 #if defined(__LP64__)
744 buf = mbuf = malloc(len + 4 + 16);
747 mbuf = buf = malloc(len + 4);
750 Log_fatal("Out of memory");
752 CryptState_encrypt(&client->cryptState, data, buf, len);
754 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
760 memcpy(buf, data, len);
761 msg = Msg_create(UDPTunnel);
763 msg->payload.UDPTunnel->packet.data = buf;
764 msg->payload.UDPTunnel->packet.len = len;
765 Client_send_message(client, msg);