1 /* Copyright (C) 2009-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 extern char system_string[], version_string[];
47 static int Client_read(client_t *client);
48 static int Client_write(client_t *client);
49 static int Client_send_udp(client_t *client, uint8_t *data, int len);
50 void Client_free(client_t *client);
52 declare_list(clients);
53 static int clientcount; /* = 0 */
54 static int session = 1;
55 static int maxBandwidth;
57 int iCodecAlpha, iCodecBeta;
64 maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
72 int Client_getfds(struct pollfd *pollfds)
76 list_iterate(itr, &clients) {
78 c = list_get_entry(itr, client_t, node);
79 pollfds[i].fd = c->tcpfd;
80 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
81 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
82 pollfds[i].events |= POLLOUT;
91 int bwTop = maxBandwidth + maxBandwidth / 4;
92 list_iterate(itr, &clients) {
94 c = list_get_entry(itr, client_t, node);
95 Log_debug("Client %s BW available %d", c->playerName, c->availableBandwidth);
96 c->availableBandwidth += maxBandwidth;
97 if (c->availableBandwidth > bwTop)
98 c->availableBandwidth = bwTop;
100 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
101 /* No activity from client - assume it is lost and close. */
102 Log_info_client(c, "Timeout, closing.");
108 void recheckCodecVersions()
110 int codec_map[MAX_CODECS][2];
111 client_t *itr = NULL;
112 int i, codecindex, max = 0, version, current_version;
115 memset(codec_map, 0, MAX_CODECS * 2 * sizeof(int));
116 while (Client_iterate(&itr) != NULL) {
117 for (i = 0; i < itr->codec_count; i++) {
118 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
119 if (codec_map[codecindex][0] == 0) {
120 codec_map[codecindex][0] = itr->codecs[i];
121 codec_map[codecindex][1] = 1;
124 if (itr->codecs[i] == codec_map[codecindex][0])
125 codec_map[codecindex][1]++;
129 for (codecindex = 0; codecindex < MAX_CODECS; codecindex++) {
130 if (codec_map[codecindex][0] == 0)
132 if (codec_map[codecindex][1] > max) {
133 max = codec_map[codecindex][1];
134 version = codec_map[codecindex][0];
137 current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
138 if (current_version == version)
140 // If we don't already use the compat bitstream version set
141 // it as alpha and announce it. If another codec now got the
142 // majority set it as the opposite of the currently valid bPreferAlpha
144 if (version == (uint32_t)0x8000000a)
147 bPreferAlpha = ! bPreferAlpha;
150 iCodecAlpha = version;
152 iCodecBeta = version;
154 sendmsg = Msg_create(CodecVersion);
155 sendmsg->payload.codecVersion->alpha = version;
156 sendmsg->payload.codecVersion->beta = version;
157 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
158 Client_send_message_except(NULL, sendmsg);
160 Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
161 bPreferAlpha ? iCodecAlpha : iCodecBeta);
165 int Client_add(int fd, struct sockaddr_in *remote)
170 newclient = malloc(sizeof(client_t));
171 if (newclient == NULL)
172 Log_fatal("Out of memory");
173 memset(newclient, 0, sizeof(client_t));
175 newclient->tcpfd = fd;
176 memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
177 newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
178 if (newclient->ssl == NULL) {
179 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
180 ntohs(remote->sin_port));
184 newclient->availableBandwidth = maxBandwidth;
185 Timer_init(&newclient->lastActivity);
186 newclient->sessionId = session++; /* XXX - more elaborate? */
188 init_list_entry(&newclient->txMsgQueue);
189 init_list_entry(&newclient->chan_node);
190 init_list_entry(&newclient->node);
191 init_list_entry(&newclient->voicetargets);
193 list_add_tail(&newclient->node, &clients);
196 /* Send version message to client */
197 sendmsg = Msg_create(Version);
198 sendmsg->payload.version->has_version = true;
199 sendmsg->payload.version->version = PROTOCOL_VERSION;
200 sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
201 sendmsg->payload.version->os = strdup(system_string);
202 sendmsg->payload.version->os_version = strdup(version_string);
203 Client_send_message(newclient, sendmsg);
208 void Client_free(client_t *client)
210 struct dlist *itr, *save;
213 if (client->authenticated) {
215 leave_id = Chan_playerLeave(client);
216 if (leave_id > 0) { /* Remove temp channel */
217 sendmsg = Msg_create(ChannelRemove);
218 sendmsg->payload.channelRemove->channel_id = leave_id;
219 Client_send_message_except(client, sendmsg);
221 sendmsg = Msg_create(UserRemove);
222 sendmsg->payload.userRemove->session = client->sessionId;
223 Client_send_message_except(client, sendmsg);
225 list_iterate_safe(itr, save, &client->txMsgQueue) {
226 list_del(&list_get_entry(itr, message_t, node)->node);
227 Msg_free(list_get_entry(itr, message_t, node));
229 Voicetarget_free_all(client);
231 list_del(&client->node);
233 SSL_free(client->ssl);
234 close(client->tcpfd);
237 free(client->release);
240 if (client->playerName)
241 free(client->playerName);
243 free(client->context);
247 void Client_close(client_t *client)
249 SSL_shutdown(client->ssl);
250 client->shutdown_wait = true;
253 void Client_disconnect_all()
255 struct dlist *itr, *save;
257 list_iterate_safe(itr, save, &clients) {
258 Client_free(list_get_entry(itr, client_t, node));
262 int Client_read_fd(int fd)
265 client_t *client = NULL;
267 list_iterate(itr, &clients) {
268 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
269 client = list_get_entry(itr, client_t, node);
274 Log_fatal("No client found for fd %d", fd);
276 return Client_read(client);
279 int Client_read(client_t *client)
283 Timer_restart(&client->lastActivity);
285 if (client->writeBlockedOnRead) {
286 client->writeBlockedOnRead = false;
287 Log_debug("Client_read: writeBlockedOnRead == true");
288 return Client_write(client);
291 if (client->shutdown_wait) {
295 if (!client->SSLready) {
297 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
306 if (!client->msgsize)
307 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
308 else if (client->drainleft > 0)
309 rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
311 rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
314 if (client->drainleft > 0)
315 client->drainleft -= rc;
317 client->rxcount += rc;
318 if (!client->msgsize && client->rxcount >= 6) {
320 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
321 client->msgsize = ntohl(msgLen);
323 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
324 Log_info_client(client, "Too big message received (%d bytes). Discarding.", client->msgsize);
325 client->rxcount = client->msgsize = 0;
326 client->drainleft = client->msgsize;
328 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
329 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
330 /* pass messsage to handler */
332 Mh_handle_message(client, msg);
333 client->rxcount = client->msgsize = 0;
336 } else /* rc <= 0 */ {
337 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
340 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
341 client->readBlockedOnWrite = true;
344 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
345 Log_info_client(client, "Connection closed by peer");
346 if (!client->shutdown_wait)
347 Client_close(client);
350 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
351 /* Hmm. This is where we end up when the client closes its connection.
354 Log_info_client(client, "Connection closed by peer");
357 Log_info_client(client, "SSL error: %d - Closing connection", SSL_get_error(client->ssl, rc));
363 } while (SSL_pending(client->ssl));
367 int Client_write_fd(int fd)
370 client_t *client = NULL;
372 list_iterate(itr, &clients) {
373 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
374 client = list_get_entry(itr, client_t, node);
379 Log_fatal("No client found for fd %d", fd);
380 Client_write(client);
384 int Client_write(client_t *client)
388 if (client->readBlockedOnWrite) {
389 client->readBlockedOnWrite = false;
390 Log_debug("Client_write: readBlockedOnWrite == true");
391 return Client_read(client);
393 rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
395 client->txcount += rc;
396 if (client->txcount == client->txsize)
397 client->txsize = client->txcount = 0;
400 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
401 client->writeBlockedOnRead = true;
404 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
408 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
409 Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
411 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
416 if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
418 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
419 list_del(list_get_first(&client->txMsgQueue));
420 client->txQueueCount--;
421 Client_send_message(client, msg);
426 int Client_send_message(client_t *client, message_t *msg)
428 if (!client->authenticated && msg->messageType != Version) {
432 if (client->txsize != 0 || !client->SSLready) {
434 if ((client->txQueueCount > 5 && msg->messageType == UDPTunnel) ||
435 client->txQueueCount > 30) {
439 client->txQueueCount++;
440 list_add_tail(&msg->node, &client->txMsgQueue);
441 Log_debug("Queueing message");
444 memset(client->txbuf, 0, BUFSIZE);
445 len = Msg_messageToNetwork(msg, client->txbuf);
446 doAssert(len < BUFSIZE);
448 client->txsize = len;
450 Client_write(client);
456 client_t *Client_iterate(client_t **client_itr)
458 client_t *c = *client_itr;
460 if (list_empty(&clients))
464 c = list_get_entry(list_get_first(&clients), client_t, node);
466 if (list_get_next(&c->node) == &clients)
469 c = list_get_entry(list_get_next(&c->node), client_t, node);
476 int Client_send_message_except(client_t *client, message_t *msg)
478 client_t *itr = NULL;
481 Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
482 while (Client_iterate(&itr) != NULL) {
485 Msg_inc_ref(msg); /* One extra reference for each new copy */
486 Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->playerName, msg->refcount);
487 Client_send_message(itr, msg);
490 Msg_free(msg); /* Free our reference to the message */
493 Msg_free(msg); /* If only 1 client is connected then no message is passed
494 * to Client_send_message(). Free it here. */
499 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
501 if (CryptState_isValid(&client->cryptState) &&
502 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
505 if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
506 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
508 Timer_restart(&client->cryptState.tLastRequest);
510 sendmsg = Msg_create(CryptSetup);
511 Log_info_client(client, "Requesting voice channel crypt resync");
512 Client_send_message(client, sendmsg);
518 #define UDP_PACKET_SIZE 1024
519 int Client_read_udp()
522 struct sockaddr_in from;
523 socklen_t fromlen = sizeof(struct sockaddr_in);
526 UDPMessageType_t msgType;
528 #if defined(__LP64__)
529 uint8_t encbuff[UDP_PACKET_SIZE + 8];
530 uint8_t *encrypted = encbuff + 4;
532 uint8_t encrypted[UDP_PACKET_SIZE];
534 uint8_t buffer[UDP_PACKET_SIZE];
536 len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
539 } else if (len < 0) {
541 } else if (len < 5) {
542 // 4 bytes crypt header + type + session
544 } else if (len > UDP_PACKET_SIZE) {
549 if (len == 12 && *encrypted == 0) {
550 uint32_t *ping = (uint32_t *)encrypted;
551 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
552 // 1 and 2 will be the timestamp, which we return unmodified.
553 ping[3] = htonl((uint32_t)clientcount);
554 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
555 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
557 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
561 key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
564 while (Client_iterate(&itr) != NULL) {
565 if (itr->key == key) {
566 if (!checkDecrypt(itr, encrypted, buffer, len))
571 if (itr == NULL) { /* Unknown peer */
572 while (Client_iterate(&itr) != NULL) {
573 if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
574 if (checkDecrypt(itr, encrypted, buffer, len)) {
576 Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
577 memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
580 else Log_warn("Bad cryptstate from peer");
588 msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
591 case UDPVoiceCELTAlpha:
592 case UDPVoiceCELTBeta:
594 Client_voiceMsg(itr, buffer, len);
597 Log_debug("UDP Ping reply len %d", len);
598 Client_send_udp(itr, buffer, len);
601 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
608 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
610 if (IS_AUTH(dst) && dst != src && !dst->deaf) {
611 if (poslen > 0 && /* Has positional data */
612 src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
613 strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
614 Client_send_udp(dst, data, len);
616 Client_send_udp(dst, data, len - poslen);
620 /* Handle decrypted voice message */
621 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
623 uint8_t buffer[UDP_PACKET_SIZE];
624 pds_t *pdi = Pds_create(data + 1, len - 1);
625 pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
626 unsigned int type = data[0] & 0xe0;
627 unsigned int target = data[0] & 0x1f;
628 unsigned int poslen, counter;
629 int offset, packetsize;
632 channel_t *ch = (channel_t *)client->channel;
635 if (!client->authenticated || client->mute)
638 packetsize = 20 + 8 + 4 + len;
639 if (client->availableBandwidth - packetsize < 0)
640 goto out; /* Discard */
641 client->availableBandwidth -= packetsize;
643 counter = Pds_get_numval(pdi); /* step past session id */
645 counter = Pds_next8(pdi);
646 offset = Pds_skip(pdi, counter & 0x7f);
647 } while ((counter & 0x80) && offset > 0);
649 poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
651 Pds_add_numval(pds, client->sessionId);
652 Pds_append_data_nosize(pds, data + 1, len - 1);
654 if (target == 0x1f) { /* Loopback */
655 buffer[0] = (uint8_t) type;
656 Client_send_udp(client, buffer, pds->offset + 1);
658 else if (target == 0) { /* regular channel speech */
659 buffer[0] = (uint8_t) type;
664 list_iterate(itr, &ch->clients) {
666 c = list_get_entry(itr, client_t, chan_node);
667 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
670 if (!list_empty(&ch->channel_links)) {
671 struct dlist *ch_itr;
672 list_iterate(ch_itr, &ch->channel_links) {
674 ch_link = list_get_entry(ch_itr, channel_t, link_node);
675 list_iterate(itr, &ch_link->clients) {
677 c = list_get_entry(itr, client_t, chan_node);
678 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
679 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
683 } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
687 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
688 Log_debug("Whisper channel %d", vt->channels[i]);
689 ch = Chan_fromId(vt->channels[i]);
692 list_iterate(itr, &ch->clients) {
694 c = list_get_entry(itr, client_t, chan_node);
695 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
699 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
701 Log_debug("Whisper session %d", vt->sessions[i]);
702 while (Client_iterate(&c) != NULL) {
703 if (c->sessionId == vt->sessions[i]) {
704 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
718 static int Client_send_udp(client_t *client, uint8_t *data, int len)
722 if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
723 #if defined(__LP64__)
724 buf = mbuf = malloc(len + 4 + 16);
727 mbuf = buf = malloc(len + 4);
730 Log_fatal("Out of memory");
732 CryptState_encrypt(&client->cryptState, data, buf, len);
734 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
740 memcpy(buf, data, len);
741 msg = Msg_create(UDPTunnel);
743 msg->payload.UDPTunnel->packet.data = buf;
744 msg->payload.UDPTunnel->packet.len = len;
745 Client_send_message(client, msg);