Add support for UserStats message.
[umurmur.git] / src / client.c
1 /* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
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.
18
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.
30 */
31 #include <sys/poll.h>
32 #include <sys/socket.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <limits.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include "log.h"
39 #include "list.h"
40 #include "client.h"
41 #include "ssl.h"
42 #include "messages.h"
43 #include "messagehandler.h"
44 #include "conf.h"
45 #include "channel.h"
46 #include "version.h"
47 #include "voicetarget.h"
48
49 extern char system_string[], version_string[];
50
51 static int Client_read(client_t *client);
52 static int Client_write(client_t *client);
53 static int Client_send_udp(client_t *client, uint8_t *data, int len);
54 void Client_free(client_t *client);
55
56 declare_list(clients);
57 static int clientcount; /* = 0 */
58 static int maxBandwidth;
59
60 int iCodecAlpha, iCodecBeta;
61 bool_t bPreferAlpha;
62
63 extern int udpsock;
64
65 void Client_init()
66 {
67         maxBandwidth = getIntConf(MAX_BANDWIDTH) / 8; /* From bits/s -> bytes/s */
68 }
69
70 int Client_count()
71 {
72         return clientcount;
73 }
74
75 int Client_getfds(struct pollfd *pollfds)
76 {
77         struct dlist *itr;
78         int i = 0;
79         list_iterate(itr, &clients) {
80                 client_t *c;
81                 c = list_get_entry(itr, client_t, node);
82                 pollfds[i].fd = c->tcpfd;
83                 pollfds[i].events = POLLIN | POLLHUP | POLLERR;
84                 if (c->txsize > 0 || c->readBlockedOnWrite) /* Data waiting to be sent? */
85                         pollfds[i].events |= POLLOUT;
86                 i++;
87         }
88         return i;
89 }
90
91 void Client_janitor()
92 {
93         struct dlist *itr;
94         int bwTop = maxBandwidth + maxBandwidth / 4;
95         list_iterate(itr, &clients) {
96                 client_t *c;
97                 c = list_get_entry(itr, client_t, node);
98                 Log_debug("Client %s BW available %d", c->username, c->availableBandwidth);
99                 c->availableBandwidth += maxBandwidth;
100                 if (c->availableBandwidth > bwTop)
101                         c->availableBandwidth = bwTop;
102                 
103                 if (Timer_isElapsed(&c->lastActivity, 1000000LL * INACTICITY_TIMEOUT)) {
104                         /* No activity from client - assume it is lost and close. */
105                         Log_info_client(c, "Timeout, closing.");
106                         Client_free(c);
107                 }
108         }
109 }
110
111 void Client_codec_add(client_t *client, int codec)
112 {
113         codec_t *cd = malloc(sizeof(codec_t));
114         if (cd == NULL)
115                 Log_fatal("Out of memory");
116         init_list_entry(&cd->node);
117         cd->codec = codec;
118         list_add_tail(&cd->node, &client->codecs);
119 }
120
121 void Client_codec_free(client_t *client)
122 {
123         struct dlist *itr, *save;
124         list_iterate_safe(itr, save, &client->codecs) {
125                 list_del(&list_get_entry(itr, codec_t, node)->node);
126                 free(list_get_entry(itr, codec_t, node));
127         }
128 }
129
130 codec_t *Client_codec_iterate(client_t *client, codec_t **codec_itr)
131 {
132         codec_t *cd = *codec_itr;
133
134         if (list_empty(&client->codecs))
135                 return NULL;
136         
137         if (cd == NULL) {
138                 cd = list_get_entry(list_get_first(&client->codecs), codec_t, node);
139         } else {
140                 if (list_get_next(&cd->node) == &client->codecs)
141                         cd = NULL;
142                 else
143                         cd = list_get_entry(list_get_next(&cd->node), codec_t, node);
144         }
145         *codec_itr = cd;
146         return cd;
147 }
148
149 void recheckCodecVersions()
150 {
151         client_t *client_itr = NULL;
152         int max = 0, version, current_version;
153         message_t *sendmsg;
154         struct dlist codec_list, *itr, *save;
155         codec_t *codec_itr, *cd;
156         bool_t found;
157         
158         init_list_entry(&codec_list);
159         
160         while (Client_iterate(&client_itr) != NULL) {
161                 codec_itr = NULL;
162                 while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
163                         found = false;
164                         list_iterate(itr, &codec_list) {
165                                 cd = list_get_entry(itr, codec_t, node);
166                                 if (cd->codec == codec_itr->codec) {
167                                         cd->count++;
168                                         found = true;
169                                 }
170                         }
171                         if (!found) {
172                                 cd = malloc(sizeof(codec_t));
173                                 if (!cd)
174                                         Log_fatal("Out of memory");
175                                 memset(cd, 0, sizeof(codec_t));
176                                 init_list_entry(&cd->node);
177                                 cd->codec = codec_itr->codec;
178                                 cd->count = 1;
179                                 list_add_tail(&cd->node, &codec_list);
180                         }
181                 }
182         }
183         
184         list_iterate(itr, &codec_list) {
185                 cd = list_get_entry(itr, codec_t, node);
186                 if (cd->count > max) {
187                         max = cd->count;
188                         version = cd->codec;
189                 }
190         }
191         list_iterate_safe(itr, save, &codec_list) {
192                 list_del(&list_get_entry(itr, codec_t, node)->node);
193                 free(list_get_entry(itr, codec_t, node));
194         }
195         
196         current_version = bPreferAlpha ? iCodecAlpha : iCodecBeta;
197         if (current_version == version)
198                 return;
199         // If we don't already use the compat bitstream version set
200         // it as alpha and announce it. If another codec now got the
201         // majority set it as the opposite of the currently valid bPreferAlpha
202         // and announce it.
203         if (version == (uint32_t)0x8000000a)
204                 bPreferAlpha = true;
205         else
206                 bPreferAlpha = ! bPreferAlpha;
207
208         if (bPreferAlpha)
209                 iCodecAlpha = version;
210         else
211                 iCodecBeta = version;
212         
213         sendmsg = Msg_create(CodecVersion);
214         sendmsg->payload.codecVersion->alpha = version;
215         sendmsg->payload.codecVersion->beta = version;
216         sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
217         Client_send_message_except(NULL, sendmsg);
218         
219         Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
220                          bPreferAlpha ? iCodecAlpha : iCodecBeta);
221         
222 }
223
224 static int findFreeSessionId()
225 {
226         int id;
227         client_t *itr = NULL;
228
229         for (id = 1; id < INT_MAX; id++) {
230                 itr = NULL;
231                 while ((itr = Client_iterate(&itr)) != NULL) {
232                         if (itr->sessionId == id)
233                                 break;
234                 }
235                 if (itr == NULL) /* Found free id */
236                         return id;
237         }
238         return -1;
239 }
240
241 int Client_add(int fd, struct sockaddr_in *remote)
242 {
243         client_t *newclient;
244         message_t *sendmsg;
245         
246         newclient = malloc(sizeof(client_t));
247         if (newclient == NULL)
248                 Log_fatal("Out of memory");
249         memset(newclient, 0, sizeof(client_t));
250
251         newclient->tcpfd = fd;
252         memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
253         newclient->ssl = SSLi_newconnection(&newclient->tcpfd, &newclient->SSLready);
254         if (newclient->ssl == NULL) {
255                 Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
256                                  ntohs(remote->sin_port));
257                 free(newclient);
258                 return -1;
259         }
260         newclient->availableBandwidth = maxBandwidth;
261         Timer_init(&newclient->lastActivity);
262         Timer_init(&newclient->connectTime);
263         Timer_init(&newclient->idleTime);
264         newclient->sessionId = findFreeSessionId();
265         if (newclient->sessionId < 0)
266                 Log_fatal("Could not find a free session ID");
267         
268         init_list_entry(&newclient->txMsgQueue);
269         init_list_entry(&newclient->chan_node);
270         init_list_entry(&newclient->node);
271         init_list_entry(&newclient->voicetargets);
272         init_list_entry(&newclient->codecs);
273         
274         list_add_tail(&newclient->node, &clients);
275         clientcount++;
276         
277         /* Send version message to client */
278         sendmsg = Msg_create(Version);
279         sendmsg->payload.version->has_version = true;
280         sendmsg->payload.version->version = PROTOCOL_VERSION;
281         sendmsg->payload.version->release = strdup(UMURMUR_VERSION);
282         sendmsg->payload.version->os = strdup(system_string);
283         sendmsg->payload.version->os_version = strdup(version_string);
284         Client_send_message(newclient, sendmsg);
285
286         return 0;
287 }
288
289 void Client_free(client_t *client)
290 {
291         struct dlist *itr, *save;
292         message_t *sendmsg;
293
294         if (client->authenticated) {
295                 int leave_id;
296                 leave_id = Chan_userLeave(client);
297                 if (leave_id > 0) { /* Remove temp channel */
298                         sendmsg = Msg_create(ChannelRemove);
299                         sendmsg->payload.channelRemove->channel_id = leave_id;
300                         Client_send_message_except(client, sendmsg);
301                 }
302                 sendmsg = Msg_create(UserRemove);
303                 sendmsg->payload.userRemove->session = client->sessionId;
304                 Client_send_message_except(client, sendmsg);
305         }
306         list_iterate_safe(itr, save, &client->txMsgQueue) {
307                 list_del(&list_get_entry(itr, message_t, node)->node);
308                 Msg_free(list_get_entry(itr, message_t, node));
309         }
310         Client_codec_free(client);
311         Voicetarget_free_all(client);
312         
313         list_del(&client->node);
314         if (client->ssl)
315                 SSLi_free(client->ssl);
316         close(client->tcpfd);
317         clientcount--;
318         if (client->release)
319                 free(client->release);
320         if (client->os)
321                 free(client->os);                       
322         if (client->os_version)
323                 free(client->os_version);                       
324         if (client->username)
325                 free(client->username);
326         if (client->context)
327                 free(client->context);
328         free(client);
329 }
330
331 void Client_close(client_t *client)
332 {
333         SSLi_shutdown(client->ssl);
334         client->shutdown_wait = true;
335 }
336
337 void Client_disconnect_all()
338 {
339         struct dlist *itr, *save;
340         
341         list_iterate_safe(itr, save, &clients) {
342                 Client_free(list_get_entry(itr, client_t, node));
343         }
344 }
345
346 int Client_read_fd(int fd)
347 {
348         struct dlist *itr;
349         client_t *client = NULL;
350         
351         list_iterate(itr, &clients) {
352                 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
353                         client = list_get_entry(itr, client_t, node);
354                         break;
355                 }
356         }
357         if (client == NULL)
358                 Log_fatal("No client found for fd %d", fd);
359         
360         return Client_read(client);
361 }
362
363 int Client_read(client_t *client)
364 {
365         int rc;
366
367         Timer_restart(&client->lastActivity);
368         
369         if (client->writeBlockedOnRead) {
370                 client->writeBlockedOnRead = false;
371                 Log_debug("Client_read: writeBlockedOnRead == true");
372                 return Client_write(client);
373         }
374         
375         if (client->shutdown_wait) {
376                 Client_free(client);
377                 return 0;
378         }
379         if (!client->SSLready) {
380                 int rc;
381                 rc = SSLi_nonblockaccept(client->ssl, &client->SSLready);
382                 if (rc < 0) {
383                         Client_free(client);
384                         return -1;
385                 }
386         }
387
388         do {
389                 errno = 0;
390                 if (!client->msgsize) 
391                         rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
392                 else
393                         rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
394                 if (rc > 0) {
395                         message_t *msg;
396                         client->rxcount += rc;
397                         if (!client->msgsize && client->rxcount >= 6) {
398                                 uint32_t msgLen;
399                                 memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
400                                 client->msgsize = ntohl(msgLen);
401                         }
402                         if (client->msgsize > BUFSIZE - 6) {
403                                 /* XXX - figure out how to handle this. A large size here can represent two cases:
404                                  * 1. A valid size. The only message that is this big is UserState message with a big texture
405                                  * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
406                                  */
407                                 Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
408                                                  client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
409                                 Client_free(client);
410                                 return -1;
411                                 /* client->rxcount = client->msgsize = 0; */
412                         }
413                         else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
414                                 msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
415                                 /* pass messsage to handler */
416                                 if (msg)
417                                         Mh_handle_message(client, msg);
418                                 client->rxcount = client->msgsize = 0;
419                         }
420                 } else /* rc <= 0 */ {
421                         if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
422                                 return 0;
423                         }
424                         else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
425                                 client->readBlockedOnWrite = true;
426                                 return 0;
427                         }
428                         else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN) {
429                                 Log_info_client(client, "Connection closed by peer");
430                                 if (!client->shutdown_wait)
431                                         Client_close(client);
432                         }
433                         else {
434                                 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
435                                         Log_info_client(client, "Connection closed by peer");
436                                 }
437                                 else {
438                                         Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
439                                 }
440                                 Client_free(client);
441                                 return -1;
442                         }
443                 }
444         } while (SSLi_data_pending(client->ssl));
445         
446         return 0;
447 }
448
449 int Client_write_fd(int fd)
450 {
451         struct dlist *itr;
452         client_t *client = NULL;
453         
454         list_iterate(itr, &clients) {
455                 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
456                         client = list_get_entry(itr, client_t, node);
457                         break;
458                 }
459         }
460         if (client == NULL)
461                 Log_fatal("No client found for fd %d", fd);
462         Client_write(client);
463         return 0;
464 }
465
466 int Client_write(client_t *client)
467 {
468         int rc;
469         
470         if (client->readBlockedOnWrite) {
471                 client->readBlockedOnWrite = false;
472                 Log_debug("Client_write: readBlockedOnWrite == true");
473                 return Client_read(client);
474         }
475         rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
476         if (rc > 0) {
477                 client->txcount += rc;
478                 if (client->txcount == client->txsize)
479                         client->txsize = client->txcount = 0;
480         }
481         else if (rc < 0) {
482                 if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
483                         client->writeBlockedOnRead = true;
484                         return 0;
485                 }
486                 else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
487                         return 0;
488                 }
489                 else {
490                         if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL)
491                                 Log_warn("Client_write: Error: %s  - Closing connection", strerror(errno));
492                         else
493                                 Log_warn("Client_write: SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
494                         Client_free(client);
495                         return -1;
496                 }
497         }
498         if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
499                 message_t *msg;
500                 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
501                 list_del(list_get_first(&client->txMsgQueue));
502                 client->txQueueCount--;
503                 Client_send_message(client, msg);
504         }
505         return 0;
506 }
507
508 int Client_send_message(client_t *client, message_t *msg)
509 {
510         if (!client->authenticated && msg->messageType != Version) {
511                 Msg_free(msg);
512                 return 0;
513         }
514         if (client->txsize != 0 || !client->SSLready) {
515                 /* Queue message */
516                 if ((client->txQueueCount > 5 &&  msg->messageType == UDPTunnel) ||
517                         client->txQueueCount > 30) {
518                         Msg_free(msg);
519                         return -1;
520                 }
521                 client->txQueueCount++;
522                 list_add_tail(&msg->node, &client->txMsgQueue);
523                 Log_debug("Queueing message");
524         } else {
525                 int len;
526                 len = Msg_messageToNetwork(msg, client->txbuf);
527                 doAssert(len < BUFSIZE);
528
529                 client->txsize = len;
530                 client->txcount = 0;
531                 Client_write(client);
532                 Msg_free(msg);
533         }
534         return 0;
535 }
536
537 client_t *Client_iterate(client_t **client_itr)
538 {
539         client_t *c = *client_itr;
540
541         if (list_empty(&clients))
542                 return NULL;
543         
544         if (c == NULL) {
545                 c = list_get_entry(list_get_first(&clients), client_t, node);
546         } else {
547                 if (list_get_next(&c->node) == &clients)
548                         c = NULL;
549                 else
550                         c = list_get_entry(list_get_next(&c->node), client_t, node);
551         }
552         *client_itr = c;
553         return c;
554 }
555
556
557 int Client_send_message_except(client_t *client, message_t *msg)
558 {
559         client_t *itr = NULL;
560         int count = 0;
561         
562         Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
563         while (Client_iterate(&itr) != NULL) {
564                 if (itr != client) {
565                         if (count++ > 0)
566                                 Msg_inc_ref(msg); /* One extra reference for each new copy */
567                         Log_debug("Msg %d to %s refcount %d",  msg->messageType, itr->username, msg->refcount);
568                         Client_send_message(itr, msg);
569                 }
570         }
571         Msg_free(msg); /* Free our reference to the message */
572         
573         if (count == 0)
574                 Msg_free(msg); /* If only 1 client is connected then no message is passed
575                                                 * to Client_send_message(). Free it here. */
576                 
577         return 0;
578 }
579
580 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
581 {
582         if (CryptState_isValid(&client->cryptState) &&
583                 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
584                 return true;
585
586         if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
587                 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
588                         message_t *sendmsg;
589                         Timer_restart(&client->cryptState.tLastRequest);
590                         
591                         sendmsg = Msg_create(CryptSetup);
592                         Log_info_client(client, "Requesting voice channel crypt resync");               
593                         Client_send_message(client, sendmsg);
594                 }
595         }
596         return false;
597 }
598
599 #define UDP_PACKET_SIZE 1024
600 int Client_read_udp()
601 {
602         int len;
603         struct sockaddr_in from;
604         socklen_t fromlen = sizeof(struct sockaddr_in);
605         uint64_t key;
606         client_t *itr;
607         UDPMessageType_t msgType;
608         
609 #if defined(__LP64__)
610         uint8_t encbuff[UDP_PACKET_SIZE + 8];
611         uint8_t *encrypted = encbuff + 4;
612 #else
613         uint8_t encrypted[UDP_PACKET_SIZE];
614 #endif
615         uint8_t buffer[UDP_PACKET_SIZE];
616         
617         len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
618         if (len == 0) {
619                 return -1;
620         } else if (len < 0) {
621                 return -1;
622         } else if (len < 5) {
623                 // 4 bytes crypt header + type + session
624                 return 0;
625         } else if (len > UDP_PACKET_SIZE) {
626                 return 0;
627         }
628
629         /* Ping packet */
630         if (len == 12 && *encrypted == 0) {
631                 uint32_t *ping = (uint32_t *)encrypted;
632                 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
633                 // 1 and 2 will be the timestamp, which we return unmodified.
634                 ping[3] = htonl((uint32_t)clientcount);
635                 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
636                 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
637                 
638                 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
639                 return 0;
640         }
641         
642         key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
643         itr = NULL;
644         
645         while (Client_iterate(&itr) != NULL) {
646                 if (itr->key == key) {
647                         if (!checkDecrypt(itr, encrypted, buffer, len))
648                                 goto out;
649                         break;
650                 }
651         }       
652         if (itr == NULL) { /* Unknown peer */
653                 while (Client_iterate(&itr) != NULL) {
654                         if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
655                                 if (checkDecrypt(itr, encrypted, buffer, len)) {
656                                         itr->key = key;
657                                         Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
658                                         memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
659                                         break;
660                                 }
661                                 else Log_warn("Bad cryptstate from peer");
662                         }
663                 } /* while */
664         }
665         if (itr == NULL) { /* Couldn't find this peer among connected clients */
666                 goto out;
667         }
668         
669         itr->bUDP = true;
670         len -= 4; /* Adjust for crypt header */
671         msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
672         switch (msgType) {
673         case UDPVoiceSpeex:
674         case UDPVoiceCELTAlpha:
675         case UDPVoiceCELTBeta:
676                 Client_voiceMsg(itr, buffer, len);
677                 break;
678         case UDPPing:
679                 Log_debug("UDP Ping reply len %d", len);
680                 Client_send_udp(itr, buffer, len);
681                 break;
682         default:
683                 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
684                 break;
685         }
686         
687 out:
688         return 0;
689 }
690
691 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
692 {
693         if (IS_AUTH(dst) && dst != src && !dst->deaf) {
694                 if (poslen > 0 && /* Has positional data */
695                         src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
696                         strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
697                         Client_send_udp(dst, data, len);
698                 else 
699                         Client_send_udp(dst, data, len - poslen);
700         }
701 }
702
703 /* Handle decrypted voice message */
704 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
705 {
706         uint8_t buffer[UDP_PACKET_SIZE];
707         pds_t *pdi = Pds_create(data + 1, len - 1);
708         pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
709         unsigned int type = data[0] & 0xe0;
710         unsigned int target = data[0] & 0x1f;
711         unsigned int poslen, counter;
712         int offset, packetsize;
713         voicetarget_t *vt;
714         
715         channel_t *ch = (channel_t *)client->channel;
716         struct dlist *itr;
717         
718         if (!client->authenticated || client->mute)
719                 goto out;
720         
721         packetsize = 20 + 8 + 4 + len;
722         if (client->availableBandwidth - packetsize < 0)
723                 goto out; /* Discard */
724         client->availableBandwidth -= packetsize;
725         
726         Timer_restart(&client->idleTime);
727         
728         counter = Pds_get_numval(pdi); /* step past session id */
729         do {
730                 counter = Pds_next8(pdi);
731                 offset = Pds_skip(pdi, counter & 0x7f);
732         } while ((counter & 0x80) && offset > 0);
733
734         poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
735         
736         Pds_add_numval(pds, client->sessionId);
737         Pds_append_data_nosize(pds, data + 1, len - 1);
738         
739         if (target == 0x1f) { /* Loopback */
740                 buffer[0] = (uint8_t) type;
741                 Client_send_udp(client, buffer, pds->offset + 1);
742         }
743         else if (target == 0) { /* regular channel speech */
744                 buffer[0] = (uint8_t) type;
745                 
746                 if (ch == NULL)
747                         goto out;
748                 
749                 list_iterate(itr, &ch->clients) {
750                         client_t *c;
751                         c = list_get_entry(itr, client_t, chan_node);
752                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
753                 }
754         } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
755                 int i;
756                 channel_t *ch;
757                 /* Channels */
758                 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
759                         buffer[0] = (uint8_t) (type | 1);
760                         Log_debug("Whisper channel %d", vt->channels[i]);
761                         ch = Chan_fromId(vt->channels[i].channel);
762                         if (ch == NULL)
763                                 continue;
764                         list_iterate(itr, &ch->clients) {
765                                 client_t *c;
766                                 c = list_get_entry(itr, client_t, chan_node);
767                                 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
768                         }
769                         /* Channel links */
770                         if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
771                                 struct dlist *ch_itr;
772                                 list_iterate(ch_itr, &ch->channel_links) {
773                                         channel_t *ch_link;
774                                         ch_link = list_get_entry(ch_itr, channel_t, link_node);
775                                         list_iterate(itr, &ch_link->clients) {
776                                                 client_t *c;
777                                                 c = list_get_entry(itr, client_t, chan_node);
778                                                 Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
779                                                 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
780                                         }
781                                 }
782                         }
783                         /* children */
784                         if (vt->channels[i].children) {
785                                 struct dlist chanlist, *ch_itr;
786                                 init_list_entry(&chanlist);
787                                 Chan_buildTreeList(ch, &chanlist);
788                                 list_iterate(ch_itr, &chanlist) {
789                                         channel_t *sub;
790                                         sub = list_get_entry(ch_itr, channellist_t, node)->chan;
791                                         list_iterate(itr, &sub->clients) {
792                                                 client_t *c;
793                                                 c = list_get_entry(itr, client_t, chan_node);
794                                                 Log_debug("Child voice from %s -> %s", ch->name, sub->name);
795                                                 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
796                                         }
797                                 }
798                                 Chan_freeTreeList(&chanlist);
799                         }
800                 }                       
801                 /* Sessions */
802                 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
803                         client_t *c;
804                         buffer[0] = (uint8_t) (type | 2);
805                         Log_debug("Whisper session %d", vt->sessions[i]);
806                         while (Client_iterate(&c) != NULL) {
807                                 if (c->sessionId == vt->sessions[i]) {
808                                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
809                                         break;
810                                 }
811                         }
812                 }
813         }
814 out:
815         Pds_free(pds);
816         Pds_free(pdi);
817         
818         return 0;
819 }
820
821
822 static int Client_send_udp(client_t *client, uint8_t *data, int len)
823 {
824         uint8_t *buf, *mbuf;
825
826         if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
827                 client->bUDP) {
828 #if defined(__LP64__)
829                 buf = mbuf = malloc(len + 4 + 16);
830                 buf += 4;
831 #else
832                 mbuf = buf = malloc(len + 4);
833 #endif
834                 if (mbuf == NULL)
835                         Log_fatal("Out of memory");
836                 
837                 CryptState_encrypt(&client->cryptState, data, buf, len);
838                 
839                 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
840                 
841                 free(mbuf);
842         } else {
843                 message_t *msg;
844                 msg = Msg_CreateVoiceMsg(data, len);
845                 Client_send_message(client, msg);
846         }
847         return 0;
848 }