1 /* Copyright (C) 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("Session ID %d timeout - closing", c->sessionId);
106 void recheckCodecVersions()
108 int codec_map[MAX_CODECS][2];
109 client_t *itr = NULL;
110 int i, codecindex, max = 0, version, current_version;
113 memset(codec_map, 0, MAX_CODECS * 2 * sizeof(int));
114 while (Client_iterate(&itr) != NULL) {
115 for (i = 0; i < itr->codec_count; i++) {
116 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
117 if (codec_map[codecindex][0] == 0) {
118 codec_map[codecindex][0] = itr->codecs[i];
119 codec_map[codecindex][1] = 1;
122 if (itr->codecs[i] == codec_map[codecindex][0])
123 codec_map[codecindex][1]++;
127 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
128 if (codec_map[codecindex][0] == 0)
130 if (codec_map[codecindex][1] > max) {
131 max = codec_map[codecindex][1];
132 version = codec_map[codecindex][0];
135 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
136 if (current_version == version)
138 // If we don't already use the compat bitstream version set
139 // it as alpha and announce it. If another codec now got the
140 // majority set it as the opposite of the currently valid bPreferAlpha
142 if (version == (uint32_t)0x8000000a)
145 bPreferAlpha = ! bPreferAlpha;
148 iCodecAlpha = version;
150 iCodecBeta = version;
152 sendmsg = Msg_create(CodecVersion);
153 sendmsg->payload.codecVersion->alpha = version;
154 sendmsg->payload.codecVersion->beta = version;
155 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
156 Client_send_message_except(NULL, sendmsg);
158 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
159 bPreferAlpha ? iCodecAlpha : iCodecBeta);
163 int Client_add(int fd, struct sockaddr_in *remote)
168 newclient = malloc(sizeof(client_t));
169 if (newclient == NULL)
170 Log_fatal("Out of memory");
171 memset(newclient, 0, sizeof(client_t));
173 newclient->tcpfd = fd;
174 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
175 newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
176 if (newclient->ssl == NULL) {
177 Log_warn("SSL negotiation failed");
181 newclient->availableBandwidth = maxBandwidth;
182 Timer_init(&newclient->lastActivity);
183 newclient->sessionId = session++; /* XXX - more elaborate? */
185 init_list_entry(&newclient->txMsgQueue);
186 init_list_entry(&newclient->chan_node);
187 init_list_entry(&newclient->node);
188 init_list_entry(&newclient->voicetargets);
190 list_add_tail(&newclient->node, &clients);
193 /* Send version message to client */
194 sendmsg = Msg_create(Version);
195 sendmsg->payload.version->has_version = true;
196 sendmsg->payload.version->version = PROTOCOL_VERSION;
197 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
198 /* XXX - set OS to something relevant? */
199 /* sendmsg->payload.version->os = strdup("Linux/OpenWRT"); */
201 Client_send_message(newclient, sendmsg);
206 void Client_free(client_t *client)
208 struct dlist *itr, *save;
211 Log_info("Disconnect client ID %d addr %s port %d", client->sessionId,
212 inet_ntoa(client->remote_tcp.sin_addr),
213 ntohs(client->remote_tcp.sin_port));
215 if (client->authenticated) {
216 sendmsg = Msg_create(UserRemove);
217 sendmsg->payload.userRemove->session = client->sessionId;
218 Client_send_message_except(client, sendmsg);
220 list_iterate_safe(itr, save, &client->txMsgQueue) {
221 list_del(&list_get_entry(itr, message_t, node)->node);
222 Msg_free(list_get_entry(itr, message_t, node));
224 Voicetarget_free_all(client);
226 list_del(&client->node);
227 list_del(&client->chan_node);
229 SSL_free(client->ssl);
230 close(client->tcpfd);
233 free(client->release);
236 if (client->playerName)
237 free(client->playerName);
239 free(client->context);
243 void Client_close(client_t *client)
245 SSL_shutdown(client->ssl);
246 client->shutdown_wait = true;
249 void Client_disconnect_all()
251 struct dlist *itr, *save;
253 list_iterate_safe(itr, save, &clients) {
254 Client_free(list_get_entry(itr, client_t, node));
258 int Client_read_fd(int fd)
261 client_t *client = NULL;
263 list_iterate(itr, &clients) {
264 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
265 client = list_get_entry(itr, client_t, node);
270 Log_fatal("No client found for fd %d", fd);
272 return Client_read(client);
275 int Client_read(client_t *client)
279 Timer_restart(&client->lastActivity);
281 if (client->writeBlockedOnRead) {
282 client->writeBlockedOnRead = false;
283 Log_debug("Client_read: writeBlockedOnRead == true");
284 return Client_write(client);
287 if (client->shutdown_wait) {
291 if (!client->SSLready) {
293 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
302 if (!client->msgsize)
303 rc = SSL_read(client->ssl, client->rxbuf, 6 - client->rxcount);
304 else if (client->drainleft > 0)
305 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
307 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
310 if (client->drainleft > 0)
311 client->drainleft -= rc;
313 client->rxcount += rc;
314 if (!client->msgsize && client->rxcount >= 6) {
315 uint32_t *msgLen = (uint32_t *) &client->rxbuf[2];
316 client->msgsize = ntohl(*msgLen);
318 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
319 Log_warn("Too big message received (%d). Discarding.", client->msgsize);
320 client->rxcount = client->msgsize = 0;
321 client->drainleft = client->msgsize;
323 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
324 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
325 /* pass messsage to handler */
327 Mh_handle_message(client, msg);
328 client->rxcount = client->msgsize = 0;
331 } else /* rc <= 0 */ {
332 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
335 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
336 client->readBlockedOnWrite = true;
339 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
340 Log_warn("Error: Zero return - closing");
341 if (!client->shutdown_wait)
342 Client_close(client);
345 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
346 /* Hmm. This is where we end up when the client closes its connection.
349 Log_info("Connection closed by peer");
352 Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
358 } while (SSL_pending(client->ssl));
362 int Client_write_fd(int fd)
365 client_t *client = NULL;
367 list_iterate(itr, &clients) {
368 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
369 client = list_get_entry(itr, client_t, node);
374 Log_fatal("No client found for fd %d", fd);
375 Client_write(client);
379 int Client_write(client_t *client)
383 if (client->readBlockedOnWrite) {
384 client->readBlockedOnWrite = false;
385 Log_debug("Client_write: readBlockedOnWrite == true");
386 return Client_read(client);
388 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
390 client->txcount += rc;
391 if (client->txcount == client->txsize)
392 client->txsize = client->txcount = 0;
395 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
396 client->writeBlockedOnRead = true;
399 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
403 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
404 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
406 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
411 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
413 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
414 list_del(list_get_first(&client->txMsgQueue));
415 client->txQueueCount--;
416 Client_send_message(client, msg);
421 int Client_send_message(client_t *client, message_t *msg)
423 if (!client->authenticated && msg->messageType != Version) {
427 if (client->txsize != 0 || !client->SSLready) {
429 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
430 client->txQueueCount > 30) {
434 client->txQueueCount++;
435 list_add_tail(&msg->node, &client->txMsgQueue);
436 Log_debug("Queueing message");
439 memset(client->txbuf, 0, BUFSIZE);
440 len = Msg_messageToNetwork(msg, client->txbuf);
441 doAssert(len < BUFSIZE);
443 client->txsize = len;
445 Client_write(client);
451 client_t *Client_iterate(client_t **client_itr)
453 client_t *c = *client_itr;
455 if (list_empty(&clients))
459 c = list_get_entry(list_get_first(&clients), client_t, node);
461 if (list_get_next(&c->node) == &clients)
464 c = list_get_entry(list_get_next(&c->node), client_t, node);
471 int Client_send_message_except(client_t *client, message_t *msg)
473 client_t *itr = NULL;
476 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
477 while (Client_iterate(&itr) != NULL) {
480 Msg_inc_ref(msg); /* One extra reference for each new copy */
481 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
482 Client_send_message(itr, msg);
485 Msg_free(msg); /* Free our reference to the message */
488 Msg_free(msg); /* If only 1 client is connected then no message is passed
489 * to Client_send_message(). Free it here. */
494 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
496 if (CryptState_isValid(&client->cryptState) &&
497 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
500 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
501 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
503 Timer_restart(&client->cryptState.tLastRequest);
505 sendmsg = Msg_create(CryptSetup);
506 Log_info("Requesting voice channel crypt resync");
507 Client_send_message(client, sendmsg);
513 #define UDP_PACKET_SIZE 1024
514 int Client_read_udp()
517 struct sockaddr_in from;
518 socklen_t fromlen = sizeof(struct sockaddr_in);
521 UDPMessageType_t msgType;
523 #if defined(__LP64__)
524 uint8_t encbuff[UDP_PACKET_SIZE + 8];
525 uint8_t *encrypted = encbuff + 4;
527 uint8_t encrypted[UDP_PACKET_SIZE];
529 uint8_t buffer[UDP_PACKET_SIZE];
531 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
534 } else if (len < 0) {
536 } else if (len < 5) {
537 // 4 bytes crypt header + type + session
539 } else if (len > UDP_PACKET_SIZE) {
544 if (len == 12 && *encrypted == 0) {
545 uint32_t *ping = (uint32_t *)encrypted;
546 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
547 // 1 and 2 will be the timestamp, which we return unmodified.
548 ping[3] = htonl((uint32_t)clientcount);
549 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
550 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
552 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
556 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
559 while (Client_iterate(&itr) != NULL) {
560 if (itr->key == key) {
561 if (!checkDecrypt(itr, encrypted, buffer, len))
566 if (itr == NULL) { /* Unknown peer */
567 while (Client_iterate(&itr) != NULL) {
568 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
569 if (checkDecrypt(itr, encrypted, buffer, len)) {
571 Log_info("New UDP connection from %s port %d sessionId %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port), itr->sessionId);
572 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
575 else Log_warn("Bad cryptstate from peer");
583 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
586 case UDPVoiceCELTAlpha:
587 case UDPVoiceCELTBeta:
589 Client_voiceMsg(itr, buffer, len);
592 Log_debug("UDP Ping reply len %d", len);
593 Client_send_udp(itr, buffer, len);
596 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
603 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
605 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
606 if (poslen > 0 && strcmp(src->context, dst->context) == 0)
607 Client_send_udp(dst, data, len);
609 Client_send_udp(dst, data, len - poslen);
613 /* Handle decrypted voice message */
614 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
616 uint8_t buffer[UDP_PACKET_SIZE];
617 pds_t *pdi = Pds_create(data + 1, len - 1);
618 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
619 unsigned int type = data[0] & 0xe0;
620 unsigned int target = data[0] & 0x1f;
621 unsigned int poslen, counter;
622 int offset, packetsize;
625 channel_t *ch = (channel_t *)client->channel;
628 if (!client->authenticated || client->mute)
631 packetsize = 20 + 8 + 4 + len;
632 if (client->availableBandwidth - packetsize < 0)
633 goto out; /* Discard */
634 client->availableBandwidth -= packetsize;
636 counter = Pds_get_numval(pdi); /* step past session id */
638 counter = Pds_next8(pdi);
639 offset = Pds_skip(pdi, counter & 0x7f);
640 } while ((counter & 0x80) && offset > 0);
642 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
644 Pds_add_numval(pds, client->sessionId);
645 Pds_append_data_nosize(pds, data + 1, len - 1);
647 if (target == 0x1f) { /* Loopback */
648 buffer[0] = (uint8_t) type;
649 Client_send_udp(client, buffer, pds->offset + 1);
651 else if (target == 0) { /* regular channel speech */
652 buffer[0] = (uint8_t) type;
657 list_iterate(itr, &ch->clients) {
659 c = list_get_entry(itr, client_t, chan_node);
660 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
663 if (!list_empty(&ch->channel_links)) {
664 struct dlist *ch_itr;
665 list_iterate(ch_itr, &ch->channel_links) {
667 ch_link = list_get_entry(ch_itr, channel_t, link_node);
668 list_iterate(itr, &ch_link->clients) {
670 c = list_get_entry(itr, client_t, chan_node);
671 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
672 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
676 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
680 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
681 Log_debug("Whisper channel %d", vt->channels[i]);
682 ch = Chan_fromId(vt->channels[i]);
685 list_iterate(itr, &ch->clients) {
687 c = list_get_entry(itr, client_t, chan_node);
688 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
692 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
694 Log_debug("Whisper session %d", vt->sessions[i]);
695 while (Client_iterate(&c) != NULL) {
696 if (c->sessionId == vt->sessions[i]) {
697 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
711 static int Client_send_udp(client_t *client, uint8_t *data, int len)
715 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
716 #if defined(__LP64__)
717 buf = mbuf = malloc(len + 4 + 16);
720 mbuf = buf = malloc(len + 4);
723 Log_fatal("Out of memory");
725 CryptState_encrypt(&client->cryptState, data, buf, len);
727 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
733 memcpy(buf, data, len);
734 msg = Msg_create(UDPTunnel);
736 msg->payload.UDPTunnel->packet.data = buf;
737 msg->payload.UDPTunnel->packet.len = len;
738 Client_send_message(client, msg);