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"
44 static int Client_read(client_t *client);
45 static int Client_write(client_t *client);
46 static int Client_send_udp(client_t *client, uint8_t *data, int len);
47 void Client_free(client_t *client);
49 declare_list(clients);
50 static int clientcount; /* = 0 */
51 static int session = 1;
52 static int maxBandwidth;
54 int iCodecAlpha, iCodecBeta;
61 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
69 int Client_getfds(struct pollfd *pollfds)
73 list_iterate(itr, &clients) {
75 c = list_get_entry(itr, client_t, node);
76 pollfds[i].fd = c->tcpfd;
77 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
78 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
79 pollfds[i].events |= POLLOUT;
88 int bwTop = maxBandwidth + maxBandwidth / 4;
89 list_iterate(itr, &clients) {
91 c = list_get_entry(itr, client_t, node);
92 Log_debug("Client %s BW available %d", c->playerName, c->availableBandwidth);
93 c->availableBandwidth += maxBandwidth;
94 if (c->availableBandwidth > bwTop)
95 c->availableBandwidth = bwTop;
97 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
98 /* No activity from client - assume it is lost and close. */
99 Log_info("Session ID %d timeout - closing", c->sessionId);
105 void recheckCodecVersions()
107 int codec_map[MAX_CODECS][2];
109 int i, codecindex, max = 0, version, current_version;
112 memset(codec_map, 0, MAX_CODECS * 2 * sizeof(int));
113 while (Client_iterate(&itr) != NULL) {
114 for (i = 0; i < itr->codec_count; i++) {
115 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
116 if (codec_map[codecindex][0] == 0)
117 codec_map[codecindex][0] = itr->codecs[i];
118 if (itr->codecs[i] == codec_map[codecindex][0])
119 codec_map[codecindex][1]++;
123 if (codec_map[codecindex][0] == 0)
125 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
126 if (codec_map[codecindex][0] == 0)
128 if (codec_map[codecindex][1] > max) {
129 max = codec_map[codecindex][1];
130 version = codec_map[codecindex][0];
133 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
134 if (current_version == version)
136 // If we don't already use the compat bitstream version set
137 // it as alpha and announce it. If another codec now got the
138 // majority set it as the opposite of the currently valid bPreferAlpha
140 if (version == (uint32_t)0x8000000a)
143 bPreferAlpha = ! bPreferAlpha;
146 iCodecAlpha = version;
148 iCodecBeta = version;
150 sendmsg = Msg_create(CodecVersion);
151 sendmsg->payload.codecVersion->alpha = version;
152 sendmsg->payload.codecVersion->beta = version;
153 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
154 Client_send_message_except(NULL, sendmsg);
156 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
157 bPreferAlpha ? iCodecAlpha : iCodecBeta);
161 int Client_add(int fd, struct sockaddr_in *remote)
166 newclient = malloc(sizeof(client_t));
167 if (newclient == NULL)
168 Log_fatal("Out of memory");
169 memset(newclient, 0, sizeof(client_t));
171 newclient->tcpfd = fd;
172 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
173 newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
174 if (newclient->ssl == NULL) {
175 Log_warn("SSL negotiation failed");
179 newclient->availableBandwidth = maxBandwidth;
180 Timer_init(&newclient->lastActivity);
181 newclient->sessionId = session++; /* XXX - more elaborate? */
183 init_list_entry(&newclient->txMsgQueue);
184 init_list_entry(&newclient->chan_node);
185 init_list_entry(&newclient->node);
187 list_add_tail(&newclient->node, &clients);
190 /* Send version message to client */
191 sendmsg = Msg_create(Version);
192 sendmsg->payload.version->has_version = true;
193 sendmsg->payload.version->version = PROTOCOL_VERSION;
194 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
195 /* XXX - set OS to something relevant? */
196 /* sendmsg->payload.version->os = strdup("Linux/OpenWRT"); */
198 Client_send_message(newclient, sendmsg);
203 void Client_free(client_t *client)
205 struct dlist *itr, *save;
208 Log_info("Disconnect client ID %d addr %s port %d", client->sessionId,
209 inet_ntoa(client->remote_tcp.sin_addr),
210 ntohs(client->remote_tcp.sin_port));
212 if (client->authenticated) {
213 sendmsg = Msg_create(UserRemove);
214 sendmsg->payload.userRemove->session = client->sessionId;
215 Client_send_message_except(client, sendmsg);
217 list_iterate_safe(itr, save, &client->txMsgQueue) {
218 list_del(&list_get_entry(itr, message_t, node)->node);
219 Msg_free(list_get_entry(itr, message_t, node));
222 list_del(&client->node);
223 list_del(&client->chan_node);
225 SSL_free(client->ssl);
226 close(client->tcpfd);
229 free(client->release);
232 if (client->playerName)
233 free(client->playerName);
237 void Client_close(client_t *client)
239 SSL_shutdown(client->ssl);
240 client->shutdown_wait = true;
243 void Client_disconnect_all()
245 struct dlist *itr, *save;
247 list_iterate_safe(itr, save, &clients) {
248 Client_free(list_get_entry(itr, client_t, node));
252 int Client_read_fd(int fd)
255 client_t *client = NULL;
257 list_iterate(itr, &clients) {
258 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
259 client = list_get_entry(itr, client_t, node);
264 Log_fatal("No client found for fd %d", fd);
266 return Client_read(client);
269 int Client_read(client_t *client)
273 Timer_restart(&client->lastActivity);
275 if (client->writeBlockedOnRead) {
276 client->writeBlockedOnRead = false;
277 Log_debug("Client_read: writeBlockedOnRead == true");
278 return Client_write(client);
281 if (client->shutdown_wait) {
285 if (!client->SSLready) {
287 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
296 if (!client->msgsize)
297 rc = SSL_read(client->ssl, client->rxbuf, 6 - client->rxcount);
298 else if (client->drainleft > 0)
299 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
301 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
304 if (client->drainleft > 0)
305 client->drainleft -= rc;
307 client->rxcount += rc;
308 if (!client->msgsize && client->rxcount >= 6) {
309 uint32_t *msgLen = (uint32_t *) &client->rxbuf[2];
310 client->msgsize = ntohl(*msgLen);
312 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
313 Log_warn("Too big message received (%d). Discarding.", client->msgsize);
314 client->rxcount = client->msgsize = 0;
315 client->drainleft = client->msgsize;
317 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
318 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
319 /* pass messsage to handler */
321 Mh_handle_message(client, msg);
322 client->rxcount = client->msgsize = 0;
325 } else /* rc <= 0 */ {
326 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
329 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
330 client->readBlockedOnWrite = true;
333 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
334 Log_warn("Error: Zero return - closing");
335 if (!client->shutdown_wait)
336 Client_close(client);
339 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
340 /* Hmm. This is where we end up when the client closes its connection.
343 Log_info("Connection closed by peer");
346 Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
352 } while (SSL_pending(client->ssl));
356 int Client_write_fd(int fd)
359 client_t *client = NULL;
361 list_iterate(itr, &clients) {
362 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
363 client = list_get_entry(itr, client_t, node);
368 Log_fatal("No client found for fd %d", fd);
369 Client_write(client);
373 int Client_write(client_t *client)
377 if (client->readBlockedOnWrite) {
378 client->readBlockedOnWrite = false;
379 Log_debug("Client_write: readBlockedOnWrite == true");
380 return Client_read(client);
382 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
384 client->txcount += rc;
385 if (client->txcount == client->txsize)
386 client->txsize = client->txcount = 0;
389 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
390 client->writeBlockedOnRead = true;
393 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
397 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
398 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
400 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
405 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
407 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
408 list_del(list_get_first(&client->txMsgQueue));
409 client->txQueueCount--;
410 Client_send_message(client, msg);
415 int Client_send_message(client_t *client, message_t *msg)
417 if (!client->authenticated && msg->messageType != Version) {
421 if (client->txsize != 0 || !client->SSLready) {
423 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
424 client->txQueueCount > 30) {
428 client->txQueueCount++;
429 list_add_tail(&msg->node, &client->txMsgQueue);
430 Log_debug("Queueing message");
433 memset(client->txbuf, 0, BUFSIZE);
434 len = Msg_messageToNetwork(msg, client->txbuf);
435 doAssert(len < BUFSIZE);
437 client->txsize = len;
439 Client_write(client);
445 client_t *Client_iterate(client_t **client_itr)
447 client_t *c = *client_itr;
449 if (list_empty(&clients))
453 c = list_get_entry(list_get_first(&clients), client_t, node);
455 if (list_get_next(&c->node) == &clients)
458 c = list_get_entry(list_get_next(&c->node), client_t, node);
465 int Client_send_message_except(client_t *client, message_t *msg)
467 client_t *itr = NULL;
470 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
471 while (Client_iterate(&itr) != NULL) {
474 Msg_inc_ref(msg); /* One extra reference for each new copy */
475 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
476 Client_send_message(itr, msg);
479 Msg_free(msg); /* Free our reference to the message */
482 Msg_free(msg); /* If only 1 client is connected then no message is passed
483 * to Client_send_message(). Free it here. */
488 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
490 if (CryptState_isValid(&client->cryptState) &&
491 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
494 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
495 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
497 Timer_restart(&client->cryptState.tLastRequest);
499 sendmsg = Msg_create(CryptSetup);
500 Log_info("Requesting voice channel crypt resync");
501 Client_send_message(client, sendmsg);
507 #define UDP_PACKET_SIZE 1024
508 int Client_read_udp()
511 struct sockaddr_in from;
512 socklen_t fromlen = sizeof(struct sockaddr_in);
515 UDPMessageType_t msgType;
517 #if defined(__LP64__)
518 uint8_t encbuff[UDP_PACKET_SIZE + 8];
519 uint8_t *encrypted = encbuff + 4;
521 uint8_t encrypted[UDP_PACKET_SIZE];
523 uint8_t buffer[UDP_PACKET_SIZE];
525 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
528 } else if (len < 0) {
530 } else if (len < 5) {
531 // 4 bytes crypt header + type + session
533 } else if (len > UDP_PACKET_SIZE) {
538 if (len == 12 && *encrypted == 0) {
539 uint32_t *ping = (uint32_t *)encrypted;
540 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
541 // 1 and 2 will be the timestamp, which we return unmodified.
542 ping[3] = htonl((uint32_t)clientcount);
543 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
544 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
546 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
550 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
553 while (Client_iterate(&itr) != NULL) {
554 if (itr->key == key) {
555 if (!checkDecrypt(itr, encrypted, buffer, len))
560 if (itr == NULL) { /* Unknown peer */
561 while (Client_iterate(&itr) != NULL) {
562 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
563 if (checkDecrypt(itr, encrypted, buffer, len)) {
565 Log_info("New UDP connection from %s port %d sessionId %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port), itr->sessionId);
566 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
569 else Log_warn("Bad cryptstate from peer");
577 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
580 case UDPVoiceCELTAlpha:
581 case UDPVoiceCELTBeta:
583 Client_voiceMsg(itr, buffer, len);
586 Client_send_udp(itr, buffer, len);
589 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
596 /* Handle decrypted voice message */
597 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
599 uint8_t buffer[UDP_PACKET_SIZE];
600 pds_t *pdi = Pds_create(data + 1, len - 1);
601 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
602 unsigned int type = data[0] & 0xe0;
603 unsigned int target = data[0] & 0x1f;
604 unsigned int poslen, counter;
605 int offset, packetsize;
607 channel_t *ch = (channel_t *)client->channel;
610 if (!client->authenticated || client->mute)
613 packetsize = 20 + 8 + 4 + len;
614 if (client->availableBandwidth - packetsize < 0)
615 goto out; /* Discard */
616 client->availableBandwidth -= packetsize;
618 counter = Pds_get_numval(pdi); /* step past session id */
620 counter = Pds_next8(pdi);
621 offset = Pds_skip(pdi, counter & 0x7f);
622 } while ((counter & 0x80) && offset > 0);
624 poslen = pdi->maxsize - pdi->offset; /* XXX - Add stripping of positional audio */
626 Pds_add_numval(pds, client->sessionId);
627 Pds_append_data_nosize(pds, data + 1, len - 1);
629 if (target & 0x1f) { /* Loopback */
630 buffer[0] = (uint8_t) type;
631 Client_send_udp(client, buffer, pds->offset + 1);
633 else if (target == 0) { /* regular channel speech */
634 buffer[0] = (uint8_t) type;
639 list_iterate(itr, &ch->clients) {
641 c = list_get_entry(itr, client_t, chan_node);
642 if (c != client && !c->deaf) {
643 Client_send_udp(c, buffer, pds->offset + 1);
647 /* XXX - Add targeted whisper here */
656 static int Client_send_udp(client_t *client, uint8_t *data, int len)
660 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
661 #if defined(__LP64__)
662 buf = mbuf = malloc(len + 4 + 16);
665 mbuf = buf = malloc(len + 4);
668 Log_fatal("Out of memory");
670 CryptState_encrypt(&client->cryptState, data, buf, len);
672 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
678 memcpy(buf, data, len);
679 msg = Msg_create(UDPTunnel);
681 msg->payload.UDPTunnel->packet.data = buf;
682 msg->payload.UDPTunnel->packet.len = len;
683 Client_send_message(client, msg);