Remove buffer zeroing since it's not neccesary.
[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                 len = Msg_messageToNetwork(msg, client->txbuf);
522                 doAssert(len < BUFSIZE);
523
524                 client->txsize = len;
525                 client->txcount = 0;
526                 Client_write(client);
527                 Msg_free(msg);
528         }
529         return 0;
530 }
531
532 client_t *Client_iterate(client_t **client_itr)
533 {
534         client_t *c = *client_itr;
535
536         if (list_empty(&clients))
537                 return NULL;
538         
539         if (c == NULL) {
540                 c = list_get_entry(list_get_first(&clients), client_t, node);
541         } else {
542                 if (list_get_next(&c->node) == &clients)
543                         c = NULL;
544                 else
545                         c = list_get_entry(list_get_next(&c->node), client_t, node);
546         }
547         *client_itr = c;
548         return c;
549 }
550
551
552 int Client_send_message_except(client_t *client, message_t *msg)
553 {
554         client_t *itr = NULL;
555         int count = 0;
556         
557         Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
558         while (Client_iterate(&itr) != NULL) {
559                 if (itr != client) {
560                         if (count++ > 0)
561                                 Msg_inc_ref(msg); /* One extra reference for each new copy */
562                         Log_debug("Msg %d to %s refcount %d",  msg->messageType, itr->username, msg->refcount);
563                         Client_send_message(itr, msg);
564                 }
565         }
566         Msg_free(msg); /* Free our reference to the message */
567         
568         if (count == 0)
569                 Msg_free(msg); /* If only 1 client is connected then no message is passed
570                                                 * to Client_send_message(). Free it here. */
571                 
572         return 0;
573 }
574
575 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
576 {
577         if (CryptState_isValid(&client->cryptState) &&
578                 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
579                 return true;
580
581         if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
582                 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
583                         message_t *sendmsg;
584                         Timer_restart(&client->cryptState.tLastRequest);
585                         
586                         sendmsg = Msg_create(CryptSetup);
587                         Log_info_client(client, "Requesting voice channel crypt resync");               
588                         Client_send_message(client, sendmsg);
589                 }
590         }
591         return false;
592 }
593
594 #define UDP_PACKET_SIZE 1024
595 int Client_read_udp()
596 {
597         int len;
598         struct sockaddr_in from;
599         socklen_t fromlen = sizeof(struct sockaddr_in);
600         uint64_t key;
601         client_t *itr;
602         UDPMessageType_t msgType;
603         
604 #if defined(__LP64__)
605         uint8_t encbuff[UDP_PACKET_SIZE + 8];
606         uint8_t *encrypted = encbuff + 4;
607 #else
608         uint8_t encrypted[UDP_PACKET_SIZE];
609 #endif
610         uint8_t buffer[UDP_PACKET_SIZE];
611         
612         len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
613         if (len == 0) {
614                 return -1;
615         } else if (len < 0) {
616                 return -1;
617         } else if (len < 5) {
618                 // 4 bytes crypt header + type + session
619                 return 0;
620         } else if (len > UDP_PACKET_SIZE) {
621                 return 0;
622         }
623
624         /* Ping packet */
625         if (len == 12 && *encrypted == 0) {
626                 uint32_t *ping = (uint32_t *)encrypted;
627                 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
628                 // 1 and 2 will be the timestamp, which we return unmodified.
629                 ping[3] = htonl((uint32_t)clientcount);
630                 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
631                 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
632                 
633                 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
634                 return 0;
635         }
636         
637         key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
638         itr = NULL;
639         
640         while (Client_iterate(&itr) != NULL) {
641                 if (itr->key == key) {
642                         if (!checkDecrypt(itr, encrypted, buffer, len))
643                                 goto out;
644                         break;
645                 }
646         }       
647         if (itr == NULL) { /* Unknown peer */
648                 while (Client_iterate(&itr) != NULL) {
649                         if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
650                                 if (checkDecrypt(itr, encrypted, buffer, len)) {
651                                         itr->key = key;
652                                         Log_info_client(itr, "New UDP connection port %d", ntohs(from.sin_port));
653                                         memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
654                                         break;
655                                 }
656                                 else Log_warn("Bad cryptstate from peer");
657                         }
658                 } /* while */
659         }
660         if (itr == NULL) {
661                 goto out;
662         }
663         
664         msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
665         switch (msgType) {
666         case UDPVoiceSpeex:
667         case UDPVoiceCELTAlpha:
668         case UDPVoiceCELTBeta:
669                 // u->bUdp = true;
670                 Client_voiceMsg(itr, buffer, len);
671                 break;
672         case UDPPing:
673                 Log_debug("UDP Ping reply len %d", len);
674                 Client_send_udp(itr, buffer, len);
675                 break;
676         default:
677                 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
678                 break;
679         }
680 out:
681         return 0;
682 }
683
684 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
685 {
686         if (IS_AUTH(dst) && dst != src && !dst->deaf) {
687                 if (poslen > 0 && /* Has positional data */
688                         src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
689                         strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
690                         Client_send_udp(dst, data, len);
691                 else
692                         Client_send_udp(dst, data, len - poslen);
693         }
694 }
695
696 /* Handle decrypted voice message */
697 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
698 {
699         uint8_t buffer[UDP_PACKET_SIZE];
700         pds_t *pdi = Pds_create(data + 1, len - 1);
701         pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
702         unsigned int type = data[0] & 0xe0;
703         unsigned int target = data[0] & 0x1f;
704         unsigned int poslen, counter;
705         int offset, packetsize;
706         voicetarget_t *vt;
707         
708         channel_t *ch = (channel_t *)client->channel;
709         struct dlist *itr;
710         
711         if (!client->authenticated || client->mute)
712                 goto out;
713         
714         packetsize = 20 + 8 + 4 + len;
715         if (client->availableBandwidth - packetsize < 0)
716                 goto out; /* Discard */
717         client->availableBandwidth -= packetsize;
718         
719         counter = Pds_get_numval(pdi); /* step past session id */
720         do {
721                 counter = Pds_next8(pdi);
722                 offset = Pds_skip(pdi, counter & 0x7f);
723         } while ((counter & 0x80) && offset > 0);
724
725         poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
726         
727         Pds_add_numval(pds, client->sessionId);
728         Pds_append_data_nosize(pds, data + 1, len - 1);
729         
730         if (target == 0x1f) { /* Loopback */
731                 buffer[0] = (uint8_t) type;
732                 Client_send_udp(client, buffer, pds->offset + 1);
733         }
734         else if (target == 0) { /* regular channel speech */
735                 buffer[0] = (uint8_t) type;
736                 
737                 if (ch == NULL)
738                         goto out;
739                 
740                 list_iterate(itr, &ch->clients) {
741                         client_t *c;
742                         c = list_get_entry(itr, client_t, chan_node);
743                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
744                 }
745                 /* Channel links */
746                 if (!list_empty(&ch->channel_links)) {
747                         struct dlist *ch_itr;
748                         list_iterate(ch_itr, &ch->channel_links) {
749                                 channel_t *ch_link;
750                                 ch_link = list_get_entry(ch_itr, channel_t, link_node);
751                                 list_iterate(itr, &ch_link->clients) {
752                                         client_t *c;
753                                         c = list_get_entry(itr, client_t, chan_node);
754                                         Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
755                                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
756                                 }
757                         }
758                 }
759         } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
760                 int i;
761                 channel_t *ch;
762                 /* Channels */
763                 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
764                         Log_debug("Whisper channel %d", vt->channels[i]);
765                         ch = Chan_fromId(vt->channels[i]);
766                         if (ch == NULL)
767                                 continue;
768                         list_iterate(itr, &ch->clients) {
769                                 client_t *c;
770                                 c = list_get_entry(itr, client_t, chan_node);
771                                 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
772                         }
773                 }                       
774                 /* Sessions */
775                 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
776                         client_t *c;
777                         Log_debug("Whisper session %d", vt->sessions[i]);
778                         while (Client_iterate(&c) != NULL) {
779                                 if (c->sessionId == vt->sessions[i]) {
780                                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
781                                         break;
782                                 }
783                         }
784                 }
785         }
786 out:
787         Pds_free(pds);
788         Pds_free(pdi);
789         
790         return 0;
791 }
792
793
794 static int Client_send_udp(client_t *client, uint8_t *data, int len)
795 {
796         uint8_t *buf, *mbuf;
797
798         if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
799 #if defined(__LP64__)
800                 buf = mbuf = malloc(len + 4 + 16);
801                 buf += 4;
802 #else
803                 mbuf = buf = malloc(len + 4);
804 #endif
805                 if (mbuf == NULL)
806                         Log_fatal("Out of memory");
807                 
808                 CryptState_encrypt(&client->cryptState, data, buf, len);
809                 
810                 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
811                 
812                 free(mbuf);
813         } else {
814                 message_t *msg;
815                 buf = malloc(len);
816                 memcpy(buf, data, len);
817                 msg = Msg_create(UDPTunnel);
818                 
819                 msg->payload.UDPTunnel->packet.data = buf;
820                 msg->payload.UDPTunnel->packet.len = len;
821                 Client_send_message(client, msg);
822         }
823         return 0;
824 }