Use a dynamic list for codecs instead of arrays.
[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 if (client->drainleft > 0)
386                         rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
387                 else
388                         rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
389                 if (rc > 0) {
390                         message_t *msg;
391                         if (client->drainleft > 0)
392                                 client->drainleft -= rc;
393                         else {
394                                 client->rxcount += rc;
395                                 if (!client->msgsize && client->rxcount >= 6) {
396                                         uint32_t msgLen;
397                                         memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
398                                         client->msgsize = ntohl(msgLen);
399                                 }
400                                 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
401                                         Log_info_client(client, "Too big message received (%d bytes). Discarding.", client->msgsize);
402                                         client->rxcount = client->msgsize = 0;
403                                         client->drainleft = client->msgsize;
404                                 }
405                                 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
406                                         msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
407                                         /* pass messsage to handler */
408                                         if (msg)
409                                                         Mh_handle_message(client, msg);
410                                         client->rxcount = client->msgsize = 0;
411                                 }
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         return 0;       
442 }
443
444 int Client_write_fd(int fd)
445 {
446         struct dlist *itr;
447         client_t *client = NULL;
448         
449         list_iterate(itr, &clients) {
450                 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
451                         client = list_get_entry(itr, client_t, node);
452                         break;
453                 }
454         }
455         if (client == NULL)
456                 Log_fatal("No client found for fd %d", fd);
457         Client_write(client);
458         return 0;
459 }
460
461 int Client_write(client_t *client)
462 {
463         int rc;
464         
465         if (client->readBlockedOnWrite) {
466                 client->readBlockedOnWrite = false;
467                 Log_debug("Client_write: readBlockedOnWrite == true");
468                 return Client_read(client);
469         }
470         rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
471         if (rc > 0) {
472                 client->txcount += rc;
473                 if (client->txcount == client->txsize)
474                         client->txsize = client->txcount = 0;
475         }
476         else if (rc < 0) {
477                 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
478                         client->writeBlockedOnRead = true;
479                         return 0;
480                 }
481                 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
482                         return 0;
483                 }
484                 else {
485                         if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
486                                 Log_warn("Client_write: Error: %s  - Closing connection", strerror(errno));
487                         else
488                                 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
489                         Client_free(client);
490                         return -1;
491                 }
492         }
493         if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
494                 message_t *msg;
495                 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
496                 list_del(list_get_first(&client->txMsgQueue));
497                 client->txQueueCount--;
498                 Client_send_message(client, msg);
499         }
500         return 0;
501 }
502
503 int Client_send_message(client_t *client, message_t *msg)
504 {
505         if (!client->authenticated && msg->messageType != Version) {
506                 Msg_free(msg);
507                 return 0;
508         }
509         if (client->txsize != 0 || !client->SSLready) {
510                 /* Queue message */
511                 if ((client->txQueueCount > 5 &&  msg->messageType == UDPTunnel) ||
512                         client->txQueueCount > 30) {
513                         Msg_free(msg);
514                         return -1;
515                 }
516                 client->txQueueCount++;
517                 list_add_tail(&msg->node, &client->txMsgQueue);
518                 Log_debug("Queueing message");
519         } else {
520                 int len;
521                 memset(client->txbuf, 0, BUFSIZE);
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) {
662                 goto out;
663         }
664         
665         msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
666         switch (msgType) {
667         case UDPVoiceSpeex:
668         case UDPVoiceCELTAlpha:
669         case UDPVoiceCELTBeta:
670                 // u->bUdp = true;
671                 Client_voiceMsg(itr, buffer, len);
672                 break;
673         case UDPPing:
674                 Log_debug("UDP Ping reply len %d", len);
675                 Client_send_udp(itr, buffer, len);
676                 break;
677         default:
678                 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
679                 break;
680         }
681 out:
682         return 0;
683 }
684
685 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
686 {
687         if (IS_AUTH(dst) && dst != src && !dst->deaf) {
688                 if (poslen > 0 && /* Has positional data */
689                         src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
690                         strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
691                         Client_send_udp(dst, data, len);
692                 else
693                         Client_send_udp(dst, data, len - poslen);
694         }
695 }
696
697 /* Handle decrypted voice message */
698 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
699 {
700         uint8_t buffer[UDP_PACKET_SIZE];
701         pds_t *pdi = Pds_create(data + 1, len - 1);
702         pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
703         unsigned int type = data[0] & 0xe0;
704         unsigned int target = data[0] & 0x1f;
705         unsigned int poslen, counter;
706         int offset, packetsize;
707         voicetarget_t *vt;
708         
709         channel_t *ch = (channel_t *)client->channel;
710         struct dlist *itr;
711         
712         if (!client->authenticated || client->mute)
713                 goto out;
714         
715         packetsize = 20 + 8 + 4 + len;
716         if (client->availableBandwidth - packetsize < 0)
717                 goto out; /* Discard */
718         client->availableBandwidth -= packetsize;
719         
720         counter = Pds_get_numval(pdi); /* step past session id */
721         do {
722                 counter = Pds_next8(pdi);
723                 offset = Pds_skip(pdi, counter & 0x7f);
724         } while ((counter & 0x80) && offset > 0);
725
726         poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
727         
728         Pds_add_numval(pds, client->sessionId);
729         Pds_append_data_nosize(pds, data + 1, len - 1);
730         
731         if (target == 0x1f) { /* Loopback */
732                 buffer[0] = (uint8_t) type;
733                 Client_send_udp(client, buffer, pds->offset + 1);
734         }
735         else if (target == 0) { /* regular channel speech */
736                 buffer[0] = (uint8_t) type;
737                 
738                 if (ch == NULL)
739                         goto out;
740                 
741                 list_iterate(itr, &ch->clients) {
742                         client_t *c;
743                         c = list_get_entry(itr, client_t, chan_node);
744                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
745                 }
746                 /* Channel links */
747                 if (!list_empty(&ch->channel_links)) {
748                         struct dlist *ch_itr;
749                         list_iterate(ch_itr, &ch->channel_links) {
750                                 channel_t *ch_link;
751                                 ch_link = list_get_entry(ch_itr, channel_t, link_node);
752                                 list_iterate(itr, &ch_link->clients) {
753                                         client_t *c;
754                                         c = list_get_entry(itr, client_t, chan_node);
755                                         Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
756                                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
757                                 }
758                         }
759                 }
760         } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
761                 int i;
762                 channel_t *ch;
763                 /* Channels */
764                 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
765                         Log_debug("Whisper channel %d", vt->channels[i]);
766                         ch = Chan_fromId(vt->channels[i]);
767                         if (ch == NULL)
768                                 continue;
769                         list_iterate(itr, &ch->clients) {
770                                 client_t *c;
771                                 c = list_get_entry(itr, client_t, chan_node);
772                                 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
773                         }
774                 }                       
775                 /* Sessions */
776                 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
777                         client_t *c;
778                         Log_debug("Whisper session %d", vt->sessions[i]);
779                         while (Client_iterate(&c) != NULL) {
780                                 if (c->sessionId == vt->sessions[i]) {
781                                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
782                                         break;
783                                 }
784                         }
785                 }
786         }
787 out:
788         Pds_free(pds);
789         Pds_free(pdi);
790         
791         return 0;
792 }
793
794
795 static int Client_send_udp(client_t *client, uint8_t *data, int len)
796 {
797         uint8_t *buf, *mbuf;
798
799         if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
800 #if defined(__LP64__)
801                 buf = mbuf = malloc(len + 4 + 16);
802                 buf += 4;
803 #else
804                 mbuf = buf = malloc(len + 4);
805 #endif
806                 if (mbuf == NULL)
807                         Log_fatal("Out of memory");
808                 
809                 CryptState_encrypt(&client->cryptState, data, buf, len);
810                 
811                 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
812                 
813                 free(mbuf);
814         } else {
815                 message_t *msg;
816                 buf = malloc(len);
817                 memcpy(buf, data, len);
818                 msg = Msg_create(UDPTunnel);
819                 
820                 msg->payload.UDPTunnel->packet.data = buf;
821                 msg->payload.UDPTunnel->packet.len = len;
822                 Client_send_message(client, msg);
823         }
824         return 0;
825 }