Change priority from extra to optional in debian/control.
[debian/iodine.git] / src / client.c
1 /*
2  * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
3  * 2006-2009 Bjorn Andersson <flex@kryo.se>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 #include <ctype.h>
19 #include <stdio.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <strings.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <sys/param.h>
27 #include <sys/time.h>
28 #include <fcntl.h>
29 #include <zlib.h>
30 #include <time.h>
31
32 #ifdef WINDOWS32
33 #include "windows.h"
34 #else
35 #ifdef ANDROID
36 #include "android_dns.h"
37 #endif
38 #include <arpa/nameser.h>
39 #ifdef DARWIN
40 #define BIND_8_COMPAT
41 #include <arpa/nameser_compat.h>
42 #endif
43 #include <grp.h>
44 #include <pwd.h>
45 #include <netdb.h>
46 #endif
47
48 #include "common.h"
49 #include "encoding.h"
50 #include "base32.h"
51 #include "base64.h"
52 #include "base64u.h"
53 #include "base128.h"
54 #include "dns.h"
55 #include "login.h"
56 #include "tun.h"
57 #include "version.h"
58 #include "client.h"
59
60 static void handshake_lazyoff(int dns_fd);
61
62 static int running;
63 static const char *password;
64
65 static struct sockaddr_storage nameserv;
66 static int nameserv_len;
67 static struct sockaddr_in raw_serv;
68 static const char *topdomain;
69
70 static uint16_t rand_seed;
71
72 /* Current up/downstream IP packet */
73 static struct packet outpkt;
74 static struct packet inpkt;
75 int outchunkresent = 0;
76
77 /* My userid at the server */
78 static char userid;
79 static char userid_char;                /* used when sending (lowercase) */
80 static char userid_char2;               /* also accepted when receiving (uppercase) */
81
82 /* DNS id for next packet */
83 static uint16_t chunkid;
84 static uint16_t chunkid_prev;
85 static uint16_t chunkid_prev2;
86
87 /* Base32 encoder used for non-data packets and replies */
88 static struct encoder *b32;
89 /* Base64 etc encoders for replies */
90 static struct encoder *b64;
91 static struct encoder *b64u;
92 static struct encoder *b128;
93
94 /* The encoder used for data packets
95  * Defaults to Base32, can be changed after handshake */
96 static struct encoder *dataenc;
97
98 /* The encoder to use for downstream data */
99 static char downenc = ' ';
100
101 /* set query type to send */
102 static unsigned short do_qtype = T_UNSET;
103
104 /* My connection mode */
105 static enum connection conn;
106
107 static int selecttimeout;               /* RFC says timeout minimum 5sec */
108 static int lazymode;
109 static long send_ping_soon;
110 static time_t lastdownstreamtime;
111 static long send_query_sendcnt = -1;
112 static long send_query_recvcnt = 0;
113 static int hostname_maxlen = 0xFF;
114
115 void
116 client_init()
117 {
118         running = 1;
119         b32 = get_base32_encoder();
120         b64 = get_base64_encoder();
121         b64u = get_base64u_encoder();
122         b128 = get_base128_encoder();
123         dataenc = get_base32_encoder();
124         rand_seed = ((unsigned int) rand()) & 0xFFFF;
125         send_ping_soon = 1;     /* send ping immediately after startup */
126         conn = CONN_DNS_NULL;
127
128         chunkid = ((unsigned int) rand()) & 0xFFFF;
129         chunkid_prev = 0;
130         chunkid_prev2 = 0;
131
132         outpkt.len = 0;
133         outpkt.seqno = 0;
134         outpkt.fragment = 0;
135         outchunkresent = 0;
136         inpkt.len = 0;
137         inpkt.seqno = 0;
138         inpkt.fragment = 0;
139 }
140
141 void
142 client_stop()
143 {
144         running = 0;
145 }
146
147 enum connection
148 client_get_conn()
149 {
150         return conn;
151 }
152
153 void
154 client_set_nameserver(struct sockaddr_storage *addr, int addrlen)
155 {
156         memcpy(&nameserv, addr, addrlen);
157         nameserv_len = addrlen;
158 }
159
160 void
161 client_set_topdomain(const char *cp)
162 {
163         topdomain = cp;
164 }
165
166 void
167 client_set_password(const char *cp)
168 {
169         password = cp;
170 }
171
172 int
173 client_set_qtype(char *qtype)
174 {
175         if (!strcasecmp(qtype, "NULL"))
176                 do_qtype = T_NULL;
177         else if (!strcasecmp(qtype, "PRIVATE"))
178                 do_qtype = T_PRIVATE;
179         else if (!strcasecmp(qtype, "CNAME"))
180                 do_qtype = T_CNAME;
181         else if (!strcasecmp(qtype, "A"))
182                 do_qtype = T_A;
183         else if (!strcasecmp(qtype, "MX"))
184                 do_qtype = T_MX;
185         else if (!strcasecmp(qtype, "SRV"))
186                 do_qtype = T_SRV;
187         else if (!strcasecmp(qtype, "TXT"))
188                 do_qtype = T_TXT;
189         return (do_qtype == T_UNSET);
190 }
191
192 char *
193 client_get_qtype()
194 {
195         char *c = "UNDEFINED";
196
197         if (do_qtype == T_NULL)         c = "NULL";
198         else if (do_qtype == T_PRIVATE) c = "PRIVATE";
199         else if (do_qtype == T_CNAME)   c = "CNAME";
200         else if (do_qtype == T_A)       c = "A";
201         else if (do_qtype == T_MX)      c = "MX";
202         else if (do_qtype == T_SRV)     c = "SRV";
203         else if (do_qtype == T_TXT)     c = "TXT";
204
205         return c;
206 }
207
208 void
209 client_set_downenc(char *encoding)
210 {
211         if (!strcasecmp(encoding, "base32"))
212                 downenc = 'T';
213         else if (!strcasecmp(encoding, "base64"))
214                 downenc = 'S';
215         else if (!strcasecmp(encoding, "base64u"))
216                 downenc = 'U';
217         else if (!strcasecmp(encoding, "base128"))
218                 downenc = 'V';
219         else if (!strcasecmp(encoding, "raw"))
220                 downenc = 'R';
221 }
222
223 void
224 client_set_selecttimeout(int select_timeout)
225 {
226         selecttimeout = select_timeout;
227 }
228
229 void
230 client_set_lazymode(int lazy_mode)
231 {
232         lazymode = lazy_mode;
233 }
234
235 void
236 client_set_hostname_maxlen(int i)
237 {
238         if (i <= 0xFF)
239                 hostname_maxlen = i;
240 }
241
242 const char *
243 client_get_raw_addr()
244 {
245         return inet_ntoa(raw_serv.sin_addr);
246 }
247
248 static void
249 send_query(int fd, char *hostname)
250 {
251         char packet[4096];
252         struct query q;
253         size_t len;
254
255         chunkid_prev2 = chunkid_prev;
256         chunkid_prev = chunkid;
257         chunkid += 7727;
258         if (chunkid == 0)
259                 /* 0 is used as "no-query" in iodined.c */
260                 chunkid = 7727;
261
262         q.id = chunkid;
263         q.type = do_qtype;
264
265         len = dns_encode(packet, sizeof(packet), &q, QR_QUERY, hostname, strlen(hostname));
266         if (len < 1) {
267                 warnx("dns_encode doesn't fit");
268                 return;
269         }
270
271 #if 0
272         fprintf(stderr, "  Sendquery: id %5d name[0] '%c'\n", q.id, hostname[0]);
273 #endif
274
275         sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, nameserv_len);
276
277         /* There are DNS relays that time out quickly but don't send anything
278            back on timeout.
279            And there are relays where, in lazy mode, our new query apparently
280            _replaces_ our previous query, and we get no answers at all in
281            lazy mode while legacy immediate-ping-pong works just fine.
282            Here we detect and fix these situations.
283            (Can't very well do this anywhere else; this is the only place
284            we'll reliably get to in such situations.)
285          */
286
287         if (send_query_sendcnt >= 0 && send_query_sendcnt < 100 && lazymode) {
288                 send_query_sendcnt++;
289
290                 if ((send_query_sendcnt > 6 && send_query_recvcnt <= 0) ||
291                     (send_query_sendcnt > 10 &&
292                      4 * send_query_recvcnt < send_query_sendcnt)) {
293                         if (selecttimeout > 1) {
294                                 warnx("Receiving too few answers. Setting interval to 1 (-I1)");
295                                 selecttimeout = 1;
296                                 /* restart counting */
297                                 send_query_sendcnt = 0;
298                                 send_query_recvcnt = 0;
299                         } else if (lazymode) {
300                                 warnx("Receiving too few answers. Will try to switch lazy mode off, but that may not always work any more. Start with -L0 next time on this network.");
301                                 lazymode = 0;
302                                 selecttimeout = 1;
303                                 handshake_lazyoff(fd);
304                         }
305                 }
306         }
307 }
308
309 static void
310 send_raw(int fd, char *buf, int buflen, int user, int cmd)
311 {
312         char packet[4096];
313         int len;
314
315         len = MIN(sizeof(packet) - RAW_HDR_LEN, buflen);
316
317         memcpy(packet, raw_header, RAW_HDR_LEN);
318         if (len) {
319                 memcpy(&packet[RAW_HDR_LEN], buf, len);
320         }
321
322         len += RAW_HDR_LEN;
323         packet[RAW_HDR_CMD] = cmd | (user & 0x0F);
324
325         sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv));
326 }
327
328 static void
329 send_raw_data(int dns_fd)
330 {
331         send_raw(dns_fd, outpkt.data, outpkt.len, userid, RAW_HDR_CMD_DATA);
332         outpkt.len = 0;
333 }
334
335
336 static void
337 send_packet(int fd, char cmd, const char *data, const size_t datalen)
338 {
339         char buf[4096];
340
341         buf[0] = cmd;
342
343         build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain,
344                        b32, hostname_maxlen);
345         send_query(fd, buf);
346 }
347
348 static inline int
349 is_sending()
350 {
351         return (outpkt.len != 0);
352 }
353
354 static void
355 send_chunk(int fd)
356 {
357         char buf[4096];
358         int avail;
359         int code;
360         char *p;
361         static int datacmc = 0;
362         char *datacmcchars = "abcdefghijklmnopqrstuvwxyz0123456789";
363
364         p = outpkt.data;
365         p += outpkt.offset;
366         avail = outpkt.len - outpkt.offset;
367
368         /* Note: must be same, or smaller than send_fragsize_probe() */
369         outpkt.sentlen = build_hostname(buf + 5, sizeof(buf) - 5, p, avail,
370                                         topdomain, dataenc, hostname_maxlen);
371
372         /* Build upstream data header (see doc/proto_xxxxxxxx.txt) */
373
374         buf[0] = userid_char;           /* First byte is hex userid */
375
376         code = ((outpkt.seqno & 7) << 2) | ((outpkt.fragment & 15) >> 2);
377         buf[1] = b32_5to8(code); /* Second byte is 3 bits seqno, 2 upper bits fragment count */
378
379         code = ((outpkt.fragment & 3) << 3) | (inpkt.seqno & 7);
380         buf[2] = b32_5to8(code); /* Third byte is 2 bits lower fragment count, 3 bits downstream packet seqno */
381
382         code = ((inpkt.fragment & 15) << 1) | (outpkt.sentlen == avail);
383         buf[3] = b32_5to8(code); /* Fourth byte is 4 bits downstream fragment count, 1 bit last frag flag */
384
385         buf[4] = datacmcchars[datacmc]; /* Fifth byte is data-CMC */
386         datacmc++;
387         if (datacmc >= 36)
388                 datacmc = 0;
389
390 #if 0
391         fprintf(stderr, "  Send: down %d/%d up %d/%d, %d bytes\n",
392                 inpkt.seqno, inpkt.fragment, outpkt.seqno, outpkt.fragment,
393                 outpkt.sentlen);
394 #endif
395
396         send_query(fd, buf);
397 }
398
399 static void
400 send_ping(int fd)
401 {
402         if (conn == CONN_DNS_NULL) {
403                 char data[4];
404
405                 data[0] = userid;
406                 data[1] = ((inpkt.seqno & 7) << 4) | (inpkt.fragment & 15);
407                 data[2] = (rand_seed >> 8) & 0xff;
408                 data[3] = (rand_seed >> 0) & 0xff;
409
410                 rand_seed++;
411
412 #if 0
413                 fprintf(stderr, "  Send: down %d/%d         (ping)\n",
414                         inpkt.seqno, inpkt.fragment);
415 #endif
416
417                 send_packet(fd, 'p', data, sizeof(data));
418         } else {
419                 send_raw(fd, NULL, 0, userid, RAW_HDR_CMD_PING);
420         }
421 }
422
423 static void
424 write_dns_error(struct query *q, int ignore_some_errors)
425 /* This is called from:
426    1. handshake_waitdns() when already checked that reply fits to our
427       latest query.
428    2. tunnel_dns() when already checked that reply is for our ping or data
429       packet, but not necessarily the most recent (SERVFAIL mostly comes
430       after long delay).
431    So ignorable errors are never printed.
432 */
433 {
434         if (!q) return;
435
436         switch (q->rcode) {
437         case NOERROR:   /* 0 */
438                 if (!ignore_some_errors)
439                         warnx("Got reply without error, but also without question and/or answer");
440                 break;
441         case FORMERR:   /* 1 */
442                 warnx("Got FORMERR as reply: server does not understand our request");
443                 break;
444         case SERVFAIL:  /* 2 */
445                 if (!ignore_some_errors)
446                         warnx("Got SERVFAIL as reply: server failed or recursion timeout");
447                 break;
448         case NXDOMAIN:  /* 3 */
449                 warnx("Got NXDOMAIN as reply: domain does not exist");
450                 break;
451         case NOTIMP:    /* 4 */
452                 warnx("Got NOTIMP as reply: server does not support our request");
453                 break;
454         case REFUSED:   /* 5 */
455                 warnx("Got REFUSED as reply");
456                 break;
457         default:
458                 warnx("Got RCODE %u as reply", q->rcode);
459                 break;
460         }
461 }
462
463 static int
464 dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
465 /* Decodes *buf to *outdata.
466  * *buf WILL be changed by undotify.
467  * Note: buflen must be _exactly_ strlen(buf) before undotifying.
468  * (undotify of reduced-len won't copy \0, base-X decode will decode too much.)
469  * Returns #bytes usefully filled in outdata.
470  */
471 {
472         size_t outdatalenu = outdatalen;
473
474         switch (buf[0]) {
475         case 'h': /* Hostname with base32 */
476         case 'H':
477                 /* Need 1 byte H, 3 bytes ".xy", >=1 byte data */
478                 if (buflen < 5)
479                         return 0;
480
481                 /* this also does undotify */
482                 return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
483                                    b32);
484
485         case 'i': /* Hostname++ with base64 */
486         case 'I':
487                 /* Need 1 byte I, 3 bytes ".xy", >=1 byte data */
488                 if (buflen < 5)
489                         return 0;
490
491                 /* this also does undotify */
492                 return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
493                                    b64);
494
495         case 'j': /* Hostname++ with base64u */
496         case 'J':
497                 /* Need 1 byte J, 3 bytes ".xy", >=1 byte data */
498                 if (buflen < 5)
499                         return 0;
500
501                 /* this also does undotify */
502                 return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
503                                    b64u);
504
505         case 'k': /* Hostname++ with base128 */
506         case 'K':
507                 /* Need 1 byte J, 3 bytes ".xy", >=1 byte data */
508                 if (buflen < 5)
509                         return 0;
510
511                 /* this also does undotify */
512                 return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
513                                    b128);
514
515         case 't': /* plain base32(Thirty-two) from TXT */
516         case 'T':
517                 if (buflen < 2)
518                         return 0;
519
520                 return b32->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
521
522         case 's': /* plain base64(Sixty-four) from TXT */
523         case 'S':
524                 if (buflen < 2)
525                         return 0;
526
527                 return b64->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
528
529         case 'u': /* plain base64u (Underscore) from TXT */
530         case 'U':
531                 if (buflen < 2)
532                         return 0;
533
534                 return b64u->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
535
536         case 'v': /* plain base128 from TXT */
537         case 'V':
538                 if (buflen < 2)
539                         return 0;
540
541                 return b128->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
542
543         case 'r': /* Raw binary from TXT */
544         case 'R':
545                 /* buflen>=1 already checked */
546                 buflen--;
547                 buflen = MIN(buflen, outdatalen);
548                 memcpy(outdata, buf + 1, buflen);
549                 return buflen;
550
551         default:
552                 warnx("Received unsupported encoding");
553                 return 0;
554         }
555
556         /* notreached */
557         return 0;
558 }
559
560 static int
561 read_dns_withq(int dns_fd, int tun_fd, char *buf, int buflen, struct query *q)
562 /* FIXME: tun_fd needed for raw handling */
563 /* Returns -1 on receive error or decode error, including DNS error replies.
564    Returns 0 on replies that could be correct but are useless, and are not
565    DNS error replies.
566    Returns >0 on correct replies; value is #valid bytes in *buf.
567 */
568 {
569         struct sockaddr_storage from;
570         char data[64*1024];
571         socklen_t addrlen;
572         int r;
573
574         addrlen = sizeof(from);
575         if ((r = recvfrom(dns_fd, data, sizeof(data), 0,
576                           (struct sockaddr*)&from, &addrlen)) < 0) {
577                 warn("recvfrom");
578                 return -1;
579         }
580
581         if (conn == CONN_DNS_NULL) {
582                 int rv;
583                 if (r <= 0)
584                         /* useless packet */
585                         return 0;
586
587                 rv = dns_decode(buf, buflen, q, QR_ANSWER, data, r);
588                 if (rv <= 0)
589                         return rv;
590
591                 if (q->type == T_CNAME || q->type == T_TXT)
592                 /* CNAME can also be returned from an A question */
593                 {
594                         /*
595                          * buf is a hostname or txt stream that we still need to
596                          * decode to binary
597                          *
598                          * also update rv with the number of valid bytes
599                          *
600                          * data is unused here, and will certainly hold the smaller binary
601                          */
602
603                         rv = dns_namedec(data, sizeof(data), buf, rv);
604
605                         rv = MIN(rv, buflen);
606                         if (rv > 0)
607                                 memcpy(buf, data, rv);
608
609                 } else if (q->type == T_MX || q->type == T_SRV) {
610                         /* buf is like "Hname.com\0Hanother.com\0\0" */
611                         int buftotal = rv;      /* idx of last \0 */
612                         int bufoffset = 0;
613                         int dataoffset = 0;
614                         int thispartlen, dataspace, datanew;
615
616                         while (1) {
617                                 thispartlen = strlen(buf);
618                                 thispartlen = MIN(thispartlen, buftotal-bufoffset);
619                                 dataspace = sizeof(data) - dataoffset;
620                                 if (thispartlen <= 0 || dataspace <= 0)
621                                         break;
622
623                                 datanew = dns_namedec(data + dataoffset, dataspace,
624                                                       buf + bufoffset, thispartlen);
625                                 if (datanew <= 0)
626                                         break;
627
628                                 bufoffset += thispartlen + 1;
629                                 dataoffset += datanew;
630                         }
631                         rv = dataoffset;
632                         rv = MIN(rv, buflen);
633                         if (rv > 0)
634                                 memcpy(buf, data, rv);
635                 }
636
637                 return rv;
638         } else { /* CONN_RAW_UDP */
639                 unsigned long datalen;
640                 char buf[64*1024];
641
642                 /* minimum length */
643                 if (r < RAW_HDR_LEN) return 0;
644                 /* should start with header */
645                 if (memcmp(data, raw_header, RAW_HDR_IDENT_LEN)) return 0;
646                 /* should be my user id */
647                 if (RAW_HDR_GET_USR(data) != userid) return 0;
648
649                 if (RAW_HDR_GET_CMD(data) == RAW_HDR_CMD_DATA ||
650                     RAW_HDR_GET_CMD(data) == RAW_HDR_CMD_PING)
651                         lastdownstreamtime = time(NULL);
652
653                 /* should be data packet */
654                 if (RAW_HDR_GET_CMD(data) != RAW_HDR_CMD_DATA) return 0;
655
656                 r -= RAW_HDR_LEN;
657                 datalen = sizeof(buf);
658                 if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) &data[RAW_HDR_LEN], r) == Z_OK) {
659                         write_tun(tun_fd, buf, datalen);
660                 }
661
662                 /* don't process any further */
663                 return 0;
664         }
665 }
666
667 static int
668 handshake_waitdns(int dns_fd, char *buf, int buflen, char c1, char c2, int timeout)
669 /* Wait for DNS reply fitting to our latest query and returns it.
670    Returns length of reply = #bytes used in buf.
671    Returns 0 if fitting reply happens to be useless.
672    Returns -2 on (at least) DNS error that fits to our latest query,
673    error message already printed.
674    Returns -3 on timeout (given in seconds).
675    Returns -1 on other errors.
676
677    Timeout is restarted when "wrong" (previous/delayed) replies are received,
678    so effective timeout may be longer than specified.
679 */
680 {
681         struct query q;
682         int r, rv;
683         fd_set fds;
684         struct timeval tv;
685
686         while (1) {
687                 tv.tv_sec = timeout;
688                 tv.tv_usec = 0;
689                 FD_ZERO(&fds);
690                 FD_SET(dns_fd, &fds);
691                 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
692
693                 if (r < 0)
694                         return -1;      /* select error */
695                 if (r == 0)
696                         return -3;      /* select timeout */
697
698                 q.id = 0;
699                 q.name[0] = '\0';
700                 rv = read_dns_withq(dns_fd, 0, buf, buflen, &q);
701
702                 if (q.id != chunkid || (q.name[0] != c1 && q.name[0] != c2)) {
703 #if 0
704                         fprintf(stderr, "Ignoring unfitting reply id %d starting with '%c'\n", q.id, q.name[0]);
705 #endif
706                         continue;
707                 }
708
709                 /* if still here: reply matches our latest query */
710
711                 /* Non-recursive DNS servers (such as [a-m].root-servers.net)
712                    return no answer, but only additional and authority records.
713                    Can't explicitly test for that here, just assume that
714                    NOERROR is such situation. Only trigger on the very first
715                    requests (Y or V, depending if -T given).
716                  */
717                 if (rv < 0 && q.rcode == NOERROR &&
718                     (q.name[0] == 'Y' || q.name[0] == 'y' ||
719                      q.name[0] == 'V' || q.name[0] == 'v')) {
720                         fprintf(stderr, "Got empty reply. This nameserver may not be resolving recursively, use another.\n");
721                         fprintf(stderr, "Try \"iodine [options] ns.%s %s\" first, it might just work.\n",
722                                 topdomain, topdomain);
723                         return -2;
724                 }
725
726                 /* If we get an immediate SERVFAIL on the handshake query
727                    we're waiting for, wait a while before sending the next.
728                    SERVFAIL reliably happens during fragsize autoprobe, but
729                    mostly long after we've moved along to some other queries.
730                    However, some DNS relays, once they throw a SERVFAIL, will
731                    for several seconds apply it immediately to _any_ new query
732                    for the same topdomain. When this happens, waiting a while
733                    is the only option that works.
734                  */
735                 if (rv < 0 && q.rcode == SERVFAIL)
736                         sleep(1);
737
738                 if (rv < 0) {
739                         write_dns_error(&q, 1);
740                         return -2;
741                 }
742                 /* rv either 0 or >0, return it as is. */
743                 return rv;
744         }
745
746         /* not reached */
747         return -1;
748 }
749
750 static int
751 tunnel_tun(int tun_fd, int dns_fd)
752 {
753         unsigned long outlen;
754         unsigned long inlen;
755         char out[64*1024];
756         char in[64*1024];
757         ssize_t read;
758
759         if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0)
760                 return -1;
761
762         /* We may be here only to empty the tun device; then return -1
763            to force continue in select loop. */
764         if (is_sending())
765                 return -1;
766
767         outlen = sizeof(out);
768         inlen = read;
769         compress2((uint8_t*)out, &outlen, (uint8_t*)in, inlen, 9);
770
771         memcpy(outpkt.data, out, MIN(outlen, sizeof(outpkt.data)));
772         outpkt.sentlen = 0;
773         outpkt.offset = 0;
774         outpkt.seqno = (outpkt.seqno + 1) & 7;
775         outpkt.len = outlen;
776         outpkt.fragment = 0;
777         outchunkresent = 0;
778
779         if (conn == CONN_DNS_NULL) {
780                 send_chunk(dns_fd);
781
782                 send_ping_soon = 0;
783         } else {
784                 send_raw_data(dns_fd);
785         }
786
787         return read;
788 }
789
790 static int
791 tunnel_dns(int tun_fd, int dns_fd)
792 {
793         static long packrecv = 0;
794         static long packrecv_oos = 0;
795         static long packrecv_servfail = 0;
796         int up_ack_seqno;
797         int up_ack_fragment;
798         int new_down_seqno;
799         int new_down_fragment;
800         struct query q;
801         unsigned long datalen;
802         char buf[64*1024];
803         int read;
804         int send_something_now = 0;
805
806         memset(q.name, 0, sizeof(q.name));
807         read = read_dns_withq(dns_fd, tun_fd, buf, sizeof(buf), &q);
808
809         if (conn != CONN_DNS_NULL)
810                 return 1;  /* everything already done */
811
812 #if 0
813         fprintf(stderr, "                               Recv: id %5d name[0]='%c'\n",
814                 q.id, q.name[0]);
815 #endif
816
817         /* Don't process anything that isn't data for us; usually error
818            replies from fragsize probes etc. However a sequence of those,
819            mostly 1 sec apart, will continuously break the >=2-second select
820            timeout, which means we won't send a proper ping for a while.
821            So make select a bit faster, <1sec. */
822         if (q.name[0] != 'P' && q.name[0] != 'p' &&
823             q.name[0] != userid_char && q.name[0] != userid_char2) {
824                 send_ping_soon = 700;
825                 return -1;      /* nothing done */
826         }
827
828         if (read < 2) {
829                 /* Maybe SERVFAIL etc. Send ping to get things back in order,
830                    but wait a bit to prevent fast ping-pong loops. */
831
832                 if (read < 0)
833                         write_dns_error(&q, 0);
834
835                 if (read < 0 && q.rcode == SERVFAIL && lazymode &&
836                     selecttimeout > 1) {
837                         if (packrecv < 500 && packrecv_servfail < 4) {
838                                 packrecv_servfail++;
839                                 warnx("Hmm, that's %ld. Your data should still go through...", packrecv_servfail);
840                         } else if (packrecv < 500 && packrecv_servfail == 4) {
841                                 packrecv_servfail++;
842                                 warnx("I think %ld is too many. Setting interval to 1 to hopefully reduce SERVFAILs. But just ignore them if data still comes through. (Use -I1 next time on this network.)", packrecv_servfail);
843                                 selecttimeout = 1;
844                                 send_query_sendcnt = 0;
845                                 send_query_recvcnt = 0;
846                         } else if (packrecv >= 500 && packrecv_servfail > 0) {
847                                 warnx("(Sorry, stopped counting; try -I1 if you experience hiccups.)");
848                                 packrecv_servfail = 0;
849                         }
850                 }
851
852                 /* read==1 happens with "QMEM" illegal replies, caused by
853                    heavy reordering, or after short disconnections when
854                    data-CMC has looped around into the "duplicate" values.
855                    All these cases are helped by faster pinging. */
856 #if 0
857                 if (read == 1)
858                         fprintf(stderr, "   q=%c id %5d 1-byte illegal \"QMEM\" reply\n", q.name[0], q.id);
859 #endif
860
861                 send_ping_soon = 900;
862                 return -1;      /* nothing done */
863         }
864
865         if (read == 5 && !strncmp("BADIP", buf, 5)) {
866                 warnx("BADIP: Server rejected sender IP address (maybe iodined -c will help), or server kicked us due to timeout. Will exit if no downstream data is received in 60 seconds.");
867                 return -1;      /* nothing done */
868         }
869
870         if (send_ping_soon) {
871                 send_something_now = 1;
872                 send_ping_soon = 0;
873         }
874
875         /* Decode the data header, update seqno and frag;
876            already checked read>=2
877            Note that buf[] gets overwritten when down-pkt complete */
878         new_down_seqno = (buf[1] >> 5) & 7;
879         new_down_fragment = (buf[1] >> 1) & 15;
880         up_ack_seqno = (buf[0] >> 4) & 7;
881         up_ack_fragment = buf[0] & 15;
882
883 #if 0
884         fprintf(stderr, "                               Recv: id %5d down %d/%d up %d/%d, %d bytes\n",
885                 q.id, new_down_seqno, new_down_fragment, up_ack_seqno,
886                 up_ack_fragment, read);
887 #endif
888
889         /* Downstream data traffic */
890
891         if (read > 2 && new_down_seqno != inpkt.seqno &&
892             recent_seqno(inpkt.seqno, new_down_seqno)) {
893                 /* This is the previous seqno, or a bit earlier.
894                    Probably out-of-sequence dupe due to unreliable
895                    intermediary DNS. Don't get distracted, but send
896                    ping quickly to get things back in order.
897                    Ping will send our current seqno idea.
898                    If it's really a new packet that skipped multiple seqnos
899                    (why??), server will re-send and drop a few times and
900                    eventually everything will work again. */
901                 read = 2;
902                 send_ping_soon = 500;
903                 /* Still process upstream ack, if any */
904         }
905
906         if (!(packrecv & 0x1000000))
907                 packrecv++;
908         send_query_recvcnt++;  /* overflow doesn't matter */
909
910         /* Don't process any non-recent stuff any further.
911            No need to remember more than 3 ids: in practice any older replies
912            arrive after new/current replies, and whatever data the old replies
913            have, it has become useless in the mean time.
914            Actually, ever since iodined is replying to both the original query
915            and the last dupe, this hardly triggers any more.
916          */
917         if (q.id != chunkid && q.id != chunkid_prev && q.id != chunkid_prev2) {
918                 packrecv_oos++;
919 #if 0
920                 fprintf(stderr, "   q=%c Packs received = %8ld  Out-of-sequence = %8ld\n", q.name[0], packrecv, packrecv_oos);
921 #endif
922                 if (lazymode && packrecv < 1000 && packrecv_oos == 5) {
923                         if (selecttimeout > 1)
924                                 warnx("Hmm, getting some out-of-sequence DNS replies. Setting interval to 1 (use -I1 next time on this network). If data traffic still has large hiccups, try if -L0 works better.");
925                         else
926                                 warnx("Hmm, getting some out-of-sequence DNS replies. If data traffic often has large hiccups, try running with -L0 .");
927                         selecttimeout = 1;
928                         send_query_sendcnt = 0;
929                         send_query_recvcnt = 0;
930                 }
931
932                 if (send_something_now) {
933                         send_ping(dns_fd);
934                         send_ping_soon = 0;
935                 }
936                 return -1;      /* nothing done */
937         }
938 #if 0
939         fprintf(stderr, "   q=%c Packs received = %8ld  Out-of-sequence = %8ld\n", q.name[0], packrecv, packrecv_oos);
940 #endif
941
942         /* Okay, we have a recent downstream packet */
943         lastdownstreamtime = time(NULL);
944
945         /* In lazy mode, we shouldn't get much replies to our most-recent
946            query, only during heavy data transfer. Since this means the server
947            doesn't have any packets left, send one relatively fast (but not
948            too fast, to avoid runaway ping-pong loops..) */
949         if (q.id == chunkid && lazymode) {
950                 if (!send_ping_soon || send_ping_soon > 900)
951                         send_ping_soon = 900;
952         }
953
954         if (read == 2 && new_down_seqno != inpkt.seqno &&
955             !recent_seqno(inpkt.seqno, new_down_seqno)) {
956                 /* This is a seqno that we didn't see yet, but it has
957                    no data any more. Possible since iodined will send
958                    fitting packs just once and not wait for ack.
959                    Real data got lost, or will arrive shortly.
960                    Update our idea of the seqno, and drop any waiting
961                    old pack. Send ping to get things back on track. */
962                 inpkt.seqno = new_down_seqno;
963                 inpkt.fragment = new_down_fragment;
964                 inpkt.len = 0;
965                 send_ping_soon = 500;
966         }
967
968         while (read > 2) {
969         /* "if" with easy exit */
970
971                 if (new_down_seqno != inpkt.seqno) {
972                         /* New packet (and not dupe of recent; checked above) */
973                         /* Forget any old packet, even if incomplete */
974                         inpkt.seqno = new_down_seqno;
975                         inpkt.fragment = new_down_fragment;   /* hopefully 0 */
976                         inpkt.len = 0;
977                 } else if (inpkt.fragment == 0 && new_down_fragment == 0 &&
978                            inpkt.len == 0) {
979                         /* Weird situation: we probably got a no-data reply
980                            for this seqno (see above), and the actual data
981                            is following now. */
982                         /* okay, nothing to do here, just so that next else-if
983                            doesn't trigger */
984                 } else if (new_down_fragment <= inpkt.fragment) {
985                         /* Same packet but duplicate fragment, ignore.
986                            If the server didn't get our ack for it, the next
987                            ping or chunk will do that. */
988                         send_ping_soon = 500;
989                         break;
990                 } else if (new_down_fragment > inpkt.fragment + 1) {
991                         /* Quite impossible. We missed a fragment, but the
992                            server got our ack for it and is sending the next
993                            fragment already. Don't handle it but let server
994                            re-send and drop. */
995                         send_ping_soon = 500;
996                         break;
997                 }
998                 inpkt.fragment = new_down_fragment;
999
1000                 datalen = MIN(read - 2, sizeof(inpkt.data) - inpkt.len);
1001
1002                 /* we are here only when read > 2, so datalen "always" >=1 */
1003
1004                 /* Skip 2 byte data header and append to packet */
1005                 memcpy(&inpkt.data[inpkt.len], &buf[2], datalen);
1006                 inpkt.len += datalen;
1007
1008                 if (buf[1] & 1) { /* If last fragment flag is set */
1009                         /* Uncompress packet and send to tun */
1010                         /* RE-USES buf[] */
1011                         datalen = sizeof(buf);
1012                         if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) inpkt.data, inpkt.len) == Z_OK) {
1013                                 write_tun(tun_fd, buf, datalen);
1014                         }
1015                         inpkt.len = 0;
1016                         /* Keep .seqno and .fragment as is, so that we won't
1017                            reassemble from duplicate fragments */
1018                 }
1019
1020                 /* Send anything to ack the received seqno/frag, and get more */
1021                 if (inpkt.len == 0) {
1022                         /* was last frag; wait just a trifle because our
1023                            tun will probably return TCP-ack immediately.
1024                            5msec = 200 DNSreq/sec */
1025                         send_ping_soon = 5;
1026                 } else {
1027                         /* server certainly has more data */
1028                         send_something_now = 1;
1029                 }
1030
1031                 break;
1032         }
1033
1034         /* NOTE: buf[] was overwritten when down-packet complete */
1035
1036
1037         /* Upstream data traffic */
1038
1039         if (is_sending()) {
1040                 /* already checked read>=2 */
1041 #if 0
1042                 fprintf(stderr, "Got ack for %d,%d - expecting %d,%d - id=%d cur=%d prev=%d prev2=%d\n",
1043                         up_ack_seqno, up_ack_fragment, outpkt.seqno, outpkt.fragment,
1044                         q.id, chunkid, chunkid_prev, chunkid_prev2);
1045 #endif
1046
1047                 if (up_ack_seqno == outpkt.seqno &&
1048                     up_ack_fragment == outpkt.fragment) {
1049                         /* Okay, previously sent fragment has arrived */
1050
1051                         outpkt.offset += outpkt.sentlen;
1052                         if (outpkt.offset >= outpkt.len) {
1053                                 /* Packet completed */
1054                                 outpkt.offset = 0;
1055                                 outpkt.len = 0;
1056                                 outpkt.sentlen = 0;
1057                                 outchunkresent = 0;
1058
1059                                 /* Normally, server still has a query in queue,
1060                                    but sometimes not. So send a ping.
1061                                    (Comment this out and you'll see occasional
1062                                    hiccups.)
1063                                    But since the server often still has a
1064                                    query and we can expect a TCP-ack returned
1065                                    from our tun device quickly in many cases,
1066                                    don't be too fast.
1067                                    20msec still is 50 DNSreq/second... */
1068                                 if (!send_ping_soon || send_ping_soon > 20)
1069                                         send_ping_soon = 20;
1070                         } else {
1071                                 /* More to send */
1072                                 outpkt.fragment++;
1073                                 outchunkresent = 0;
1074                                 send_chunk(dns_fd);
1075                                 send_ping_soon = 0;
1076                                 send_something_now = 0;
1077                         }
1078                 }
1079                 /* else: Some wrong fragment has arrived, or old fragment is
1080                    acked again, mostly by ping responses.
1081                    Don't resend chunk, usually not needed; select loop will
1082                    re-send on timeout (1sec if is_sending()). */
1083         }
1084
1085
1086         /* Send ping if we didn't send anything yet */
1087         if (send_something_now) {
1088                 send_ping(dns_fd);
1089                 send_ping_soon = 0;
1090         }
1091
1092         return read;
1093 }
1094
1095 int
1096 client_tunnel(int tun_fd, int dns_fd)
1097 {
1098         struct timeval tv;
1099         fd_set fds;
1100         int rv;
1101         int i;
1102
1103         rv = 0;
1104         lastdownstreamtime = time(NULL);
1105         send_query_sendcnt = 0;  /* start counting now */
1106
1107         while (running) {
1108                 tv.tv_sec = selecttimeout;
1109                 tv.tv_usec = 0;
1110
1111                 if (is_sending()) {
1112                         /* fast timeout for retransmits */
1113                         tv.tv_sec = 1;
1114                         tv.tv_usec = 0;
1115                 }
1116
1117                 if (send_ping_soon) {
1118                         tv.tv_sec = 0;
1119                         tv.tv_usec = send_ping_soon * 1000;
1120                 }
1121
1122                 FD_ZERO(&fds);
1123                 if (!is_sending() || outchunkresent >= 2) {
1124                         /* If re-sending upstream data, chances are that
1125                            we're several seconds behind already and TCP
1126                            will start filling tun buffer with (useless)
1127                            retransmits.
1128                            Get up-to-date fast by simply dropping stuff,
1129                            that's what TCP is designed to handle. */
1130                         FD_SET(tun_fd, &fds);
1131                 }
1132                 FD_SET(dns_fd, &fds);
1133
1134                 i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv);
1135
1136                 if (lastdownstreamtime + 60 < time(NULL)) {
1137                         warnx("No downstream data received in 60 seconds, shutting down.");
1138                         running = 0;
1139                 }
1140
1141                 if (running == 0)
1142                         break;
1143
1144                 if (i < 0)
1145                         err(1, "select");
1146
1147                 if (i == 0) {
1148                         /* timeout */
1149                         if (is_sending()) {
1150                                 /* Re-send current fragment; either frag
1151                                    or ack probably dropped somewhere.
1152                                    But problem: no cache-miss-counter,
1153                                    so hostname will be identical.
1154                                    Just drop whole packet after 3 retries,
1155                                    and TCP retransmit will solve it.
1156                                    NOTE: tun dropping above should be
1157                                    >=(value_here - 1) */
1158                                 if (outchunkresent < 3) {
1159                                         outchunkresent++;
1160                                         send_chunk(dns_fd);
1161                                 } else {
1162                                         outpkt.offset = 0;
1163                                         outpkt.len = 0;
1164                                         outpkt.sentlen = 0;
1165                                         outchunkresent = 0;
1166
1167                                         send_ping(dns_fd);
1168                                 }
1169                         } else {
1170                                 send_ping(dns_fd);
1171                         }
1172                         send_ping_soon = 0;
1173
1174                 } else {
1175
1176                         if (FD_ISSET(tun_fd, &fds)) {
1177                                 if (tunnel_tun(tun_fd, dns_fd) <= 0)
1178                                         continue;
1179                                 /* Returns -1 on error OR when quickly
1180                                    dropping data in case of DNS congestion;
1181                                    we need to _not_ do tunnel_dns() then.
1182                                    If chunk sent, sets send_ping_soon=0. */
1183                         }
1184                         if (FD_ISSET(dns_fd, &fds)) {
1185                                 if (tunnel_dns(tun_fd, dns_fd) <= 0)
1186                                         continue;
1187                         }
1188                 }
1189         }
1190
1191         return rv;
1192 }
1193
1194 static void
1195 send_login(int fd, char *login, int len)
1196 {
1197         char data[19];
1198
1199         memset(data, 0, sizeof(data));
1200         data[0] = userid;
1201         memcpy(&data[1], login, MIN(len, 16));
1202
1203         data[17] = (rand_seed >> 8) & 0xff;
1204         data[18] = (rand_seed >> 0) & 0xff;
1205
1206         rand_seed++;
1207
1208         send_packet(fd, 'l', data, sizeof(data));
1209 }
1210
1211 static void
1212 send_fragsize_probe(int fd, int fragsize)
1213 {
1214         char probedata[256];
1215         char buf[4096];
1216
1217         /*
1218          * build a large query domain which is random and maximum size,
1219          * will also take up maximal space in the return packet
1220          */
1221         memset(probedata, MAX(1, rand_seed & 0xff), sizeof(probedata));
1222         probedata[1] = MAX(1, (rand_seed >> 8) & 0xff);
1223         rand_seed++;
1224
1225         /* Note: must either be same, or larger, than send_chunk() */
1226         build_hostname(buf + 5, sizeof(buf) - 5, probedata, sizeof(probedata),
1227                        topdomain, dataenc, hostname_maxlen);
1228
1229         fragsize &= 2047;
1230
1231         buf[0] = 'r'; /* Probe downstream fragsize packet */
1232         buf[1] = b32_5to8((userid << 1) | ((fragsize >> 10) & 1));
1233         buf[2] = b32_5to8((fragsize >> 5) & 31);
1234         buf[3] = b32_5to8(fragsize & 31);
1235         buf[4] = 'd'; /* dummy to match send_chunk() */
1236
1237         send_query(fd, buf);
1238 }
1239
1240 static void
1241 send_set_downstream_fragsize(int fd, int fragsize)
1242 {
1243         char data[5];
1244
1245         data[0] = userid;
1246         data[1] = (fragsize & 0xff00) >> 8;
1247         data[2] = (fragsize & 0x00ff);
1248         data[3] = (rand_seed >> 8) & 0xff;
1249         data[4] = (rand_seed >> 0) & 0xff;
1250
1251         rand_seed++;
1252
1253         send_packet(fd, 'n', data, sizeof(data));
1254 }
1255
1256 static void
1257 send_version(int fd, uint32_t version)
1258 {
1259         char data[6];
1260
1261         data[0] = (version >> 24) & 0xff;
1262         data[1] = (version >> 16) & 0xff;
1263         data[2] = (version >> 8) & 0xff;
1264         data[3] = (version >> 0) & 0xff;
1265
1266         data[4] = (rand_seed >> 8) & 0xff;
1267         data[5] = (rand_seed >> 0) & 0xff;
1268
1269         rand_seed++;
1270
1271         send_packet(fd, 'v', data, sizeof(data));
1272 }
1273
1274 static void
1275 send_ip_request(int fd, int userid)
1276 {
1277         char buf[512] = "i____.";
1278         buf[1] = b32_5to8(userid);
1279
1280         buf[2] = b32_5to8((rand_seed >> 10) & 0x1f);
1281         buf[3] = b32_5to8((rand_seed >> 5) & 0x1f);
1282         buf[4] = b32_5to8((rand_seed ) & 0x1f);
1283         rand_seed++;
1284
1285         strncat(buf, topdomain, 512 - strlen(buf));
1286         send_query(fd, buf);
1287 }
1288
1289 static void
1290 send_raw_udp_login(int dns_fd, int userid, int seed)
1291 {
1292         char buf[16];
1293         login_calculate(buf, 16, password, seed + 1);
1294
1295         send_raw(dns_fd, buf, sizeof(buf), userid, RAW_HDR_CMD_LOGIN);
1296 }
1297
1298 static void
1299 send_upenctest(int fd, char *s)
1300 /* NOTE: String may be at most 63-4=59 chars to fit in 1 dns chunk. */
1301 {
1302         char buf[512] = "z___";
1303
1304         buf[1] = b32_5to8((rand_seed >> 10) & 0x1f);
1305         buf[2] = b32_5to8((rand_seed >> 5) & 0x1f);
1306         buf[3] = b32_5to8((rand_seed ) & 0x1f);
1307         rand_seed++;
1308
1309         strncat(buf, s, 512);
1310         strncat(buf, ".", 512);
1311         strncat(buf, topdomain, 512 - strlen(buf));
1312         send_query(fd, buf);
1313 }
1314
1315 static void
1316 send_downenctest(int fd, char downenc, int variant, char *s, int slen)
1317 /* Note: content/handling of s is not defined yet. */
1318 {
1319         char buf[512] = "y_____.";
1320
1321         buf[1] = tolower(downenc);
1322         buf[2] = b32_5to8(variant);
1323
1324         buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
1325         buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
1326         buf[5] = b32_5to8((rand_seed ) & 0x1f);
1327         rand_seed++;
1328
1329         strncat(buf, topdomain, 512 - strlen(buf));
1330         send_query(fd, buf);
1331 }
1332
1333 static void
1334 send_codec_switch(int fd, int userid, int bits)
1335 {
1336         char buf[512] = "s_____.";
1337         buf[1] = b32_5to8(userid);
1338         buf[2] = b32_5to8(bits);
1339
1340         buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
1341         buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
1342         buf[5] = b32_5to8((rand_seed ) & 0x1f);
1343         rand_seed++;
1344
1345         strncat(buf, topdomain, 512 - strlen(buf));
1346         send_query(fd, buf);
1347 }
1348
1349
1350 static void
1351 send_downenc_switch(int fd, int userid)
1352 {
1353         char buf[512] = "o_____.";
1354         buf[1] = b32_5to8(userid);
1355         buf[2] = tolower(downenc);
1356
1357         buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
1358         buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
1359         buf[5] = b32_5to8((rand_seed ) & 0x1f);
1360         rand_seed++;
1361
1362         strncat(buf, topdomain, 512 - strlen(buf));
1363         send_query(fd, buf);
1364 }
1365
1366 static void
1367 send_lazy_switch(int fd, int userid)
1368 {
1369         char buf[512] = "o_____.";
1370         buf[1] = b32_5to8(userid);
1371
1372         if (lazymode)
1373                 buf[2] = 'l';
1374         else
1375                 buf[2] = 'i';
1376
1377         buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
1378         buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
1379         buf[5] = b32_5to8((rand_seed ) & 0x1f);
1380         rand_seed++;
1381
1382         strncat(buf, topdomain, 512 - strlen(buf));
1383         send_query(fd, buf);
1384 }
1385
1386 static int
1387 handshake_version(int dns_fd, int *seed)
1388 {
1389         char hex[] = "0123456789abcdef";
1390         char hex2[] = "0123456789ABCDEF";
1391         char in[4096];
1392         uint32_t payload;
1393         int i;
1394         int read;
1395
1396         for (i = 0; running && i < 5; i++) {
1397
1398                 send_version(dns_fd, VERSION);
1399
1400                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'v', 'V', i+1);
1401
1402                 if (read >= 9) {
1403                         payload =  (((in[4] & 0xff) << 24) |
1404                                         ((in[5] & 0xff) << 16) |
1405                                         ((in[6] & 0xff) << 8) |
1406                                         ((in[7] & 0xff)));
1407
1408                         if (strncmp("VACK", in, 4) == 0) {
1409                                 *seed = payload;
1410                                 userid = in[8];
1411                                 userid_char = hex[userid & 15];
1412                                 userid_char2 = hex2[userid & 15];
1413
1414                                 fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid);
1415                                 return 0;
1416                         } else if (strncmp("VNAK", in, 4) == 0) {
1417                                 warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
1418                                                 VERSION, payload);
1419                                 return 1;
1420                         } else if (strncmp("VFUL", in, 4) == 0) {
1421                                 warnx("Server full, all %d slots are taken. Try again later", payload);
1422                                 return 1;
1423                         }
1424                 } else if (read > 0)
1425                         warnx("did not receive proper login challenge");
1426
1427                 fprintf(stderr, "Retrying version check...\n");
1428         }
1429         warnx("couldn't connect to server (maybe other -T options will work)");
1430         return 1;
1431 }
1432
1433 static int
1434 handshake_login(int dns_fd, int seed)
1435 {
1436         char in[4096];
1437         char login[16];
1438         char server[65];
1439         char client[65];
1440         int mtu;
1441         int i;
1442         int read;
1443
1444         login_calculate(login, 16, password, seed);
1445
1446         for (i=0; running && i<5 ;i++) {
1447
1448                 send_login(dns_fd, login, 16);
1449
1450                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'l', 'L', i+1);
1451
1452                 if (read > 0) {
1453                         int netmask;
1454                         if (strncmp("LNAK", in, 4) == 0) {
1455                                 fprintf(stderr, "Bad password\n");
1456                                 return 1;
1457                         } else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
1458                                 server, client, &mtu, &netmask) == 4) {
1459
1460                                 server[64] = 0;
1461                                 client[64] = 0;
1462                                 if (tun_setip(client, server, netmask) == 0 &&
1463                                         tun_setmtu(mtu) == 0) {
1464
1465                                         fprintf(stderr, "Server tunnel IP is %s\n", server);
1466                                         return 0;
1467                                 } else {
1468                                         errx(4, "Failed to set IP and MTU");
1469                                 }
1470                         } else {
1471                                 fprintf(stderr, "Received bad handshake\n");
1472                         }
1473                 }
1474
1475                 fprintf(stderr, "Retrying login...\n");
1476         }
1477         warnx("couldn't login to server");
1478         return 1;
1479 }
1480
1481 static int
1482 handshake_raw_udp(int dns_fd, int seed)
1483 {
1484         struct timeval tv;
1485         char in[4096];
1486         fd_set fds;
1487         int i;
1488         int r;
1489         int len;
1490         unsigned remoteaddr = 0;
1491         struct in_addr server;
1492
1493         fprintf(stderr, "Testing raw UDP data to the server (skip with -r)");
1494         for (i=0; running && i<3 ;i++) {
1495
1496                 send_ip_request(dns_fd, userid);
1497
1498                 len = handshake_waitdns(dns_fd, in, sizeof(in), 'i', 'I', i+1);
1499
1500                 if (len == 5 && in[0] == 'I') {
1501                         /* Received IP address */
1502                         remoteaddr = (in[1] & 0xff);
1503                         remoteaddr <<= 8;
1504                         remoteaddr |= (in[2] & 0xff);
1505                         remoteaddr <<= 8;
1506                         remoteaddr |= (in[3] & 0xff);
1507                         remoteaddr <<= 8;
1508                         remoteaddr |= (in[4] & 0xff);
1509                         server.s_addr = ntohl(remoteaddr);
1510                         break;
1511                 }
1512
1513                 fprintf(stderr, ".");
1514                 fflush(stderr);
1515         }
1516         fprintf(stderr, "\n");
1517         if (!running)
1518                 return 0;
1519
1520         if (!remoteaddr) {
1521                 fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n");
1522                 return 0;
1523         }
1524         fprintf(stderr, "Server is at %s, trying raw login: ", inet_ntoa(server));
1525         fflush(stderr);
1526
1527         /* Store address to iodined server */
1528         memset(&raw_serv, 0, sizeof(raw_serv));
1529         raw_serv.sin_family = AF_INET;
1530         raw_serv.sin_port = htons(53);
1531         raw_serv.sin_addr = server;
1532
1533         /* do login against port 53 on remote server
1534          * based on the old seed. If reply received,
1535          * switch to raw udp mode */
1536         for (i=0; running && i<4 ;i++) {
1537                 tv.tv_sec = i + 1;
1538                 tv.tv_usec = 0;
1539
1540                 send_raw_udp_login(dns_fd, userid, seed);
1541
1542                 FD_ZERO(&fds);
1543                 FD_SET(dns_fd, &fds);
1544
1545                 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
1546
1547                 if(r > 0) {
1548                         /* recv() needed for windows, dont change to read() */
1549                         len = recv(dns_fd, in, sizeof(in), 0);
1550                         if (len >= (16 + RAW_HDR_LEN)) {
1551                                 char hash[16];
1552                                 login_calculate(hash, 16, password, seed - 1);
1553                                 if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0
1554                                         && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN
1555                                         && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0) {
1556
1557                                         fprintf(stderr, "OK\n");
1558                                         return 1;
1559                                 }
1560                         }
1561                 }
1562                 fprintf(stderr, ".");
1563                 fflush(stderr);
1564         }
1565
1566         fprintf(stderr, "failed\n");
1567         return 0;
1568 }
1569
1570 static int
1571 handshake_upenctest(int dns_fd, char *s)
1572 /* NOTE: *s may be max 59 chars; must start with "aA" for case-swap check
1573    Returns:
1574    -1: case swap, no need for any further test: error printed; or Ctrl-C
1575    0: not identical or error or timeout
1576    1: identical string returned
1577 */
1578 {
1579         char in[4096];
1580         unsigned char *uin = (unsigned char *) in;
1581         unsigned char *us = (unsigned char *) s;
1582         int i;
1583         int read;
1584         int slen;
1585
1586         slen = strlen(s);
1587         for (i=0; running && i<3 ;i++) {
1588
1589                 send_upenctest(dns_fd, s);
1590
1591                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'z', 'Z', i+1);
1592
1593                 if (read == -2)
1594                         return 0;       /* hard error */
1595
1596                 if (read > 0 && read < slen + 4)
1597                         return 0;       /* reply too short (chars dropped) */
1598
1599                 if (read > 0) {
1600                         int k;
1601 #if 0
1602                         /* in[56] = '@'; */
1603                         /* in[56] = '_'; */
1604                         /* if (in[29] == '\344') in[29] = 'a'; */
1605                         in[read] = '\0';
1606                         fprintf(stderr, "BounceReply: >%s<\n", in);
1607 #endif
1608                         /* quick check if case swapped, to give informative error msg */
1609                         if (in[4] == 'A') {
1610                                 fprintf(stderr, "DNS queries get changed to uppercase, keeping upstream codec Base32\n");
1611                                 return -1;
1612                         }
1613                         if (in[5] == 'a') {
1614                                 fprintf(stderr, "DNS queries get changed to lowercase, keeping upstream codec Base32\n");
1615                                 return -1;
1616                         }
1617
1618                         for (k = 0; k < slen; k++) {
1619                                 if (in[k+4] != s[k]) {
1620                                         /* Definitely not reliable */
1621                                         if (in[k+4] >= ' ' && in[k+4] <= '~' &&
1622                                             s[k] >= ' ' && s[k] <= '~') {
1623                                                 fprintf(stderr, "DNS query char '%c' gets changed into '%c'\n",
1624                                                         s[k], in[k+4]);
1625                                         } else {
1626                                                 fprintf(stderr, "DNS query char 0x%02X gets changed into 0x%02X\n",
1627                                                         (unsigned int) us[k],
1628                                                         (unsigned int) uin[k+4]);
1629                                         }
1630                                         return 0;
1631                                 }
1632                         }
1633                         /* if still here, then all okay */
1634                         return 1;
1635                 }
1636
1637                 fprintf(stderr, "Retrying upstream codec test...\n");
1638         }
1639
1640         if (!running)
1641                 return -1;
1642
1643         /* timeout */
1644         return 0;
1645 }
1646
1647 static int
1648 handshake_upenc_autodetect(int dns_fd)
1649 /* Returns:
1650    0: keep Base32
1651    1: Base64 is okay
1652    2: Base64u is okay
1653    3: Base128 is okay
1654 */
1655 {
1656         /* Note: max 59 chars, must start with "aA".
1657            pat64: If 0129 work, assume 3-8 are okay too.
1658
1659            RFC1035 par 2.3.1 states that [A-Z0-9-] allowed, but only
1660            [A-Z] as first, and [A-Z0-9] as last char _per label_.
1661            Test by having '-' as last char.
1662          */
1663         char *pat64="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ+0129-";
1664         char *pat64u="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ_0129-";
1665         char *pat128a="aA-Aaahhh-Drink-mal-ein-J\344germeister-";
1666         char *pat128b="aA-La-fl\373te-na\357ve-fran\347aise-est-retir\351-\340-Cr\350te";
1667         char *pat128c="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
1668         char *pat128d="aA0123456789\274\275\276\277"
1669                       "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317";
1670         char *pat128e="aA"
1671                       "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
1672                       "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
1673                       "\360\361\362\363\364\365\366\367\370\371\372\373\374\375";
1674         int res;
1675
1676         /* Try Base128, starting very gently to not draw attention */
1677         while (1) {
1678                 res = handshake_upenctest(dns_fd, pat128a);
1679                 if (res < 0) {
1680                         /* DNS swaps case, msg already printed; or Ctrl-C */
1681                         return 0;
1682                 } else if (res == 0) {
1683                         /* Probably not okay, skip Base128 entirely */
1684                         break;
1685                 }
1686
1687                 res = handshake_upenctest(dns_fd, pat128b);
1688                 if (res < 0)
1689                         return 0;
1690                 else if (res == 0)
1691                         break;
1692
1693                 /* if this works, we can test the real stuff */
1694
1695                 res = handshake_upenctest(dns_fd, pat128c);
1696                 if (res < 0)
1697                         return 0;
1698                 else if (res == 0)
1699                         break;
1700
1701                 res = handshake_upenctest(dns_fd, pat128d);
1702                 if (res < 0)
1703                         return 0;
1704                 else if (res == 0)
1705                         break;
1706
1707                 res = handshake_upenctest(dns_fd, pat128e);
1708                 if (res < 0)
1709                         return 0;
1710                 else if (res == 0)
1711                         break;
1712
1713                 /* if still here, then base128 works completely */
1714                 return 3;
1715         }
1716
1717         /* Try Base64 (with plus sign) */
1718         res = handshake_upenctest(dns_fd, pat64);
1719         if (res < 0) {
1720                 /* DNS swaps case, msg already printed; or Ctrl-C */
1721                 return 0;
1722         } else if (res > 0) {
1723                 /* All okay, Base64 msg will be printed later */
1724                 return 1;
1725         }
1726
1727         /* Try Base64u (with _u_nderscore) */
1728         res = handshake_upenctest(dns_fd, pat64u);
1729         if (res < 0) {
1730                 /* DNS swaps case, msg already printed; or Ctrl-C */
1731                 return 0;
1732         } else if (res > 0) {
1733                 /* All okay, Base64u msg will be printed later */
1734                 return 2;
1735         }
1736
1737         /* if here, then nonthing worked */
1738         fprintf(stderr, "Keeping upstream codec Base32\n");
1739         return 0;
1740 }
1741
1742 static int
1743 handshake_downenctest(int dns_fd, char trycodec)
1744 /* Returns:
1745    0: not identical or error or timeout
1746    1: identical string returned
1747 */
1748 {
1749         char in[4096];
1750         int i;
1751         int read;
1752         char *s = DOWNCODECCHECK1;
1753         int slen = DOWNCODECCHECK1_LEN;
1754
1755         for (i=0; running && i<3 ;i++) {
1756
1757                 send_downenctest(dns_fd, trycodec, 1, NULL, 0);
1758
1759                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', i+1);
1760
1761                 if (read == -2)
1762                         return 0;       /* hard error */
1763
1764                 if (read > 0 && read != slen)
1765                         return 0;       /* reply incorrect = unreliable */
1766
1767                 if (read > 0) {
1768                         int k;
1769                         for (k = 0; k < slen; k++) {
1770                                 if (in[k] != s[k]) {
1771                                         /* Definitely not reliable */
1772                                         return 0;
1773                                 }
1774                         }
1775                         /* if still here, then all okay */
1776                         return 1;
1777                 }
1778
1779                 fprintf(stderr, "Retrying downstream codec test...\n");
1780         }
1781
1782         /* timeout */
1783         return 0;
1784 }
1785
1786 static char
1787 handshake_downenc_autodetect(int dns_fd)
1788 /* Returns codec char (or ' ' if no advanced codec works) */
1789 {
1790         int base64ok = 0;
1791         int base64uok = 0;
1792         int base128ok = 0;
1793
1794         if (do_qtype == T_NULL || do_qtype == T_PRIVATE) {
1795                 /* no other choice than raw */
1796                 fprintf(stderr, "No alternative downstream codec available, using default (Raw)\n");
1797                 return ' ';
1798         }
1799
1800         fprintf(stderr, "Autodetecting downstream codec (use -O to override)\n");
1801
1802         /* Try Base64 */
1803         if (handshake_downenctest(dns_fd, 'S'))
1804                 base64ok = 1;
1805         else if (running && handshake_downenctest(dns_fd, 'U'))
1806                 base64uok = 1;
1807
1808         /* Try Base128 only if 64 gives us some perspective */
1809         if (running && (base64ok || base64uok)) {
1810                 if (handshake_downenctest(dns_fd, 'V'))
1811                         base128ok = 1;
1812         }
1813
1814         /* If 128 works, then TXT may give us Raw as well */
1815         if (running && (base128ok && do_qtype == T_TXT)) {
1816                 if (handshake_downenctest(dns_fd, 'R'))
1817                         return 'R';
1818         }
1819
1820         if (!running)
1821                 return ' ';
1822
1823         if (base128ok)
1824                 return 'V';
1825         if (base64ok)
1826                 return 'S';
1827         if (base64uok)
1828                 return 'U';
1829
1830         fprintf(stderr, "No advanced downstream codecs seem to work, using default (Base32)\n");
1831         return ' ';
1832 }
1833
1834 static int
1835 handshake_qtypetest(int dns_fd, int timeout)
1836 /* Returns:
1837    0: doesn't work with this timeout
1838    1: works properly
1839 */
1840 {
1841         char in[4096];
1842         int read;
1843         char *s = DOWNCODECCHECK1;
1844         int slen = DOWNCODECCHECK1_LEN;
1845         int trycodec;
1846         int k;
1847
1848         if (do_qtype == T_NULL || do_qtype == T_PRIVATE)
1849                 trycodec = 'R';
1850         else
1851                 trycodec = 'T';
1852
1853         /* We could use 'Z' bouncing here, but 'Y' also tests that 0-255
1854            byte values can be returned, which is needed for NULL/PRIVATE
1855            to work. */
1856
1857         send_downenctest(dns_fd, trycodec, 1, NULL, 0);
1858
1859         read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', timeout);
1860
1861         if (read != slen)
1862                 return 0;       /* incorrect */
1863
1864         for (k = 0; k < slen; k++) {
1865                 if (in[k] != s[k]) {
1866                         /* corrupted */
1867                         return 0;
1868                 }
1869         }
1870
1871         /* if still here, then all okay */
1872         return 1;
1873 }
1874
1875 static int
1876 handshake_qtype_numcvt(int num)
1877 {
1878         switch (num) {
1879         case 0: return T_NULL;
1880         case 1: return T_PRIVATE;
1881         case 2: return T_TXT;
1882         case 3: return T_SRV;
1883         case 4: return T_MX;
1884         case 5: return T_CNAME;
1885         case 6: return T_A;
1886         }
1887         return T_UNSET;
1888 }
1889
1890 static int
1891 handshake_qtype_autodetect(int dns_fd)
1892 /* Returns:
1893    0: okay, do_qtype set
1894    1: problem, program exit
1895 */
1896 {
1897         int highestworking = 100;
1898         int timeout;
1899         int qtypenum;
1900
1901         fprintf(stderr, "Autodetecting DNS query type (use -T to override)");
1902         fflush(stderr);
1903
1904         /* Method: try all "interesting" qtypes with a 1-sec timeout, then try
1905            all "still-interesting" qtypes with a 2-sec timeout, etc.
1906            "Interesting" means: qtypes that (are expected to) have higher
1907            bandwidth than what we know is working already (highestworking).
1908
1909            Note that DNS relays may not immediately resolve the first (NULL)
1910            query in 1 sec, due to long recursive lookups, so we keep trying
1911            to see if things will start working after a while.
1912          */
1913
1914         for (timeout = 1; running && timeout <= 3; timeout++) {
1915                 for (qtypenum = 0; running && qtypenum < highestworking; qtypenum++) {
1916                         do_qtype = handshake_qtype_numcvt(qtypenum);
1917                         if (do_qtype == T_UNSET)
1918                                 break;  /* this round finished */
1919
1920                         fprintf(stderr, ".");
1921                         fflush(stderr);
1922
1923                         if (handshake_qtypetest(dns_fd, timeout)) {
1924                                 /* okay */
1925                                 highestworking = qtypenum;
1926 #if 0
1927                                 fprintf(stderr, " Type %s timeout %d works\n",
1928                                         client_get_qtype(), timeout);
1929 #endif
1930                                 break;
1931                                 /* try others with longer timeout */
1932                         }
1933                         /* else: try next qtype with same timeout */
1934                 }
1935                 if (highestworking == 0)
1936                         /* good, we have NULL; abort immediately */
1937                         break;
1938         }
1939
1940         fprintf(stderr, "\n");
1941
1942         if (!running) {
1943                 warnx("Stopped while autodetecting DNS query type (try setting manually with -T)");
1944                 return 1;  /* problem */
1945         }
1946
1947         /* finished */
1948         do_qtype = handshake_qtype_numcvt(highestworking);
1949
1950         if (do_qtype == T_UNSET) {
1951                 /* also catches highestworking still 100 */
1952                 warnx("No suitable DNS query type found. Are you connected to a network?");
1953                 warnx("If you expect very long roundtrip delays, use -T explicitly.");
1954                 warnx("(Also, connecting to an \"ancient\" version of iodined won't work.)");
1955                 return 1;  /* problem */
1956         }
1957
1958         /* "using qtype" message printed in handshake function */
1959         return 0;  /* okay */
1960 }
1961
1962 static int
1963 handshake_edns0_check(int dns_fd)
1964 /* Returns:
1965    0: EDNS0 not supported; or Ctrl-C
1966    1: EDNS0 works
1967 */
1968 {
1969         char in[4096];
1970         int i;
1971         int read;
1972         char *s = DOWNCODECCHECK1;
1973         int slen = DOWNCODECCHECK1_LEN;
1974         char trycodec;
1975
1976         if (do_qtype == T_NULL)
1977                 trycodec = 'R';
1978         else
1979                 trycodec = 'T';
1980
1981         for (i=0; running && i<3 ;i++) {
1982
1983                 send_downenctest(dns_fd, trycodec, 1, NULL, 0);
1984
1985                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', i+1);
1986
1987                 if (read == -2)
1988                         return 0;       /* hard error */
1989
1990                 if (read > 0 && read != slen)
1991                         return 0;       /* reply incorrect = unreliable */
1992
1993                 if (read > 0) {
1994                         int k;
1995                         for (k = 0; k < slen; k++) {
1996                                 if (in[k] != s[k]) {
1997                                         /* Definitely not reliable */
1998                                         return 0;
1999                                 }
2000                         }
2001                         /* if still here, then all okay */
2002                         return 1;
2003                 }
2004
2005                 fprintf(stderr, "Retrying EDNS0 support test...\n");
2006         }
2007
2008         /* timeout or Ctrl-C */
2009         return 0;
2010 }
2011
2012 static void
2013 handshake_switch_codec(int dns_fd, int bits)
2014 {
2015         char in[4096];
2016         int i;
2017         int read;
2018         struct encoder *tempenc;
2019
2020         if (bits == 5)
2021                 tempenc = get_base32_encoder();
2022         else if (bits == 6)
2023                 tempenc = get_base64_encoder();
2024         else if (bits == 26)    /* "2nd" 6 bits per byte, with underscore */
2025                 tempenc = get_base64u_encoder();
2026         else if (bits == 7)
2027                 tempenc = get_base128_encoder();
2028         else return;
2029
2030         fprintf(stderr, "Switching upstream to codec %s\n", tempenc->name);
2031
2032         for (i=0; running && i<5 ;i++) {
2033
2034                 send_codec_switch(dns_fd, userid, bits);
2035
2036                 read = handshake_waitdns(dns_fd, in, sizeof(in), 's', 'S', i+1);
2037
2038                 if (read > 0) {
2039                         if (strncmp("BADLEN", in, 6) == 0) {
2040                                 fprintf(stderr, "Server got bad message length. ");
2041                                 goto codec_revert;
2042                         } else if (strncmp("BADIP", in, 5) == 0) {
2043                                 fprintf(stderr, "Server rejected sender IP address. ");
2044                                 goto codec_revert;
2045                         } else if (strncmp("BADCODEC", in, 8) == 0) {
2046                                 fprintf(stderr, "Server rejected the selected codec. ");
2047                                 goto codec_revert;
2048                         }
2049                         in[read] = 0; /* zero terminate */
2050                         fprintf(stderr, "Server switched upstream to codec %s\n", in);
2051                         dataenc = tempenc;
2052                         return;
2053                 }
2054
2055                 fprintf(stderr, "Retrying codec switch...\n");
2056         }
2057         if (!running)
2058                 return;
2059
2060         fprintf(stderr, "No reply from server on codec switch. ");
2061
2062 codec_revert:
2063         fprintf(stderr, "Falling back to upstream codec %s\n", dataenc->name);
2064 }
2065
2066 static void
2067 handshake_switch_downenc(int dns_fd)
2068 {
2069         char in[4096];
2070         int i;
2071         int read;
2072         char *dname;
2073
2074         dname = "Base32";
2075         if (downenc == 'S')
2076                 dname = "Base64";
2077         else if (downenc == 'U')
2078                 dname = "Base64u";
2079         else if (downenc == 'V')
2080                 dname = "Base128";
2081         else if (downenc == 'R')
2082                 dname = "Raw";
2083
2084         fprintf(stderr, "Switching downstream to codec %s\n", dname);
2085         for (i=0; running && i<5 ;i++) {
2086
2087                 send_downenc_switch(dns_fd, userid);
2088
2089                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
2090
2091                 if (read > 0) {
2092                         if (strncmp("BADLEN", in, 6) == 0) {
2093                                 fprintf(stderr, "Server got bad message length. ");
2094                                 goto codec_revert;
2095                         } else if (strncmp("BADIP", in, 5) == 0) {
2096                                 fprintf(stderr, "Server rejected sender IP address. ");
2097                                 goto codec_revert;
2098                         } else if (strncmp("BADCODEC", in, 8) == 0) {
2099                                 fprintf(stderr, "Server rejected the selected codec. ");
2100                                 goto codec_revert;
2101                         }
2102                         in[read] = 0; /* zero terminate */
2103                         fprintf(stderr, "Server switched downstream to codec %s\n", in);
2104                         return;
2105                 }
2106
2107                 fprintf(stderr, "Retrying codec switch...\n");
2108         }
2109         if (!running)
2110                 return;
2111
2112         fprintf(stderr, "No reply from server on codec switch. ");
2113
2114 codec_revert:
2115         fprintf(stderr, "Falling back to downstream codec Base32\n");
2116 }
2117
2118 static void
2119 handshake_try_lazy(int dns_fd)
2120 {
2121         char in[4096];
2122         int i;
2123         int read;
2124
2125         fprintf(stderr, "Switching to lazy mode for low-latency\n");
2126         for (i=0; running && i<5; i++) {
2127
2128                 send_lazy_switch(dns_fd, userid);
2129
2130                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
2131
2132                 if (read > 0) {
2133                         if (strncmp("BADLEN", in, 6) == 0) {
2134                                 fprintf(stderr, "Server got bad message length. ");
2135                                 goto codec_revert;
2136                         } else if (strncmp("BADIP", in, 5) == 0) {
2137                                 fprintf(stderr, "Server rejected sender IP address. ");
2138                                 goto codec_revert;
2139                         } else if (strncmp("BADCODEC", in, 8) == 0) {
2140                                 fprintf(stderr, "Server rejected lazy mode. ");
2141                                 goto codec_revert;
2142                         } else if (strncmp("Lazy", in, 4) == 0) {
2143                                 fprintf(stderr, "Server switched to lazy mode\n");
2144                                 lazymode = 1;
2145                                 return;
2146                         }
2147                 }
2148
2149                 fprintf(stderr, "Retrying lazy mode switch...\n");
2150         }
2151         if (!running)
2152                 return;
2153
2154         fprintf(stderr, "No reply from server on lazy switch. ");
2155
2156 codec_revert:
2157         fprintf(stderr, "Falling back to legacy mode\n");
2158         lazymode = 0;
2159         selecttimeout = 1;
2160 }
2161
2162 static void
2163 handshake_lazyoff(int dns_fd)
2164 /* Used in the middle of data transfer, timing is different and no error msgs */
2165 {
2166         char in[4096];
2167         int i;
2168         int read;
2169
2170         for (i=0; running && i<5; i++) {
2171
2172                 send_lazy_switch(dns_fd, userid);
2173
2174                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', 1);
2175
2176                 if (read == 9 && strncmp("Immediate", in, 9) == 0) {
2177                         warnx("Server switched back to legacy mode.\n");
2178                         lazymode = 0;
2179                         selecttimeout = 1;
2180                         return;
2181                 }
2182         }
2183         if (!running)
2184                 return;
2185
2186         warnx("No reply from server on legacy mode switch.\n");
2187 }
2188
2189 static int
2190 fragsize_check(char *in, int read, int proposed_fragsize, int *max_fragsize)
2191 /* Returns: 0: keep checking, 1: break loop (either okay or definitely wrong) */
2192 {
2193         int acked_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
2194         int okay;
2195         int i;
2196         unsigned int v;
2197
2198         if (read >= 5 && strncmp("BADIP", in, 5) == 0) {
2199                 fprintf(stderr, "got BADIP (Try iodined -c)..\n");
2200                 fflush(stderr);
2201                 return 0;               /* maybe temporary error */
2202         }
2203
2204         if (acked_fragsize != proposed_fragsize) {
2205                 /*
2206                  * got ack for wrong fragsize, maybe late response for
2207                  * earlier query, or ack corrupted
2208                  */
2209                 return 0;
2210         }
2211
2212         if (read != proposed_fragsize) {
2213                 /*
2214                  * correctly acked fragsize but read too little (or too
2215                  * much): this fragsize is definitely not reliable
2216                  */
2217                 return 1;
2218         }
2219
2220         /* here: read == proposed_fragsize == acked_fragsize */
2221
2222         /* test: */
2223         /* in[123] = 123; */
2224
2225         if ((in[2] & 0xff) != 107) {
2226                 fprintf(stderr, "\n");
2227                 warnx("corruption at byte 2, this won't work. Try -O Base32, or other -T options.");
2228                 *max_fragsize = -1;
2229                 return 1;
2230         }
2231
2232         /* Check for corruption */
2233         okay = 1;
2234         v = in[3] & 0xff;
2235
2236         for (i = 3; i < read; i++, v = (v + 107) & 0xff)
2237                 if ((in[i] & 0xff) != v) {
2238                         okay = 0;
2239                         break;
2240                 }
2241
2242         if (okay) {
2243                 fprintf(stderr, "%d ok.. ", acked_fragsize);
2244                 fflush(stderr);
2245                 *max_fragsize = acked_fragsize;
2246                 return 1;
2247         } else {
2248                 if (downenc != ' ' && downenc != 'T') {
2249                         fprintf(stderr, "%d corrupted at %d.. (Try -O Base32)\n", acked_fragsize, i);
2250                 } else {
2251                         fprintf(stderr, "%d corrupted at %d.. ", acked_fragsize, i);
2252                 }
2253                 fflush(stderr);
2254                 return 1;
2255         }
2256
2257         /* notreached */
2258         return 1;
2259 }
2260
2261
2262 static int
2263 handshake_autoprobe_fragsize(int dns_fd)
2264 {
2265         char in[4096];
2266         int i;
2267         int read;
2268         int proposed_fragsize = 768;
2269         int range = 768;
2270         int max_fragsize;
2271
2272         max_fragsize = 0;
2273         fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n");
2274         while (running && range > 0 && (range >= 8 || max_fragsize < 300)) {
2275                 /* stop the slow probing early when we have enough bytes anyway */
2276                 for (i=0; running && i<3 ;i++) {
2277
2278                         send_fragsize_probe(dns_fd, proposed_fragsize);
2279
2280                         read = handshake_waitdns(dns_fd, in, sizeof(in), 'r', 'R', 1);
2281
2282                         if (read > 0) {
2283                                 /* We got a reply */
2284                                 if (fragsize_check(in, read, proposed_fragsize, &max_fragsize) == 1)
2285                                         break;
2286                         }
2287
2288                         fprintf(stderr, ".");
2289                         fflush(stderr);
2290                 }
2291                 if (max_fragsize < 0)
2292                         break;
2293
2294                 range >>= 1;
2295                 if (max_fragsize == proposed_fragsize) {
2296                         /* Try bigger */
2297                         proposed_fragsize += range;
2298                 } else {
2299                         /* Try smaller */
2300                         fprintf(stderr, "%d not ok.. ", proposed_fragsize);
2301                         fflush(stderr);
2302                         proposed_fragsize -= range;
2303                 }
2304         }
2305         if (!running) {
2306                 fprintf(stderr, "\n");
2307                 warnx("stopped while autodetecting fragment size (Try setting manually with -m)");
2308                 return 0;
2309         }
2310         if (max_fragsize <= 2) {
2311                 /* Tried all the way down to 2 and found no good size.
2312                    But we _did_ do all handshake before this, so there must
2313                    be some workable connection. */
2314                 fprintf(stderr, "\n");
2315                 warnx("found no accepted fragment size.");
2316                 warnx("try setting -M to 200 or lower, or try other -T or -O options.");
2317                 return 0;
2318         }
2319         /* data header adds 2 bytes */
2320         fprintf(stderr, "will use %d-2=%d\n", max_fragsize, max_fragsize - 2);
2321
2322         /* need 1200 / 16frags = 75 bytes fragsize */
2323         if (max_fragsize < 82) {
2324                 fprintf(stderr, "Note: this probably won't work well.\n");
2325                 fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n");
2326         } else if (max_fragsize < 202 &&
2327             (do_qtype == T_NULL || do_qtype == T_PRIVATE || do_qtype == T_TXT ||
2328              do_qtype == T_SRV || do_qtype == T_MX)) {
2329                 fprintf(stderr, "Note: this isn't very much.\n");
2330                 fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n");
2331         }
2332
2333         return max_fragsize - 2;
2334 }
2335
2336 static void
2337 handshake_set_fragsize(int dns_fd, int fragsize)
2338 {
2339         char in[4096];
2340         int i;
2341         int read;
2342
2343         fprintf(stderr, "Setting downstream fragment size to max %d...\n", fragsize);
2344         for (i=0; running && i<5 ;i++) {
2345
2346                 send_set_downstream_fragsize(dns_fd, fragsize);
2347
2348                 read = handshake_waitdns(dns_fd, in, sizeof(in), 'n', 'N', i+1);
2349
2350                 if (read > 0) {
2351
2352                         if (strncmp("BADFRAG", in, 7) == 0) {
2353                                 fprintf(stderr, "Server rejected fragsize. Keeping default.");
2354                                 return;
2355                         } else if (strncmp("BADIP", in, 5) == 0) {
2356                                 fprintf(stderr, "Server rejected sender IP address.\n");
2357                                 return;
2358                         }
2359
2360                         /* The server returns the accepted fragsize:
2361                         accepted_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff) */
2362                         return;
2363                 }
2364
2365                 fprintf(stderr, "Retrying set fragsize...\n");
2366         }
2367         if (!running)
2368                 return;
2369
2370         fprintf(stderr, "No reply from server when setting fragsize. Keeping default.\n");
2371 }
2372
2373 int
2374 client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsize)
2375 {
2376         int seed;
2377         int upcodec;
2378         int r;
2379
2380         dnsc_use_edns0 = 0;
2381
2382         /* qtype message printed in handshake function */
2383         if (do_qtype == T_UNSET) {
2384                 r = handshake_qtype_autodetect(dns_fd);
2385                 if (r) {
2386                         return r;
2387                 }
2388         }
2389
2390         fprintf(stderr, "Using DNS type %s queries\n", client_get_qtype());
2391
2392         r = handshake_version(dns_fd, &seed);
2393         if (r) {
2394                 return r;
2395         }
2396
2397         r = handshake_login(dns_fd, seed);
2398         if (r) {
2399                 return r;
2400         }
2401
2402         if (raw_mode && handshake_raw_udp(dns_fd, seed)) {
2403                 conn = CONN_RAW_UDP;
2404                 selecttimeout = 20;
2405         } else {
2406                 if (raw_mode == 0) {
2407                         fprintf(stderr, "Skipping raw mode\n");
2408                 }
2409
2410                 dnsc_use_edns0 = 1;
2411                 if (handshake_edns0_check(dns_fd) && running) {
2412                         fprintf(stderr, "Using EDNS0 extension\n");
2413                 } else if (!running) {
2414                         return -1;
2415                 } else {
2416                         fprintf(stderr, "DNS relay does not support EDNS0 extension\n");
2417                         dnsc_use_edns0 = 0;
2418                 }
2419
2420                 upcodec = handshake_upenc_autodetect(dns_fd);
2421                 if (!running)
2422                         return -1;
2423
2424                 if (upcodec == 1) {
2425                         handshake_switch_codec(dns_fd, 6);
2426                 } else if (upcodec == 2) {
2427                         handshake_switch_codec(dns_fd, 26);
2428                 } else if (upcodec == 3) {
2429                         handshake_switch_codec(dns_fd, 7);
2430                 }
2431                 if (!running)
2432                         return -1;
2433
2434                 if (downenc == ' ') {
2435                         downenc = handshake_downenc_autodetect(dns_fd);
2436                 }
2437                 if (!running)
2438                         return -1;
2439
2440                 if (downenc != ' ') {
2441                         handshake_switch_downenc(dns_fd);
2442                 }
2443                 if (!running)
2444                         return -1;
2445
2446                 if (lazymode) {
2447                         handshake_try_lazy(dns_fd);
2448                 }
2449                 if (!running)
2450                         return -1;
2451
2452                 if (autodetect_frag_size) {
2453                         fragsize = handshake_autoprobe_fragsize(dns_fd);
2454                         if (!fragsize) {
2455                                 return 1;
2456                         }
2457                 }
2458
2459                 handshake_set_fragsize(dns_fd, fragsize);
2460                 if (!running)
2461                         return -1;
2462         }
2463
2464         return 0;
2465 }
2466