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[client->rxcount], 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) {
316 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
317 client->msgsize = ntohl(msgLen);
319 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
320 Log_warn("Too big message received (%d). Discarding.", client->msgsize);
321 client->rxcount = client->msgsize = 0;
322 client->drainleft = client->msgsize;
324 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
325 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
326 /* pass messsage to handler */
328 Mh_handle_message(client, msg);
329 client->rxcount = client->msgsize = 0;
332 } else /* rc <= 0 */ {
333 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
336 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
337 client->readBlockedOnWrite = true;
340 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
341 Log_warn("Error: Zero return - closing");
342 if (!client->shutdown_wait)
343 Client_close(client);
346 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
347 /* Hmm. This is where we end up when the client closes its connection.
350 Log_info("Connection closed by peer");
353 Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
359 } while (SSL_pending(client->ssl));
363 int Client_write_fd(int fd)
366 client_t *client = NULL;
368 list_iterate(itr, &clients) {
369 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
370 client = list_get_entry(itr, client_t, node);
375 Log_fatal("No client found for fd %d", fd);
376 Client_write(client);
380 int Client_write(client_t *client)
384 if (client->readBlockedOnWrite) {
385 client->readBlockedOnWrite = false;
386 Log_debug("Client_write: readBlockedOnWrite == true");
387 return Client_read(client);
389 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
391 client->txcount += rc;
392 if (client->txcount == client->txsize)
393 client->txsize = client->txcount = 0;
396 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
397 client->writeBlockedOnRead = true;
400 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
404 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
405 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
407 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
412 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
414 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
415 list_del(list_get_first(&client->txMsgQueue));
416 client->txQueueCount--;
417 Client_send_message(client, msg);
422 int Client_send_message(client_t *client, message_t *msg)
424 if (!client->authenticated && msg->messageType != Version) {
428 if (client->txsize != 0 || !client->SSLready) {
430 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
431 client->txQueueCount > 30) {
435 client->txQueueCount++;
436 list_add_tail(&msg->node, &client->txMsgQueue);
437 Log_debug("Queueing message");
440 memset(client->txbuf, 0, BUFSIZE);
441 len = Msg_messageToNetwork(msg, client->txbuf);
442 doAssert(len < BUFSIZE);
444 client->txsize = len;
446 Client_write(client);
452 client_t *Client_iterate(client_t **client_itr)
454 client_t *c = *client_itr;
456 if (list_empty(&clients))
460 c = list_get_entry(list_get_first(&clients), client_t, node);
462 if (list_get_next(&c->node) == &clients)
465 c = list_get_entry(list_get_next(&c->node), client_t, node);
472 int Client_send_message_except(client_t *client, message_t *msg)
474 client_t *itr = NULL;
477 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
478 while (Client_iterate(&itr) != NULL) {
481 Msg_inc_ref(msg); /* One extra reference for each new copy */
482 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
483 Client_send_message(itr, msg);
486 Msg_free(msg); /* Free our reference to the message */
489 Msg_free(msg); /* If only 1 client is connected then no message is passed
490 * to Client_send_message(). Free it here. */
495 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
497 if (CryptState_isValid(&client->cryptState) &&
498 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
501 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
502 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
504 Timer_restart(&client->cryptState.tLastRequest);
506 sendmsg = Msg_create(CryptSetup);
507 Log_info("Requesting voice channel crypt resync");
508 Client_send_message(client, sendmsg);
514 #define UDP_PACKET_SIZE 1024
515 int Client_read_udp()
518 struct sockaddr_in from;
519 socklen_t fromlen = sizeof(struct sockaddr_in);
522 UDPMessageType_t msgType;
524 #if defined(__LP64__)
525 uint8_t encbuff[UDP_PACKET_SIZE + 8];
526 uint8_t *encrypted = encbuff + 4;
528 uint8_t encrypted[UDP_PACKET_SIZE];
530 uint8_t buffer[UDP_PACKET_SIZE];
532 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
535 } else if (len < 0) {
537 } else if (len < 5) {
538 // 4 bytes crypt header + type + session
540 } else if (len > UDP_PACKET_SIZE) {
545 if (len == 12 && *encrypted == 0) {
546 uint32_t *ping = (uint32_t *)encrypted;
547 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
548 // 1 and 2 will be the timestamp, which we return unmodified.
549 ping[3] = htonl((uint32_t)clientcount);
550 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
551 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
553 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
557 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
560 while (Client_iterate(&itr) != NULL) {
561 if (itr->key == key) {
562 if (!checkDecrypt(itr, encrypted, buffer, len))
567 if (itr == NULL) { /* Unknown peer */
568 while (Client_iterate(&itr) != NULL) {
569 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
570 if (checkDecrypt(itr, encrypted, buffer, len)) {
572 Log_info("New UDP connection from %s port %d sessionId %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port), itr->sessionId);
573 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
576 else Log_warn("Bad cryptstate from peer");
584 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
587 case UDPVoiceCELTAlpha:
588 case UDPVoiceCELTBeta:
590 Client_voiceMsg(itr, buffer, len);
593 Log_debug("UDP Ping reply len %d", len);
594 Client_send_udp(itr, buffer, len);
597 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
604 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
606 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
607 if (poslen > 0 && strcmp(src->context, dst->context) == 0)
608 Client_send_udp(dst, data, len);
610 Client_send_udp(dst, data, len - poslen);
614 /* Handle decrypted voice message */
615 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
617 uint8_t buffer[UDP_PACKET_SIZE];
618 pds_t *pdi = Pds_create(data + 1, len - 1);
619 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
620 unsigned int type = data[0] & 0xe0;
621 unsigned int target = data[0] & 0x1f;
622 unsigned int poslen, counter;
623 int offset, packetsize;
626 channel_t *ch = (channel_t *)client->channel;
629 if (!client->authenticated || client->mute)
632 packetsize = 20 + 8 + 4 + len;
633 if (client->availableBandwidth - packetsize < 0)
634 goto out; /* Discard */
635 client->availableBandwidth -= packetsize;
637 counter = Pds_get_numval(pdi); /* step past session id */
639 counter = Pds_next8(pdi);
640 offset = Pds_skip(pdi, counter & 0x7f);
641 } while ((counter & 0x80) && offset > 0);
643 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
645 Pds_add_numval(pds, client->sessionId);
646 Pds_append_data_nosize(pds, data + 1, len - 1);
648 if (target == 0x1f) { /* Loopback */
649 buffer[0] = (uint8_t) type;
650 Client_send_udp(client, buffer, pds->offset + 1);
652 else if (target == 0) { /* regular channel speech */
653 buffer[0] = (uint8_t) type;
658 list_iterate(itr, &ch->clients) {
660 c = list_get_entry(itr, client_t, chan_node);
661 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
664 if (!list_empty(&ch->channel_links)) {
665 struct dlist *ch_itr;
666 list_iterate(ch_itr, &ch->channel_links) {
668 ch_link = list_get_entry(ch_itr, channel_t, link_node);
669 list_iterate(itr, &ch_link->clients) {
671 c = list_get_entry(itr, client_t, chan_node);
672 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
673 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
677 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
681 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
682 Log_debug("Whisper channel %d", vt->channels[i]);
683 ch = Chan_fromId(vt->channels[i]);
686 list_iterate(itr, &ch->clients) {
688 c = list_get_entry(itr, client_t, chan_node);
689 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
693 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
695 Log_debug("Whisper session %d", vt->sessions[i]);
696 while (Client_iterate(&c) != NULL) {
697 if (c->sessionId == vt->sessions[i]) {
698 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
712 static int Client_send_udp(client_t *client, uint8_t *data, int len)
716 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
717 #if defined(__LP64__)
718 buf = mbuf = malloc(len + 4 + 16);
721 mbuf = buf = malloc(len + 4);
724 Log_fatal("Out of memory");
726 CryptState_encrypt(&client->cryptState, data, buf, len);
728 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
734 memcpy(buf, data, len);
735 msg = Msg_create(UDPTunnel);
737 msg->payload.UDPTunnel->packet.data = buf;
738 msg->payload.UDPTunnel->packet.len = len;
739 Client_send_message(client, msg);