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 /* Version 0.2.0 XXX fixme */
44 const uint32_t versionBlob = 1<<16 | 2<<8 | 0;
46 static int Client_read(client_t *client);
47 static int Client_write(client_t *client);
48 static int Client_send_udp(client_t *client, uint8_t *data, int len);
49 void Client_free(client_t *client);
51 declare_list(clients);
52 static int clientcount; /* = 0 */
53 static int session = 1;
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("Session ID %d timeout - closing", c->sessionId);
107 void recheckCodecVersions()
109 int codec_map[MAX_CODECS][2];
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 if (itr->codecs[i] == codec_map[codecindex][0])
121 codec_map[codecindex][1]++;
125 if (codec_map[codecindex][0] == 0)
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);
189 list_add_tail(&newclient->node, &clients);
192 /* Send version message to client */
193 sendmsg = Msg_create(Version);
194 sendmsg->payload.version->has_version = true;
195 sendmsg->payload.version->version = (1 << 16) | (2 << 8) | 0; /* XXX fix */
196 sendmsg->payload.version->release = strdup("1.2.0");
197 sendmsg->payload.version->os = strdup("Linux/OpenWRT");
199 Client_send_message(newclient, sendmsg);
204 void Client_free(client_t *client)
206 struct dlist *itr, *save;
209 Log_info("Disconnect client ID %d addr %s port %d", client->sessionId,
210 inet_ntoa(client->remote_tcp.sin_addr),
211 ntohs(client->remote_tcp.sin_port));
213 if (client->authenticated) {
214 sendmsg = Msg_create(UserRemove);
215 sendmsg->payload.userRemove->session = client->sessionId;
216 Client_send_message_except(client, sendmsg);
218 list_iterate_safe(itr, save, &client->txMsgQueue) {
219 list_del(&list_get_entry(itr, message_t, node)->node);
220 Msg_free(list_get_entry(itr, message_t, node));
223 list_del(&client->node);
224 list_del(&client->chan_node);
226 SSL_free(client->ssl);
227 close(client->tcpfd);
230 free(client->release);
233 if (client->playerName)
234 free(client->playerName);
238 void Client_close(client_t *client)
240 SSL_shutdown(client->ssl);
241 client->shutdown_wait = true;
244 void Client_disconnect_all()
246 struct dlist *itr, *save;
248 list_iterate_safe(itr, save, &clients) {
249 Client_free(list_get_entry(itr, client_t, node));
253 int Client_read_fd(int fd)
256 client_t *client = NULL;
258 list_iterate(itr, &clients) {
259 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
260 client = list_get_entry(itr, client_t, node);
265 Log_fatal("No client found for fd %d", fd);
267 return Client_read(client);
270 int Client_read(client_t *client)
274 Timer_restart(&client->lastActivity);
276 if (client->writeBlockedOnRead) {
277 client->writeBlockedOnRead = false;
278 Log_debug("Client_read: writeBlockedOnRead == true");
279 return Client_write(client);
282 if (client->shutdown_wait) {
286 if (!client->SSLready) {
288 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
297 if (!client->msgsize)
298 rc = SSL_read(client->ssl, client->rxbuf, 6 - client->rxcount);
299 else if (client->drainleft > 0)
300 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
302 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
305 if (client->drainleft > 0)
306 client->drainleft -= rc;
308 client->rxcount += rc;
309 if (!client->msgsize && client->rxcount >= 6) {
310 uint32_t *msgLen = (uint32_t *) &client->rxbuf[2];
311 client->msgsize = ntohl(*msgLen);
313 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
314 Log_warn("Too big message received (%d). Discarding.", client->msgsize);
315 client->rxcount = client->msgsize = 0;
316 client->drainleft = client->msgsize;
318 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
319 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
320 /* pass messsage to handler */
322 Mh_handle_message(client, msg);
323 client->rxcount = client->msgsize = 0;
326 } else /* rc <= 0 */ {
327 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
330 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
331 client->readBlockedOnWrite = true;
334 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
335 Log_warn("Error: Zero return - closing");
336 if (!client->shutdown_wait)
337 Client_close(client);
340 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
341 /* Hmm. This is where we end up when the client closes its connection.
344 Log_info("Connection closed by peer");
347 Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
353 } while (SSL_pending(client->ssl));
357 int Client_write_fd(int fd)
360 client_t *client = NULL;
362 list_iterate(itr, &clients) {
363 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
364 client = list_get_entry(itr, client_t, node);
369 Log_fatal("No client found for fd %d", fd);
370 Client_write(client);
374 int Client_write(client_t *client)
378 if (client->readBlockedOnWrite) {
379 client->readBlockedOnWrite = false;
380 Log_debug("Client_write: readBlockedOnWrite == true");
381 return Client_read(client);
383 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
385 client->txcount += rc;
386 if (client->txcount == client->txsize)
387 client->txsize = client->txcount = 0;
390 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
391 client->writeBlockedOnRead = true;
394 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
398 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
399 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
401 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
406 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
408 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
409 list_del(list_get_first(&client->txMsgQueue));
410 client->txQueueCount--;
411 Client_send_message(client, msg);
416 int Client_send_message(client_t *client, message_t *msg)
418 if (!client->authenticated && msg->messageType != Version) {
422 if (client->txsize != 0 || !client->SSLready) {
424 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
425 client->txQueueCount > 30) {
429 client->txQueueCount++;
430 list_add_tail(&msg->node, &client->txMsgQueue);
431 Log_debug("Queueing message");
434 memset(client->txbuf, 0, BUFSIZE);
435 len = Msg_messageToNetwork(msg, client->txbuf);
436 doAssert(len < BUFSIZE);
438 client->txsize = len;
440 Client_write(client);
446 client_t *Client_iterate(client_t **client_itr)
448 client_t *c = *client_itr;
450 if (list_empty(&clients))
454 c = list_get_entry(list_get_first(&clients), client_t, node);
456 if (list_get_next(&c->node) == &clients)
459 c = list_get_entry(list_get_next(&c->node), client_t, node);
466 int Client_send_message_except(client_t *client, message_t *msg)
468 client_t *itr = NULL;
471 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
472 while (Client_iterate(&itr) != NULL) {
475 Msg_inc_ref(msg); /* One extra reference for each new copy */
476 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
477 Client_send_message(itr, msg);
480 Msg_free(msg); /* Free our reference to the message */
483 Msg_free(msg); /* If only 1 client is connected then no message is passed
484 * to Client_send_message(). Free it here. */
489 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
491 if (CryptState_isValid(&client->cryptState) &&
492 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
495 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
496 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
498 Timer_restart(&client->cryptState.tLastRequest);
500 sendmsg = Msg_create(CryptSetup);
501 Log_info("Requesting voice channel crypt resync");
502 Client_send_message(client, sendmsg);
508 #define UDP_PACKET_SIZE 1024
509 int Client_read_udp()
512 struct sockaddr_in from;
513 socklen_t fromlen = sizeof(struct sockaddr_in);
516 UDPMessageType_t msgType;
518 #if defined(__LP64__)
519 uint8_t encbuff[UDP_PACKET_SIZE + 8];
520 uint8_t *encrypted = encbuff + 4;
522 uint8_t encrypted[UDP_PACKET_SIZE];
524 uint8_t buffer[UDP_PACKET_SIZE];
526 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
529 } else if (len < 0) {
531 } else if (len < 5) {
532 // 4 bytes crypt header + type + session
534 } else if (len > UDP_PACKET_SIZE) {
539 if (len == 12 && *encrypted == 0) {
540 uint32_t *ping = (uint32_t *)encrypted;
541 ping[0] = htons(versionBlob);
542 // 1 and 2 will be the timestamp, which we return unmodified.
543 ping[3] = htons((uint32_t)clientcount);
544 ping[4] = htons((uint32_t)getIntConf(MAX_CLIENTS));
545 ping[5] = htons((uint32_t)getIntConf(MAX_BANDWIDTH));
547 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
551 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
554 while (Client_iterate(&itr) != NULL) {
555 if (itr->key == key) {
556 if (!checkDecrypt(itr, encrypted, buffer, len))
561 if (itr == NULL) { /* Unknown peer */
562 while (Client_iterate(&itr) != NULL) {
563 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
564 if (checkDecrypt(itr, encrypted, buffer, len)) {
566 Log_info("New UDP connection from %s port %d sessionId %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port), itr->sessionId);
567 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
570 else Log_warn("Bad cryptstate from peer");
578 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
581 case UDPVoiceCELTAlpha:
582 case UDPVoiceCELTBeta:
584 Client_voiceMsg(itr, buffer, len);
587 Client_send_udp(itr, buffer, len);
590 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
597 /* Handle decrypted voice message */
598 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
600 uint8_t buffer[UDP_PACKET_SIZE];
601 pds_t *pdi = Pds_create(data + 1, len - 1);
602 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
603 unsigned int type = data[0] & 0xe0;
604 unsigned int target = data[0] & 0x1f;
605 unsigned int poslen, counter;
606 int offset, packetsize;
608 channel_t *ch = (channel_t *)client->channel;
611 if (!client->authenticated || client->mute)
614 packetsize = 20 + 8 + 4 + len;
615 if (client->availableBandwidth - packetsize < 0)
616 goto out; /* Discard */
617 client->availableBandwidth -= packetsize;
619 counter = Pds_get_numval(pdi); /* step past session id */
621 counter = Pds_next8(pdi);
622 offset = Pds_skip(pdi, counter & 0x7f);
623 } while ((counter & 0x80) && offset > 0);
625 poslen = pdi->maxsize - pdi->offset; /* XXX - Add stripping of positional audio */
627 Pds_add_numval(pds, client->sessionId);
628 Pds_append_data_nosize(pds, data + 1, len - 1);
630 if (target & 0x1f) { /* Loopback */
631 buffer[0] = (uint8_t) type;
632 Client_send_udp(client, buffer, pds->offset + 1);
634 else if (target == 0) { /* regular channel speech */
635 buffer[0] = (uint8_t) type;
640 list_iterate(itr, &ch->clients) {
642 c = list_get_entry(itr, client_t, chan_node);
643 if (c != client && !c->deaf) {
644 Client_send_udp(c, buffer, pds->offset + 1);
648 /* XXX - Add targeted whisper here */
657 static int Client_send_udp(client_t *client, uint8_t *data, int len)
661 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
662 #if defined(__LP64__)
663 buf = mbuf = malloc(len + 4 + 16);
666 mbuf = buf = malloc(len + 4);
669 Log_fatal("Out of memory");
671 CryptState_encrypt(&client->cryptState, data, buf, len);
673 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
679 memcpy(buf, data, len);
680 msg = Msg_create(UDPTunnel);
682 msg->payload.UDPTunnel->packet.data = buf;
683 msg->payload.UDPTunnel->packet.len = len;
684 Client_send_message(client, msg);