Add OS and machine info retrieval via uname
[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                 sendmsg = Msg_create(UserRemove);
224                 sendmsg->payload.userRemove->session = client->sessionId;
225                 Client_send_message_except(client, sendmsg);
226         }
227         list_iterate_safe(itr, save, &client->txMsgQueue) {
228                 list_del(&list_get_entry(itr, message_t, node)->node);
229                 Msg_free(list_get_entry(itr, message_t, node));
230         }
231         Voicetarget_free_all(client);
232         
233         list_del(&client->node);
234         list_del(&client->chan_node);
235         if (client->ssl)
236                 SSL_free(client->ssl);
237         close(client->tcpfd);
238         clientcount--;
239         if (client->release)
240                 free(client->release);
241         if (client->os)
242                 free(client->os);                       
243         if (client->playerName)
244                 free(client->playerName);
245         if (client->context)
246                 free(client->context);
247         free(client);
248 }
249
250 void Client_close(client_t *client)
251 {
252         SSL_shutdown(client->ssl);
253         client->shutdown_wait = true;
254 }
255
256 void Client_disconnect_all()
257 {
258         struct dlist *itr, *save;
259         
260         list_iterate_safe(itr, save, &clients) {
261                 Client_free(list_get_entry(itr, client_t, node));
262         }
263 }
264
265 int Client_read_fd(int fd)
266 {
267         struct dlist *itr;
268         client_t *client = NULL;
269         
270         list_iterate(itr, &clients) {
271                 if (fd == list_get_entry(itr, client_t, node)->tcpfd) {
272                         client = list_get_entry(itr, client_t, node);
273                         break;
274                 }
275         }
276         if (client == NULL)
277                 Log_fatal("No client found for fd %d", fd);
278         
279         return Client_read(client);
280 }
281
282 int Client_read(client_t *client)
283 {
284         int rc;
285
286         Timer_restart(&client->lastActivity);
287         
288         if (client->writeBlockedOnRead) {
289                 client->writeBlockedOnRead = false;
290                 Log_debug("Client_read: writeBlockedOnRead == true");
291                 return Client_write(client);
292         }
293         
294         if (client->shutdown_wait) {
295                 Client_free(client);
296                 return 0;
297         }
298         if (!client->SSLready) {
299                 int rc;
300                 rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
301                 if (rc < 0) {
302                         Client_free(client);
303                         return -1;
304                 }
305         }
306
307         do {
308                 errno = 0;
309                 if (!client->msgsize) 
310                         rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
311                 else if (client->drainleft > 0)
312                         rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
313                 else
314                         rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
315                 if (rc > 0) {
316                         message_t *msg;
317                         if (client->drainleft > 0)
318                                 client->drainleft -= rc;
319                         else {
320                                 client->rxcount += rc;
321                                 if (!client->msgsize && client->rxcount >= 6) {
322                                         uint32_t msgLen;
323                                         memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
324                                         client->msgsize = ntohl(msgLen);
325                                 }
326                                 if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
327                                         Log_warn("Too big message received (%d). Discarding.", client->msgsize);
328                                         client->rxcount = client->msgsize = 0;
329                                         client->drainleft = client->msgsize;
330                                 }
331                                 else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
332                                         msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
333                                         /* pass messsage to handler */
334                                         if (msg)
335                                                         Mh_handle_message(client, msg);
336                                         client->rxcount = client->msgsize = 0;
337                                 }
338                         }
339                 } else /* rc <= 0 */ {
340                         if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
341                                 return 0;
342                         }
343                         else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
344                                 client->readBlockedOnWrite = true;
345                                 return 0;
346                         }
347                         else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
348                                 Log_warn("Error: Zero return - closing");
349                                 if (!client->shutdown_wait)
350                                         Client_close(client);
351                         }
352                         else {
353                                 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
354                                         /* Hmm. This is where we end up when the client closes its connection.
355                                          * Kind of strange...
356                                          */
357                                         Log_info("Connection closed by peer. Session %d - %s@%s:%d",
358                                                          client->sessionId,
359                                                          client->playerName,
360                                                          inet_ntoa(client->remote_tcp.sin_addr),
361                                                          ntohs(client->remote_tcp.sin_port));
362                                 }
363                                 else {
364                                         Log_warn("SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
365                                 }
366                                 Client_free(client);
367                                 return -1;
368                         }
369                 }
370         } while (SSL_pending(client->ssl));
371         return 0;       
372 }
373
374 int Client_write_fd(int fd)
375 {
376         struct dlist *itr;
377         client_t *client = NULL;
378         
379         list_iterate(itr, &clients) {
380                 if(fd == list_get_entry(itr, client_t, node)->tcpfd) {
381                         client = list_get_entry(itr, client_t, node);
382                         break;
383                 }
384         }
385         if (client == NULL)
386                 Log_fatal("No client found for fd %d", fd);
387         Client_write(client);
388         return 0;
389 }
390
391 int Client_write(client_t *client)
392 {
393         int rc;
394         
395         if (client->readBlockedOnWrite) {
396                 client->readBlockedOnWrite = false;
397                 Log_debug("Client_write: readBlockedOnWrite == true");
398                 return Client_read(client);
399         }
400         rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
401         if (rc > 0) {
402                 client->txcount += rc;
403                 if (client->txcount == client->txsize)
404                         client->txsize = client->txcount = 0;
405         }
406         else if (rc < 0) {
407                 if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
408                         client->writeBlockedOnRead = true;
409                         return 0;
410                 }
411                 else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
412                         return 0;
413                 }
414                 else {
415                         if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
416                                 Log_warn("Client_write: Error: %s  - Closing connection", strerror(errno));
417                         else
418                                 Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
419                         Client_free(client);
420                         return -1;
421                 }
422         }
423         if (client->txsize == 0 && !list_empty(&client->txMsgQueue)) {
424                 message_t *msg;
425                 msg = list_get_entry(list_get_first(&client->txMsgQueue), message_t, node);
426                 list_del(list_get_first(&client->txMsgQueue));
427                 client->txQueueCount--;
428                 Client_send_message(client, msg);
429         }
430         return 0;
431 }
432
433 int Client_send_message(client_t *client, message_t *msg)
434 {
435         if (!client->authenticated && msg->messageType != Version) {
436                 Msg_free(msg);
437                 return 0;
438         }
439         if (client->txsize != 0 || !client->SSLready) {
440                 /* Queue message */
441                 if ((client->txQueueCount > 5 &&  msg->messageType == UDPTunnel) ||
442                         client->txQueueCount > 30) {
443                         Msg_free(msg);
444                         return -1;
445                 }
446                 client->txQueueCount++;
447                 list_add_tail(&msg->node, &client->txMsgQueue);
448                 Log_debug("Queueing message");
449         } else {
450                 int len;
451                 memset(client->txbuf, 0, BUFSIZE);
452                 len = Msg_messageToNetwork(msg, client->txbuf);
453                 doAssert(len < BUFSIZE);
454
455                 client->txsize = len;
456                 client->txcount = 0;
457                 Client_write(client);
458                 Msg_free(msg);
459         }
460         return 0;
461 }
462
463 client_t *Client_iterate(client_t **client_itr)
464 {
465         client_t *c = *client_itr;
466
467         if (list_empty(&clients))
468                 return NULL;
469         
470         if (c == NULL) {
471                 c = list_get_entry(list_get_first(&clients), client_t, node);
472         } else {
473                 if (list_get_next(&c->node) == &clients)
474                         c = NULL;
475                 else
476                         c = list_get_entry(list_get_next(&c->node), client_t, node);
477         }
478         *client_itr = c;
479         return c;
480 }
481
482
483 int Client_send_message_except(client_t *client, message_t *msg)
484 {
485         client_t *itr = NULL;
486         int count = 0;
487         
488         Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
489         while (Client_iterate(&itr) != NULL) {
490                 if (itr != client) {
491                         if (count++ > 0)
492                                 Msg_inc_ref(msg); /* One extra reference for each new copy */
493                         Log_debug("Msg %d to %s refcount %d",  msg->messageType, itr->playerName, msg->refcount);
494                         Client_send_message(itr, msg);
495                 }
496         }
497         Msg_free(msg); /* Free our reference to the message */
498         
499         if (count == 0)
500                 Msg_free(msg); /* If only 1 client is connected then no message is passed
501                                                 * to Client_send_message(). Free it here. */
502                 
503         return 0;
504 }
505
506 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
507 {
508         if (CryptState_isValid(&client->cryptState) &&
509                 CryptState_decrypt(&client->cryptState, encrypted, plain, len))
510                 return true;
511
512         if (Timer_elapsed(&client->cryptState.tLastGood) > 5000000ULL) {
513                 if (Timer_elapsed(&client->cryptState.tLastRequest) > 5000000ULL) {
514                         message_t *sendmsg;
515                         Timer_restart(&client->cryptState.tLastRequest);
516                         
517                         sendmsg = Msg_create(CryptSetup);
518                         Log_info("Requesting voice channel crypt resync. Session %d - %s@%s:%d",
519                                          client->sessionId,
520                                          client->playerName,
521                                          inet_ntoa(client->remote_tcp.sin_addr),
522                                          ntohs(client->remote_tcp.sin_port));
523                 
524                         Client_send_message(client, sendmsg);
525                 }
526         }
527         return false;
528 }
529
530 #define UDP_PACKET_SIZE 1024
531 int Client_read_udp()
532 {
533         int len;
534         struct sockaddr_in from;
535         socklen_t fromlen = sizeof(struct sockaddr_in);
536         uint64_t key;
537         client_t *itr;
538         UDPMessageType_t msgType;
539         
540 #if defined(__LP64__)
541         uint8_t encbuff[UDP_PACKET_SIZE + 8];
542         uint8_t *encrypted = encbuff + 4;
543 #else
544         uint8_t encrypted[UDP_PACKET_SIZE];
545 #endif
546         uint8_t buffer[UDP_PACKET_SIZE];
547         
548         len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
549         if (len == 0) {
550                 return -1;
551         } else if (len < 0) {
552                 return -1;
553         } else if (len < 5) {
554                 // 4 bytes crypt header + type + session
555                 return 0;
556         } else if (len > UDP_PACKET_SIZE) {
557                 return 0;
558         }
559
560         /* Ping packet */
561         if (len == 12 && *encrypted == 0) {
562                 uint32_t *ping = (uint32_t *)encrypted;
563                 ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
564                 // 1 and 2 will be the timestamp, which we return unmodified.
565                 ping[3] = htonl((uint32_t)clientcount);
566                 ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
567                 ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
568                 
569                 sendto(udpsock, encrypted, 6 * sizeof(uint32_t), 0, (struct sockaddr *)&from, fromlen);
570                 return 0;
571         }
572         
573         key = (((uint64_t)from.sin_addr.s_addr) << 16) ^ from.sin_port;
574         itr = NULL;
575         
576         while (Client_iterate(&itr) != NULL) {
577                 if (itr->key == key) {
578                         if (!checkDecrypt(itr, encrypted, buffer, len))
579                                 goto out;
580                         break;
581                 }
582         }       
583         if (itr == NULL) { /* Unknown peer */
584                 while (Client_iterate(&itr) != NULL) {
585                         if (itr->remote_tcp.sin_addr.s_addr == from.sin_addr.s_addr) {
586                                 if (checkDecrypt(itr, encrypted, buffer, len)) {
587                                         itr->key = key;
588                                         Log_info("New UDP connection from session %d - %s@%s:%d",
589                                                          itr->sessionId,
590                                                          itr->playerName,
591                                                          inet_ntoa(from.sin_addr),
592                                                          ntohs(from.sin_port));
593                                         memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
594                                         break;
595                                 }
596                                 else Log_warn("Bad cryptstate from peer");
597                         }
598                 } /* while */
599         }
600         if (itr == NULL) {
601                 goto out;
602         }
603         
604         msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
605         switch (msgType) {
606         case UDPVoiceSpeex:
607         case UDPVoiceCELTAlpha:
608         case UDPVoiceCELTBeta:
609                 // u->bUdp = true;
610                 Client_voiceMsg(itr, buffer, len);
611                 break;
612         case UDPPing:
613                 Log_debug("UDP Ping reply len %d", len);
614                 Client_send_udp(itr, buffer, len);
615                 break;
616         default:
617                 Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
618                 break;
619         }
620 out:
621         return 0;
622 }
623
624 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
625 {
626         if (IS_AUTH(dst) && dst != src && !dst->deaf) {
627                 if (poslen > 0 && strcmp(src->context, dst->context) == 0)
628                         Client_send_udp(dst, data, len);
629                 else
630                         Client_send_udp(dst, data, len - poslen);
631         }
632 }
633
634 /* Handle decrypted voice message */
635 int Client_voiceMsg(client_t *client, uint8_t *data, int len)
636 {
637         uint8_t buffer[UDP_PACKET_SIZE];
638         pds_t *pdi = Pds_create(data + 1, len - 1);
639         pds_t *pds = Pds_create(buffer + 1, UDP_PACKET_SIZE - 1);
640         unsigned int type = data[0] & 0xe0;
641         unsigned int target = data[0] & 0x1f;
642         unsigned int poslen, counter;
643         int offset, packetsize;
644         voicetarget_t *vt;
645         
646         channel_t *ch = (channel_t *)client->channel;
647         struct dlist *itr;
648         
649         if (!client->authenticated || client->mute)
650                 goto out;
651         
652         packetsize = 20 + 8 + 4 + len;
653         if (client->availableBandwidth - packetsize < 0)
654                 goto out; /* Discard */
655         client->availableBandwidth -= packetsize;
656         
657         counter = Pds_get_numval(pdi); /* step past session id */
658         do {
659                 counter = Pds_next8(pdi);
660                 offset = Pds_skip(pdi, counter & 0x7f);
661         } while ((counter & 0x80) && offset > 0);
662
663         poslen = pdi->maxsize - pdi->offset; /* For stripping of positional info */
664         
665         Pds_add_numval(pds, client->sessionId);
666         Pds_append_data_nosize(pds, data + 1, len - 1);
667         
668         if (target == 0x1f) { /* Loopback */
669                 buffer[0] = (uint8_t) type;
670                 Client_send_udp(client, buffer, pds->offset + 1);
671         }
672         else if (target == 0) { /* regular channel speech */
673                 buffer[0] = (uint8_t) type;
674                 
675                 if (ch == NULL)
676                         goto out;
677                 
678                 list_iterate(itr, &ch->clients) {
679                         client_t *c;
680                         c = list_get_entry(itr, client_t, chan_node);
681                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
682                 }
683                 /* Channel links */
684                 if (!list_empty(&ch->channel_links)) {
685                         struct dlist *ch_itr;
686                         list_iterate(ch_itr, &ch->channel_links) {
687                                 channel_t *ch_link;
688                                 ch_link = list_get_entry(ch_itr, channel_t, link_node);
689                                 list_iterate(itr, &ch_link->clients) {
690                                         client_t *c;
691                                         c = list_get_entry(itr, client_t, chan_node);
692                                         Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
693                                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
694                                 }
695                         }
696                 }
697         } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
698                 int i;
699                 channel_t *ch;
700                 /* Channels */
701                 for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
702                         Log_debug("Whisper channel %d", vt->channels[i]);
703                         ch = Chan_fromId(vt->channels[i]);
704                         if (ch == NULL)
705                                 continue;
706                         list_iterate(itr, &ch->clients) {
707                                 client_t *c;
708                                 c = list_get_entry(itr, client_t, chan_node);
709                                 Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
710                         }
711                 }                       
712                 /* Sessions */
713                 for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
714                         client_t *c;
715                         Log_debug("Whisper session %d", vt->sessions[i]);
716                         while (Client_iterate(&c) != NULL) {
717                                 if (c->sessionId == vt->sessions[i]) {
718                                         Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
719                                         break;
720                                 }
721                         }
722                 }
723         }
724 out:
725         Pds_free(pds);
726         Pds_free(pdi);
727         
728         return 0;
729 }
730
731
732 static int Client_send_udp(client_t *client, uint8_t *data, int len)
733 {
734         uint8_t *buf, *mbuf;
735
736         if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
737 #if defined(__LP64__)
738                 buf = mbuf = malloc(len + 4 + 16);
739                 buf += 4;
740 #else
741                 mbuf = buf = malloc(len + 4);
742 #endif
743                 if (mbuf == NULL)
744                         Log_fatal("Out of memory");
745                 
746                 CryptState_encrypt(&client->cryptState, data, buf, len);
747                 
748                 sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
749                 
750                 free(mbuf);
751         } else {
752                 message_t *msg;
753                 buf = malloc(len);
754                 memcpy(buf, data, len);
755                 msg = Msg_create(UDPTunnel);
756                 
757                 msg->payload.UDPTunnel->packet.data = buf;
758                 msg->payload.UDPTunnel->packet.len = len;
759                 Client_send_message(client, msg);
760         }
761         return 0;
762 }