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