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