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