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