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