1 /* Copyright (C) 2009, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2009, 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);
241 void Client_close(client_t *client)
243 SSL_shutdown(client->ssl);
244 client->shutdown_wait = true;
247 void Client_disconnect_all()
249 struct dlist *itr, *save;
251 list_iterate_safe(itr, save, &clients) {
252 Client_free(list_get_entry(itr, client_t, node));
256 int Client_read_fd(int fd)
259 client_t *client = NULL;
261 list_iterate(itr, &clients) {
262 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
263 client = list_get_entry(itr, client_t, node);
268 Log_fatal("No client found for fd %d", fd);
270 return Client_read(client);
273 int Client_read(client_t *client)
277 Timer_restart(&client->lastActivity);
279 if (client->writeBlockedOnRead) {
280 client->writeBlockedOnRead = false;
281 Log_debug("Client_read: writeBlockedOnRead == true");
282 return Client_write(client);
285 if (client->shutdown_wait) {
289 if (!client->SSLready) {
291 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
300 if (!client->msgsize)
301 rc = SSL_read(client->ssl, client->rxbuf, 6 - client->rxcount);
302 else if (client->drainleft > 0)
303 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
305 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
308 if (client->drainleft > 0)
309 client->drainleft -= rc;
311 client->rxcount += rc;
312 if (!client->msgsize && client->rxcount >= 6) {
313 uint32_t *msgLen = (uint32_t *) &client->rxbuf[2];
314 client->msgsize = ntohl(*msgLen);
316 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
317 Log_warn("Too big message received (%d). Discarding.", client->msgsize);
318 client->rxcount = client->msgsize = 0;
319 client->drainleft = client->msgsize;
321 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
322 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
323 /* pass messsage to handler */
325 Mh_handle_message(client, msg);
326 client->rxcount = client->msgsize = 0;
329 } else /* rc <= 0 */ {
330 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
333 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
334 client->readBlockedOnWrite = true;
337 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
338 Log_warn("Error: Zero return - closing");
339 if (!client->shutdown_wait)
340 Client_close(client);
343 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
344 /* Hmm. This is where we end up when the client closes its connection.
347 Log_info("Connection closed by peer");
350 Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
356 } while (SSL_pending(client->ssl));
360 int Client_write_fd(int fd)
363 client_t *client = NULL;
365 list_iterate(itr, &clients) {
366 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
367 client = list_get_entry(itr, client_t, node);
372 Log_fatal("No client found for fd %d", fd);
373 Client_write(client);
377 int Client_write(client_t *client)
381 if (client->readBlockedOnWrite) {
382 client->readBlockedOnWrite = false;
383 Log_debug("Client_write: readBlockedOnWrite == true");
384 return Client_read(client);
386 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
388 client->txcount += rc;
389 if (client->txcount == client->txsize)
390 client->txsize = client->txcount = 0;
393 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
394 client->writeBlockedOnRead = true;
397 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
401 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
402 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
404 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
409 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
411 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
412 list_del(list_get_first(&client->txMsgQueue));
413 client->txQueueCount--;
414 Client_send_message(client, msg);
419 int Client_send_message(client_t *client, message_t *msg)
421 if (!client->authenticated && msg->messageType != Version) {
425 if (client->txsize != 0 || !client->SSLready) {
427 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
428 client->txQueueCount > 30) {
432 client->txQueueCount++;
433 list_add_tail(&msg->node, &client->txMsgQueue);
434 Log_debug("Queueing message");
437 memset(client->txbuf, 0, BUFSIZE);
438 len = Msg_messageToNetwork(msg, client->txbuf);
439 doAssert(len < BUFSIZE);
441 client->txsize = len;
443 Client_write(client);
449 client_t *Client_iterate(client_t **client_itr)
451 client_t *c = *client_itr;
453 if (list_empty(&clients))
457 c = list_get_entry(list_get_first(&clients), client_t, node);
459 if (list_get_next(&c->node) == &clients)
462 c = list_get_entry(list_get_next(&c->node), client_t, node);
469 int Client_send_message_except(client_t *client, message_t *msg)
471 client_t *itr = NULL;
474 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
475 while (Client_iterate(&itr) != NULL) {
478 Msg_inc_ref(msg); /* One extra reference for each new copy */
479 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
480 Client_send_message(itr, msg);
483 Msg_free(msg); /* Free our reference to the message */
486 Msg_free(msg); /* If only 1 client is connected then no message is passed
487 * to Client_send_message(). Free it here. */
492 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
494 if (CryptState_isValid(&client->cryptState) &&
495 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
498 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
499 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
501 Timer_restart(&client->cryptState.tLastRequest);
503 sendmsg = Msg_create(CryptSetup);
504 Log_info("Requesting voice channel crypt resync");
505 Client_send_message(client, sendmsg);
511 #define UDP_PACKET_SIZE 1024
512 int Client_read_udp()
515 struct sockaddr_in from;
516 socklen_t fromlen = sizeof(struct sockaddr_in);
519 UDPMessageType_t msgType;
521 #if defined(__LP64__)
522 uint8_t encbuff[UDP_PACKET_SIZE + 8];
523 uint8_t *encrypted = encbuff + 4;
525 uint8_t encrypted[UDP_PACKET_SIZE];
527 uint8_t buffer[UDP_PACKET_SIZE];
529 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
532 } else if (len < 0) {
534 } else if (len < 5) {
535 // 4 bytes crypt header + type + session
537 } else if (len > UDP_PACKET_SIZE) {
542 if (len == 12 && *encrypted == 0) {
543 uint32_t *ping = (uint32_t *)encrypted;
544 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
545 // 1 and 2 will be the timestamp, which we return unmodified.
546 ping[3] = htonl((uint32_t)clientcount);
547 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
548 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
550 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
554 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
557 while (Client_iterate(&itr) != NULL) {
558 if (itr->key == key) {
559 if (!checkDecrypt(itr, encrypted, buffer, len))
564 if (itr == NULL) { /* Unknown peer */
565 while (Client_iterate(&itr) != NULL) {
566 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
567 if (checkDecrypt(itr, encrypted, buffer, len)) {
569 Log_info("New UDP connection from %s port %d sessionId %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port), itr->sessionId);
570 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
573 else Log_warn("Bad cryptstate from peer");
581 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
584 case UDPVoiceCELTAlpha:
585 case UDPVoiceCELTBeta:
587 Client_voiceMsg(itr, buffer, len);
590 Log_debug("UDP Ping reply len %d", len);
591 Client_send_udp(itr, buffer, len);
594 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
601 /* Handle decrypted voice message */
602 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
604 uint8_t buffer[UDP_PACKET_SIZE];
605 pds_t *pdi = Pds_create(data + 1, len - 1);
606 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
607 unsigned int type = data[0] & 0xe0;
608 unsigned int target = data[0] & 0x1f;
609 unsigned int poslen, counter;
610 int offset, packetsize;
613 channel_t *ch = (channel_t *)client->channel;
616 if (!client->authenticated || client->mute)
619 packetsize = 20 + 8 + 4 + len;
620 if (client->availableBandwidth - packetsize < 0)
621 goto out; /* Discard */
622 client->availableBandwidth -= packetsize;
624 counter = Pds_get_numval(pdi); /* step past session id */
626 counter = Pds_next8(pdi);
627 offset = Pds_skip(pdi, counter & 0x7f);
628 } while ((counter & 0x80) && offset > 0);
630 poslen = pdi->maxsize - pdi->offset; /* XXX - Add stripping of positional audio */
632 Pds_add_numval(pds, client->sessionId);
633 Pds_append_data_nosize(pds, data + 1, len - 1);
635 if (target == 0x1f) { /* Loopback */
636 buffer[0] = (uint8_t) type;
637 Client_send_udp(client, buffer, pds->offset + 1);
639 else if (target == 0) { /* regular channel speech */
640 buffer[0] = (uint8_t) type;
645 list_iterate(itr, &ch->clients) {
647 c = list_get_entry(itr, client_t, chan_node);
648 if (c != client && !c->deaf) {
649 Client_send_udp(c, buffer, pds->offset + 1);
653 if (!list_empty(&ch->channel_links)) {
654 struct dlist *ch_itr;
655 list_iterate(ch_itr, &ch->channel_links) {
657 ch_link = list_get_entry(ch_itr, channel_t, link_node);
658 list_iterate(itr, &ch_link->clients) {
660 c = list_get_entry(itr, client_t, chan_node);
661 if (c != client && !c->deaf) {
662 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
663 Client_send_udp(c, buffer, pds->offset + 1);
668 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
672 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
673 Log_debug("Whisper channel %d", vt->channels[i]);
674 ch = Chan_fromId(vt->channels[i]);
677 list_iterate(itr, &ch->clients) {
679 c = list_get_entry(itr, client_t, chan_node);
680 if (c != client && !c->deaf && IS_AUTH(c)) {
681 Client_send_udp(c, buffer, pds->offset + 1);
686 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
688 Log_debug("Whisper session %d", vt->sessions[i]);
689 while (Client_iterate(&c) != NULL) {
690 if (c->sessionId == vt->sessions[i] && c != client && !c->deaf && IS_AUTH(c)) {
691 Client_send_udp(c, buffer, pds->offset + 1);
705 static int Client_send_udp(client_t *client, uint8_t *data, int len)
709 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
710 #if defined(__LP64__)
711 buf = mbuf = malloc(len + 4 + 16);
714 mbuf = buf = malloc(len + 4);
717 Log_fatal("Out of memory");
719 CryptState_encrypt(&client->cryptState, data, buf, len);
721 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
727 memcpy(buf, data, len);
728 msg = Msg_create(UDPTunnel);
730 msg->payload.UDPTunnel->packet.data = buf;
731 msg->payload.UDPTunnel->packet.len = len;
732 Client_send_message(client, msg);