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