postinst: change order.
[debian/iodine.git] / src / client.c
index 0036b0ed093431a7b8fbb325ab10d3190f5b2355..0f951accbf05cb209aa128921f84af262cb05f37 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
+ * 2006-2009 Bjorn Andersson <flex@kryo.se>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +20,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <signal.h>
 #include <unistd.h>
 #include <sys/param.h>
 
 #ifdef WINDOWS32
 #include "windows.h"
-#include <winsock2.h>
 #else
+#ifdef ANDROID
+#include "android_dns.h"
+#endif
 #include <arpa/nameser.h>
 #ifdef DARWIN
 #define BIND_8_COMPAT
@@ -58,7 +62,8 @@ static void handshake_lazyoff(int dns_fd);
 static int running;
 static const char *password;
 
-static struct sockaddr_in nameserv;
+static struct sockaddr_storage nameserv;
+static int nameserv_len;
 static struct sockaddr_in raw_serv;
 static const char *topdomain;
 
@@ -89,10 +94,10 @@ static struct encoder *b128;
 /* The encoder used for data packets
  * Defaults to Base32, can be changed after handshake */
 static struct encoder *dataenc;
-  
+
 /* The encoder to use for downstream data */
 static char downenc = ' ';
+
 /* set query type to send */
 static unsigned short do_qtype = T_UNSET;
 
@@ -146,49 +151,10 @@ client_get_conn()
 }
 
 void
-client_set_nameserver(const char *cp, int port) 
+client_set_nameserver(struct sockaddr_storage *addr, int addrlen)
 {
-       struct in_addr addr;
-
-       if (inet_aton(cp, &addr) != 1) {
-               /* try resolving if a domain is given */
-               struct hostent *host;
-               const char *err;
-               host = gethostbyname(cp);
-               if (host != NULL && h_errno > 0) {
-                       int i = 0;
-                       while (host->h_addr_list[i] != 0) {
-                               addr = *(struct in_addr *) host->h_addr_list[i++];
-                               fprintf(stderr, "Resolved %s to %s\n", cp, inet_ntoa(addr));
-                               goto setaddr;
-                       }
-               }
-#ifndef WINDOWS32
-               err = hstrerror(h_errno);
-#else
-               {
-                       DWORD wserr = WSAGetLastError();
-                       switch (wserr) {
-                       case WSAHOST_NOT_FOUND:
-                               err = "Host not found";
-                               break;
-                       case WSANO_DATA:
-                               err = "No data record found";
-                               break;
-                       default:
-                               err = "Unknown error";
-                               break;
-                       }
-               }
-#endif /* !WINDOWS32 */
-               errx(1, "error resolving nameserver '%s': %s", cp, err);
-       }
-
-setaddr:
-       memset(&nameserv, 0, sizeof(nameserv));
-       nameserv.sin_family = AF_INET;
-       nameserv.sin_port = htons(port);
-       nameserv.sin_addr = addr;
+       memcpy(&nameserv, addr, addrlen);
+       nameserv_len = addrlen;
 }
 
 void
@@ -203,11 +169,13 @@ client_set_password(const char *cp)
        password = cp;
 }
 
-void
-set_qtype(char *qtype)
+int
+client_set_qtype(char *qtype)
 {
        if (!strcasecmp(qtype, "NULL"))
                do_qtype = T_NULL;
+       else if (!strcasecmp(qtype, "PRIVATE"))
+               do_qtype = T_PRIVATE;
        else if (!strcasecmp(qtype, "CNAME"))
                do_qtype = T_CNAME;
        else if (!strcasecmp(qtype, "A"))
@@ -218,14 +186,16 @@ set_qtype(char *qtype)
                do_qtype = T_SRV;
        else if (!strcasecmp(qtype, "TXT"))
                do_qtype = T_TXT;
+       return (do_qtype == T_UNSET);
 }
 
 char *
-get_qtype()
+client_get_qtype()
 {
        char *c = "UNDEFINED";
 
        if (do_qtype == T_NULL)         c = "NULL";
+       else if (do_qtype == T_PRIVATE) c = "PRIVATE";
        else if (do_qtype == T_CNAME)   c = "CNAME";
        else if (do_qtype == T_A)       c = "A";
        else if (do_qtype == T_MX)      c = "MX";
@@ -236,7 +206,7 @@ get_qtype()
 }
 
 void
-set_downenc(char *encoding)
+client_set_downenc(char *encoding)
 {
        if (!strcasecmp(encoding, "base32"))
                downenc = 'T';
@@ -250,7 +220,7 @@ set_downenc(char *encoding)
                downenc = 'R';
 }
 
-void 
+void
 client_set_selecttimeout(int select_timeout)
 {
        selecttimeout = select_timeout;
@@ -302,7 +272,7 @@ send_query(int fd, char *hostname)
        fprintf(stderr, "  Sendquery: id %5d name[0] '%c'\n", q.id, hostname[0]);
 #endif
 
-       sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv));
+       sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, nameserv_len);
 
        /* There are DNS relays that time out quickly but don't send anything
           back on timeout.
@@ -369,7 +339,7 @@ send_packet(int fd, char cmd, const char *data, const size_t datalen)
        char buf[4096];
 
        buf[0] = cmd;
-       
+
        build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain,
                       b32, hostname_maxlen);
        send_query(fd, buf);
@@ -402,7 +372,7 @@ send_chunk(int fd)
        /* Build upstream data header (see doc/proto_xxxxxxxx.txt) */
 
        buf[0] = userid_char;           /* First byte is hex userid */
-  
+
        code = ((outpkt.seqno & 7) << 2) | ((outpkt.fragment & 15) >> 2);
        buf[1] = b32_5to8(code); /* Second byte is 3 bits seqno, 2 upper bits fragment count */
 
@@ -416,7 +386,7 @@ send_chunk(int fd)
        datacmc++;
        if (datacmc >= 36)
                datacmc = 0;
-  
+
 #if 0
        fprintf(stderr, "  Send: down %d/%d up %d/%d, %d bytes\n",
                inpkt.seqno, inpkt.fragment, outpkt.seqno, outpkt.fragment,
@@ -431,12 +401,12 @@ send_ping(int fd)
 {
        if (conn == CONN_DNS_NULL) {
                char data[4];
-               
+
                data[0] = userid;
                data[1] = ((inpkt.seqno & 7) << 4) | (inpkt.fragment & 15);
                data[2] = (rand_seed >> 8) & 0xff;
                data[3] = (rand_seed >> 0) & 0xff;
-               
+
                rand_seed++;
 
 #if 0
@@ -596,13 +566,13 @@ read_dns_withq(int dns_fd, int tun_fd, char *buf, int buflen, struct query *q)
    Returns >0 on correct replies; value is #valid bytes in *buf.
 */
 {
-       struct sockaddr_in from;
+       struct sockaddr_storage from;
        char data[64*1024];
        socklen_t addrlen;
        int r;
 
-       addrlen = sizeof(struct sockaddr);
-       if ((r = recvfrom(dns_fd, data, sizeof(data), 0, 
+       addrlen = sizeof(from);
+       if ((r = recvfrom(dns_fd, data, sizeof(data), 0,
                          (struct sockaddr*)&from, &addrlen)) < 0) {
                warn("recvfrom");
                return -1;
@@ -624,9 +594,9 @@ read_dns_withq(int dns_fd, int tun_fd, char *buf, int buflen, struct query *q)
                        /*
                         * buf is a hostname or txt stream that we still need to
                         * decode to binary
-                        * 
+                        *
                         * also update rv with the number of valid bytes
-                        * 
+                        *
                         * data is unused here, and will certainly hold the smaller binary
                         */
 
@@ -1167,11 +1137,11 @@ client_tunnel(int tun_fd, int dns_fd)
                        warnx("No downstream data received in 60 seconds, shutting down.");
                        running = 0;
                }
-               
+
                if (running == 0)
                        break;
 
-               if (i < 0) 
+               if (i < 0)
                        err(1, "select");
 
                if (i == 0) {
@@ -1214,7 +1184,7 @@ client_tunnel(int tun_fd, int dns_fd)
                        if (FD_ISSET(dns_fd, &fds)) {
                                if (tunnel_dns(tun_fd, dns_fd) <= 0)
                                        continue;
-                       } 
+                       }
                }
        }
 
@@ -1232,7 +1202,7 @@ send_login(int fd, char *login, int len)
 
        data[17] = (rand_seed >> 8) & 0xff;
        data[18] = (rand_seed >> 0) & 0xff;
-       
+
        rand_seed++;
 
        send_packet(fd, 'l', data, sizeof(data));
@@ -1271,23 +1241,23 @@ static void
 send_set_downstream_fragsize(int fd, int fragsize)
 {
        char data[5];
-       
+
        data[0] = userid;
        data[1] = (fragsize & 0xff00) >> 8;
        data[2] = (fragsize & 0x00ff);
        data[3] = (rand_seed >> 8) & 0xff;
        data[4] = (rand_seed >> 0) & 0xff;
-       
+
        rand_seed++;
 
        send_packet(fd, 'n', data, sizeof(data));
 }
 
-static void 
+static void
 send_version(int fd, uint32_t version)
 {
        char data[6];
+
        data[0] = (version >> 24) & 0xff;
        data[1] = (version >> 16) & 0xff;
        data[2] = (version >> 8) & 0xff;
@@ -1295,7 +1265,7 @@ send_version(int fd, uint32_t version)
 
        data[4] = (rand_seed >> 8) & 0xff;
        data[5] = (rand_seed >> 0) & 0xff;
-       
+
        rand_seed++;
 
        send_packet(fd, 'v', data, sizeof(data));
@@ -1306,7 +1276,7 @@ send_ip_request(int fd, int userid)
 {
        char buf[512] = "i____.";
        buf[1] = b32_5to8(userid);
-       
+
        buf[2] = b32_5to8((rand_seed >> 10) & 0x1f);
        buf[3] = b32_5to8((rand_seed >> 5) & 0x1f);
        buf[4] = b32_5to8((rand_seed ) & 0x1f);
@@ -1330,7 +1300,7 @@ send_upenctest(int fd, char *s)
 /* NOTE: String may be at most 63-4=59 chars to fit in 1 dns chunk. */
 {
        char buf[512] = "z___";
-       
+
        buf[1] = b32_5to8((rand_seed >> 10) & 0x1f);
        buf[2] = b32_5to8((rand_seed >> 5) & 0x1f);
        buf[3] = b32_5to8((rand_seed ) & 0x1f);
@@ -1366,7 +1336,7 @@ send_codec_switch(int fd, int userid, int bits)
        char buf[512] = "s_____.";
        buf[1] = b32_5to8(userid);
        buf[2] = b32_5to8(bits);
-       
+
        buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
        buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
        buf[5] = b32_5to8((rand_seed ) & 0x1f);
@@ -1429,33 +1399,31 @@ handshake_version(int dns_fd, int *seed)
 
                read = handshake_waitdns(dns_fd, in, sizeof(in), 'v', 'V', i+1);
 
-               /*XXX START adjust indent 1 tab back*/
-                       if (read >= 9) {
-                               payload =  (((in[4] & 0xff) << 24) |
-                                               ((in[5] & 0xff) << 16) |
-                                               ((in[6] & 0xff) << 8) |
-                                               ((in[7] & 0xff)));
-
-                               if (strncmp("VACK", in, 4) == 0) {
-                                       *seed = payload;
-                                       userid = in[8];
-                                       userid_char = hex[userid & 15];
-                                       userid_char2 = hex2[userid & 15];
+               if (read >= 9) {
+                       payload =  (((in[4] & 0xff) << 24) |
+                                       ((in[5] & 0xff) << 16) |
+                                       ((in[6] & 0xff) << 8) |
+                                       ((in[7] & 0xff)));
+
+                       if (strncmp("VACK", in, 4) == 0) {
+                               *seed = payload;
+                               userid = in[8];
+                               userid_char = hex[userid & 15];
+                               userid_char2 = hex2[userid & 15];
+
+                               fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid);
+                               return 0;
+                       } else if (strncmp("VNAK", in, 4) == 0) {
+                               warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
+                                               VERSION, payload);
+                               return 1;
+                       } else if (strncmp("VFUL", in, 4) == 0) {
+                               warnx("Server full, all %d slots are taken. Try again later", payload);
+                               return 1;
+                       }
+               } else if (read > 0)
+                       warnx("did not receive proper login challenge");
 
-                                       fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid);
-                                       return 0;
-                               } else if (strncmp("VNAK", in, 4) == 0) {
-                                       warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up", 
-                                                       VERSION, payload);
-                                       return 1;
-                               } else if (strncmp("VFUL", in, 4) == 0) {
-                                       warnx("Server full, all %d slots are taken. Try again later", payload);
-                                       return 1;
-                               }
-                       } else if (read > 0)
-                               warnx("did not receive proper login challenge");
-               /*XXX END adjust indent 1 tab back*/
-               
                fprintf(stderr, "Retrying version check...\n");
        }
        warnx("couldn't connect to server (maybe other -T options will work)");
@@ -1474,37 +1442,35 @@ handshake_login(int dns_fd, int seed)
        int read;
 
        login_calculate(login, 16, password, seed);
-       
+
        for (i=0; running && i<5 ;i++) {
 
                send_login(dns_fd, login, 16);
 
                read = handshake_waitdns(dns_fd, in, sizeof(in), 'l', 'L', i+1);
 
-               /*XXX START adjust indent 1 tab back*/
-                       if (read > 0) {
-                               int netmask;
-                               if (strncmp("LNAK", in, 4) == 0) {
-                                       fprintf(stderr, "Bad password\n");
-                                       return 1;
-                               } else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d", 
-                                       server, client, &mtu, &netmask) == 4) {
-                                       
-                                       server[64] = 0;
-                                       client[64] = 0;
-                                       if (tun_setip(client, server, netmask) == 0 && 
-                                               tun_setmtu(mtu) == 0) {
-
-                                               fprintf(stderr, "Server tunnel IP is %s\n", server);
-                                               return 0;
-                                       } else {
-                                               errx(4, "Failed to set IP and MTU");
-                                       }
+               if (read > 0) {
+                       int netmask;
+                       if (strncmp("LNAK", in, 4) == 0) {
+                               fprintf(stderr, "Bad password\n");
+                               return 1;
+                       } else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
+                               server, client, &mtu, &netmask) == 4) {
+
+                               server[64] = 0;
+                               client[64] = 0;
+                               if (tun_setip(client, server, netmask) == 0 &&
+                                       tun_setmtu(mtu) == 0) {
+
+                                       fprintf(stderr, "Server tunnel IP is %s\n", server);
+                                       return 0;
                                } else {
-                                       fprintf(stderr, "Received bad handshake\n");
+                                       errx(4, "Failed to set IP and MTU");
                                }
+                       } else {
+                               fprintf(stderr, "Received bad handshake\n");
                        }
-               /*XXX END adjust indent 1 tab back*/
+               }
 
                fprintf(stderr, "Retrying login...\n");
        }
@@ -1531,20 +1497,18 @@ handshake_raw_udp(int dns_fd, int seed)
 
                len = handshake_waitdns(dns_fd, in, sizeof(in), 'i', 'I', i+1);
 
-               /*XXX START adjust indent 1 tab back*/
-                       if (len == 5 && in[0] == 'I') {
-                               /* Received IP address */
-                               remoteaddr = (in[1] & 0xff);
-                               remoteaddr <<= 8;
-                               remoteaddr |= (in[2] & 0xff);
-                               remoteaddr <<= 8;
-                               remoteaddr |= (in[3] & 0xff);
-                               remoteaddr <<= 8;
-                               remoteaddr |= (in[4] & 0xff);
-                               server.s_addr = ntohl(remoteaddr);
-                               break;
-                       }
-               /*XXX END adjust indent 1 tab back*/
+               if (len == 5 && in[0] == 'I') {
+                       /* Received IP address */
+                       remoteaddr = (in[1] & 0xff);
+                       remoteaddr <<= 8;
+                       remoteaddr |= (in[2] & 0xff);
+                       remoteaddr <<= 8;
+                       remoteaddr |= (in[3] & 0xff);
+                       remoteaddr <<= 8;
+                       remoteaddr |= (in[4] & 0xff);
+                       server.s_addr = ntohl(remoteaddr);
+                       break;
+               }
 
                fprintf(stderr, ".");
                fflush(stderr);
@@ -1552,7 +1516,7 @@ handshake_raw_udp(int dns_fd, int seed)
        fprintf(stderr, "\n");
        if (!running)
                return 0;
-       
+
        if (!remoteaddr) {
                fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n");
                return 0;
@@ -1566,7 +1530,7 @@ handshake_raw_udp(int dns_fd, int seed)
        raw_serv.sin_port = htons(53);
        raw_serv.sin_addr = server;
 
-       /* do login against port 53 on remote server 
+       /* do login against port 53 on remote server
         * based on the old seed. If reply received,
         * switch to raw udp mode */
        for (i=0; running && i<4 ;i++) {
@@ -1574,7 +1538,7 @@ handshake_raw_udp(int dns_fd, int seed)
                tv.tv_usec = 0;
 
                send_raw_udp_login(dns_fd, userid, seed);
-               
+
                FD_ZERO(&fds);
                FD_SET(dns_fd, &fds);
 
@@ -1587,7 +1551,7 @@ handshake_raw_udp(int dns_fd, int seed)
                                char hash[16];
                                login_calculate(hash, 16, password, seed - 1);
                                if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0
-                                       && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN 
+                                       && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN
                                        && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0) {
 
                                        fprintf(stderr, "OK\n");
@@ -1598,7 +1562,7 @@ handshake_raw_udp(int dns_fd, int seed)
                fprintf(stderr, ".");
                fflush(stderr);
        }
-       
+
        fprintf(stderr, "failed\n");
        return 0;
 }
@@ -1827,7 +1791,7 @@ handshake_downenc_autodetect(int dns_fd)
        int base64uok = 0;
        int base128ok = 0;
 
-       if (do_qtype == T_NULL) {
+       if (do_qtype == T_NULL || do_qtype == T_PRIVATE) {
                /* no other choice than raw */
                fprintf(stderr, "No alternative downstream codec available, using default (Raw)\n");
                return ' ';
@@ -1881,13 +1845,14 @@ handshake_qtypetest(int dns_fd, int timeout)
        int trycodec;
        int k;
 
-       if (do_qtype == T_NULL)
+       if (do_qtype == T_NULL || do_qtype == T_PRIVATE)
                trycodec = 'R';
        else
                trycodec = 'T';
 
        /* We could use 'Z' bouncing here, but 'Y' also tests that 0-255
-          byte values can be returned, which is needed for NULL to work. */
+          byte values can be returned, which is needed for NULL/PRIVATE
+          to work. */
 
        send_downenctest(dns_fd, trycodec, 1, NULL, 0);
 
@@ -1912,11 +1877,12 @@ handshake_qtype_numcvt(int num)
 {
        switch (num) {
        case 0: return T_NULL;
-       case 1: return T_TXT;
-       case 2: return T_SRV;
-       case 3: return T_MX;
-       case 4: return T_CNAME;
-       case 5: return T_A;
+       case 1: return T_PRIVATE;
+       case 2: return T_TXT;
+       case 3: return T_SRV;
+       case 4: return T_MX;
+       case 5: return T_CNAME;
+       case 6: return T_A;
        }
        return T_UNSET;
 }
@@ -1959,7 +1925,7 @@ handshake_qtype_autodetect(int dns_fd)
                                highestworking = qtypenum;
 #if 0
                                fprintf(stderr, " Type %s timeout %d works\n",
-                                       get_qtype(), timeout);
+                                       client_get_qtype(), timeout);
 #endif
                                break;
                                /* try others with longer timeout */
@@ -2066,27 +2032,25 @@ handshake_switch_codec(int dns_fd, int bits)
        for (i=0; running && i<5 ;i++) {
 
                send_codec_switch(dns_fd, userid, bits);
-               
+
                read = handshake_waitdns(dns_fd, in, sizeof(in), 's', 'S', i+1);
 
-               /*XXX START adjust indent 1 tab back*/                  
-                       if (read > 0) {
-                               if (strncmp("BADLEN", in, 6) == 0) {
-                                       fprintf(stderr, "Server got bad message length. ");
-                                       goto codec_revert;
-                               } else if (strncmp("BADIP", in, 5) == 0) {
-                                       fprintf(stderr, "Server rejected sender IP address. ");
-                                       goto codec_revert;
-                               } else if (strncmp("BADCODEC", in, 8) == 0) {
-                                       fprintf(stderr, "Server rejected the selected codec. ");
-                                       goto codec_revert;
-                               }
-                               in[read] = 0; /* zero terminate */
-                               fprintf(stderr, "Server switched upstream to codec %s\n", in);
-                               dataenc = tempenc;
-                               return;
+               if (read > 0) {
+                       if (strncmp("BADLEN", in, 6) == 0) {
+                               fprintf(stderr, "Server got bad message length. ");
+                               goto codec_revert;
+                       } else if (strncmp("BADIP", in, 5) == 0) {
+                               fprintf(stderr, "Server rejected sender IP address. ");
+                               goto codec_revert;
+                       } else if (strncmp("BADCODEC", in, 8) == 0) {
+                               fprintf(stderr, "Server rejected the selected codec. ");
+                               goto codec_revert;
                        }
-               /*XXX END adjust indent 1 tab back*/
+                       in[read] = 0; /* zero terminate */
+                       fprintf(stderr, "Server switched upstream to codec %s\n", in);
+                       dataenc = tempenc;
+                       return;
+               }
 
                fprintf(stderr, "Retrying codec switch...\n");
        }
@@ -2095,7 +2059,7 @@ handshake_switch_codec(int dns_fd, int bits)
 
        fprintf(stderr, "No reply from server on codec switch. ");
 
-codec_revert: 
+codec_revert:
        fprintf(stderr, "Falling back to upstream codec %s\n", dataenc->name);
 }
 
@@ -2124,23 +2088,21 @@ handshake_switch_downenc(int dns_fd)
 
                read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
 
-               /*XXX START adjust indent 1 tab back*/
-                       if (read > 0) {
-                               if (strncmp("BADLEN", in, 6) == 0) {
-                                       fprintf(stderr, "Server got bad message length. ");
-                                       goto codec_revert;
-                               } else if (strncmp("BADIP", in, 5) == 0) {
-                                       fprintf(stderr, "Server rejected sender IP address. ");
-                                       goto codec_revert;
-                               } else if (strncmp("BADCODEC", in, 8) == 0) {
-                                       fprintf(stderr, "Server rejected the selected codec. ");
-                                       goto codec_revert;
-                               }
-                               in[read] = 0; /* zero terminate */
-                               fprintf(stderr, "Server switched downstream to codec %s\n", in);
-                               return;
+               if (read > 0) {
+                       if (strncmp("BADLEN", in, 6) == 0) {
+                               fprintf(stderr, "Server got bad message length. ");
+                               goto codec_revert;
+                       } else if (strncmp("BADIP", in, 5) == 0) {
+                               fprintf(stderr, "Server rejected sender IP address. ");
+                               goto codec_revert;
+                       } else if (strncmp("BADCODEC", in, 8) == 0) {
+                               fprintf(stderr, "Server rejected the selected codec. ");
+                               goto codec_revert;
                        }
-               /*XXX END adjust indent 1 tab back*/
+                       in[read] = 0; /* zero terminate */
+                       fprintf(stderr, "Server switched downstream to codec %s\n", in);
+                       return;
+               }
 
                fprintf(stderr, "Retrying codec switch...\n");
        }
@@ -2149,7 +2111,7 @@ handshake_switch_downenc(int dns_fd)
 
        fprintf(stderr, "No reply from server on codec switch. ");
 
-codec_revert: 
+codec_revert:
        fprintf(stderr, "Falling back to downstream codec Base32\n");
 }
 
@@ -2167,24 +2129,22 @@ handshake_try_lazy(int dns_fd)
 
                read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
 
-               /*XXX START adjust indent 1 tab back*/
-                       if (read > 0) {
-                               if (strncmp("BADLEN", in, 6) == 0) {
-                                       fprintf(stderr, "Server got bad message length. ");
-                                       goto codec_revert;
-                               } else if (strncmp("BADIP", in, 5) == 0) {
-                                       fprintf(stderr, "Server rejected sender IP address. ");
-                                       goto codec_revert;
-                               } else if (strncmp("BADCODEC", in, 8) == 0) {
-                                       fprintf(stderr, "Server rejected lazy mode. ");
-                                       goto codec_revert;
-                               } else if (strncmp("Lazy", in, 4) == 0) {
-                                       fprintf(stderr, "Server switched to lazy mode\n");
-                                       lazymode = 1;
-                                       return;
-                               }
+               if (read > 0) {
+                       if (strncmp("BADLEN", in, 6) == 0) {
+                               fprintf(stderr, "Server got bad message length. ");
+                               goto codec_revert;
+                       } else if (strncmp("BADIP", in, 5) == 0) {
+                               fprintf(stderr, "Server rejected sender IP address. ");
+                               goto codec_revert;
+                       } else if (strncmp("BADCODEC", in, 8) == 0) {
+                               fprintf(stderr, "Server rejected lazy mode. ");
+                               goto codec_revert;
+                       } else if (strncmp("Lazy", in, 4) == 0) {
+                               fprintf(stderr, "Server switched to lazy mode\n");
+                               lazymode = 1;
+                               return;
                        }
-               /*XXX END adjust indent 1 tab back*/
+               }
 
                fprintf(stderr, "Retrying lazy mode switch...\n");
        }
@@ -2193,7 +2153,7 @@ handshake_try_lazy(int dns_fd)
 
        fprintf(stderr, "No reply from server on lazy switch. ");
 
-codec_revert: 
+codec_revert:
        fprintf(stderr, "Falling back to legacy mode\n");
        lazymode = 0;
        selecttimeout = 1;
@@ -2213,14 +2173,12 @@ handshake_lazyoff(int dns_fd)
 
                read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', 1);
 
-               /*XXX START adjust indent 2 tabs back*/
-                               if (read == 9 && strncmp("Immediate", in, 9) == 0) {
-                                       warnx("Server switched back to legacy mode.\n");
-                                       lazymode = 0;
-                                       selecttimeout = 1;
-                                       return;
-                               }
-               /*XXX END adjust indent 2 tabs back*/
+               if (read == 9 && strncmp("Immediate", in, 9) == 0) {
+                       warnx("Server switched back to legacy mode.\n");
+                       lazymode = 0;
+                       selecttimeout = 1;
+                       return;
+               }
        }
        if (!running)
                return;
@@ -2275,28 +2233,26 @@ fragsize_check(char *in, int read, int proposed_fragsize, int *max_fragsize)
        okay = 1;
        v = in[3] & 0xff;
 
-       /*XXX START adjust indent 1 tab back*/
-               for (i = 3; i < read; i++, v = (v + 107) & 0xff)
-                       if ((in[i] & 0xff) != v) {
-                               okay = 0;
-                               break;
-                       }
+       for (i = 3; i < read; i++, v = (v + 107) & 0xff)
+               if ((in[i] & 0xff) != v) {
+                       okay = 0;
+                       break;
+               }
 
-               if (okay) {
-                       fprintf(stderr, "%d ok.. ", acked_fragsize);
-                       fflush(stderr);
-                       *max_fragsize = acked_fragsize;
-                       return 1;
+       if (okay) {
+               fprintf(stderr, "%d ok.. ", acked_fragsize);
+               fflush(stderr);
+               *max_fragsize = acked_fragsize;
+               return 1;
+       } else {
+               if (downenc != ' ' && downenc != 'T') {
+                       fprintf(stderr, "%d corrupted at %d.. (Try -O Base32)\n", acked_fragsize, i);
                } else {
-                       if (downenc != ' ' && downenc != 'T') {
-                               fprintf(stderr, "%d corrupted at %d.. (Try -O Base32)\n", acked_fragsize, i);
-                       } else {
-                               fprintf(stderr, "%d corrupted at %d.. ", acked_fragsize, i);
-                       }
-                       fflush(stderr);
-                       return 1;
+                       fprintf(stderr, "%d corrupted at %d.. ", acked_fragsize, i);
                }
-       /*XXX END adjust indent 1 tab back*/
+               fflush(stderr);
+               return 1;
+       }
 
        /* notreached */
        return 1;
@@ -2314,7 +2270,7 @@ handshake_autoprobe_fragsize(int dns_fd)
        int max_fragsize;
 
        max_fragsize = 0;
-       fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n"); 
+       fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n");
        while (running && range > 0 && (range >= 8 || max_fragsize < 300)) {
                /* stop the slow probing early when we have enough bytes anyway */
                for (i=0; running && i<3 ;i++) {
@@ -2322,14 +2278,12 @@ handshake_autoprobe_fragsize(int dns_fd)
                        send_fragsize_probe(dns_fd, proposed_fragsize);
 
                        read = handshake_waitdns(dns_fd, in, sizeof(in), 'r', 'R', 1);
-                               
-                       /*XXX START adjust indent 1 tab back*/
-                               if (read > 0) {
-                                       /* We got a reply */
-                                       if (fragsize_check(in, read, proposed_fragsize, &max_fragsize) == 1)
-                                               break;
-                               }
-                       /*XXX END adjust indent 1 tab back*/
+
+                       if (read > 0) {
+                               /* We got a reply */
+                               if (fragsize_check(in, read, proposed_fragsize, &max_fragsize) == 1)
+                                       break;
+                       }
 
                        fprintf(stderr, ".");
                        fflush(stderr);
@@ -2370,7 +2324,7 @@ handshake_autoprobe_fragsize(int dns_fd)
                fprintf(stderr, "Note: this probably won't work well.\n");
                fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n");
        } else if (max_fragsize < 202 &&
-           (do_qtype == T_NULL || do_qtype == T_TXT ||
+           (do_qtype == T_NULL || do_qtype == T_PRIVATE || do_qtype == T_TXT ||
             do_qtype == T_SRV || do_qtype == T_MX)) {
                fprintf(stderr, "Note: this isn't very much.\n");
                fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n");
@@ -2393,22 +2347,20 @@ handshake_set_fragsize(int dns_fd, int fragsize)
 
                read = handshake_waitdns(dns_fd, in, sizeof(in), 'n', 'N', i+1);
 
-               /*XXX START adjust indent 1 tab back*/                  
-                       if (read > 0) {
-                               int accepted_fragsize;
-
-                               if (strncmp("BADFRAG", in, 7) == 0) {
-                                       fprintf(stderr, "Server rejected fragsize. Keeping default.");
-                                       return;
-                               } else if (strncmp("BADIP", in, 5) == 0) {
-                                       fprintf(stderr, "Server rejected sender IP address.\n");
-                                       return;
-                               }
+               if (read > 0) {
 
-                               accepted_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
+                       if (strncmp("BADFRAG", in, 7) == 0) {
+                               fprintf(stderr, "Server rejected fragsize. Keeping default.");
+                               return;
+                       } else if (strncmp("BADIP", in, 5) == 0) {
+                               fprintf(stderr, "Server rejected sender IP address.\n");
                                return;
                        }
-               /*XXX END adjust indent 1 tab back*/
+
+                       /* The server returns the accepted fragsize:
+                       accepted_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff) */
+                       return;
+               }
 
                fprintf(stderr, "Retrying set fragsize...\n");
        }
@@ -2435,7 +2387,7 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz
                }
        }
 
-       fprintf(stderr, "Using DNS type %s queries\n", get_qtype());
+       fprintf(stderr, "Using DNS type %s queries\n", client_get_qtype());
 
        r = handshake_version(dns_fd, &seed);
        if (r) {