mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-22 14:41:28 +00:00
update client code #75
This commit is contained in:
parent
90e25e3a2c
commit
2c2dd6f06e
350
src/client.c
350
src/client.c
|
@ -14,6 +14,7 @@
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -75,13 +76,21 @@ static char userid;
|
||||||
/* DNS id for next packet */
|
/* DNS id for next packet */
|
||||||
static uint16_t chunkid;
|
static uint16_t chunkid;
|
||||||
|
|
||||||
/* Base32 encoder used for non-data packets */
|
/* Base32 encoder used for non-data packets and replies */
|
||||||
static struct encoder *b32;
|
static struct encoder *b32;
|
||||||
|
/* Base64 encoder for replies */
|
||||||
|
static struct encoder *b64;
|
||||||
|
|
||||||
/* The encoder used for data packets
|
/* The encoder used for data packets
|
||||||
* Defaults to Base32, can be changed after handshake */
|
* Defaults to Base32, can be changed after handshake */
|
||||||
static struct encoder *dataenc;
|
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_NULL;
|
||||||
|
|
||||||
/* My connection mode */
|
/* My connection mode */
|
||||||
static enum connection conn;
|
static enum connection conn;
|
||||||
|
|
||||||
|
@ -95,10 +104,11 @@ client_init()
|
||||||
downstream_fragment = 0;
|
downstream_fragment = 0;
|
||||||
down_ack_seqno = 0;
|
down_ack_seqno = 0;
|
||||||
down_ack_fragment = 0;
|
down_ack_fragment = 0;
|
||||||
chunkid = 0;
|
chunkid = ((unsigned int) rand()) & 0xFFFF;
|
||||||
b32 = get_base32_encoder();
|
b32 = get_base32_encoder();
|
||||||
|
b64 = get_base64_encoder();
|
||||||
dataenc = get_base32_encoder();
|
dataenc = get_base32_encoder();
|
||||||
rand_seed = rand();
|
rand_seed = ((unsigned int) rand()) & 0xFFFF;
|
||||||
conn = CONN_DNS_NULL;
|
conn = CONN_DNS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +150,32 @@ client_set_password(const char *cp)
|
||||||
password = cp;
|
password = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_qtype(char *qtype)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(qtype, "NULL"))
|
||||||
|
do_qtype = T_NULL;
|
||||||
|
else if (!strcasecmp(qtype, "CNAME"))
|
||||||
|
do_qtype = T_CNAME;
|
||||||
|
else if (!strcasecmp(qtype, "A"))
|
||||||
|
do_qtype = T_A;
|
||||||
|
else if (!strcasecmp(qtype, "MX"))
|
||||||
|
do_qtype = T_MX;
|
||||||
|
else if (!strcasecmp(qtype, "TXT"))
|
||||||
|
do_qtype = T_TXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_downenc(char *encoding)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(encoding, "base32"))
|
||||||
|
downenc = 'T';
|
||||||
|
else if (!strcasecmp(encoding, "base64"))
|
||||||
|
downenc = 'S';
|
||||||
|
else if (!strcasecmp(encoding, "raw"))
|
||||||
|
downenc = 'R';
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
client_get_raw_addr()
|
client_get_raw_addr()
|
||||||
{
|
{
|
||||||
|
@ -153,10 +189,19 @@ send_query(int fd, char *hostname)
|
||||||
struct query q;
|
struct query q;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
q.id = ++chunkid;
|
chunkid += 7727;
|
||||||
q.type = T_NULL;
|
if (chunkid == 0)
|
||||||
|
/* 0 is used as "no-query" in iodined.c */
|
||||||
|
chunkid = 7727;
|
||||||
|
|
||||||
|
q.id = chunkid;
|
||||||
|
q.type = do_qtype;
|
||||||
|
|
||||||
len = dns_encode(packet, sizeof(packet), &q, QR_QUERY, hostname, strlen(hostname));
|
len = dns_encode(packet, sizeof(packet), &q, QR_QUERY, hostname, strlen(hostname));
|
||||||
|
if (len < 1) {
|
||||||
|
warnx("dns_encode doesn't fit");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv));
|
sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv));
|
||||||
}
|
}
|
||||||
|
@ -207,7 +252,7 @@ is_sending()
|
||||||
static void
|
static void
|
||||||
send_chunk(int fd)
|
send_chunk(int fd)
|
||||||
{
|
{
|
||||||
char hex[] = "0123456789ABCDEF";
|
char hex[] = "0123456789abcdef";
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
int avail;
|
int avail;
|
||||||
int code;
|
int code;
|
||||||
|
@ -261,7 +306,7 @@ send_ping(int fd)
|
||||||
|
|
||||||
rand_seed++;
|
rand_seed++;
|
||||||
|
|
||||||
send_packet(fd, 'P', data, sizeof(data));
|
send_packet(fd, 'p', data, sizeof(data));
|
||||||
} else {
|
} else {
|
||||||
send_raw(fd, NULL, 0, userid, RAW_HDR_CMD_PING);
|
send_raw(fd, NULL, 0, userid, RAW_HDR_CMD_PING);
|
||||||
}
|
}
|
||||||
|
@ -288,6 +333,88 @@ read_dns(int dns_fd, int tun_fd, char *buf, int buflen) /* FIXME: tun_fd needed
|
||||||
|
|
||||||
rv = dns_decode(buf, buflen, &q, QR_ANSWER, data, r);
|
rv = dns_decode(buf, buflen, &q, QR_ANSWER, data, r);
|
||||||
|
|
||||||
|
if ((q.type == T_CNAME || q.type == T_MX || q.type == T_TXT)
|
||||||
|
&& rv >= 1)
|
||||||
|
/* CNAME an also be returned from an A (or MX) question */
|
||||||
|
{
|
||||||
|
size_t space;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (buf[0]) {
|
||||||
|
case 'h': /* Hostname with base32 */
|
||||||
|
case 'H':
|
||||||
|
if (rv < 5) {
|
||||||
|
/* 1 byte H, 3 bytes ".xy", >=1 byte data */
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv -= 3; /* rv=strlen, strip ".xy" */
|
||||||
|
rv = unpack_data (data, sizeof(data), buf + 1, rv - 1, b32);
|
||||||
|
/* this also does undotify */
|
||||||
|
|
||||||
|
rv = MIN(rv, buflen);
|
||||||
|
memcpy(buf, data, rv);
|
||||||
|
break;
|
||||||
|
case 'i': /* Hostname++ with base64 */
|
||||||
|
case 'I':
|
||||||
|
if (rv < 5) {
|
||||||
|
/* 1 byte H, 3 bytes ".xy", >=1 byte data */
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv -= 3; /* rv=strlen, strip ".xy" */
|
||||||
|
rv = unpack_data (data, sizeof(data), buf + 1, rv - 1, b64);
|
||||||
|
/* this also does undotify */
|
||||||
|
|
||||||
|
rv = MIN(rv, buflen);
|
||||||
|
memcpy(buf, data, rv);
|
||||||
|
break;
|
||||||
|
case 't': /* plain base32(Thirty-two) from TXT */
|
||||||
|
case 'T':
|
||||||
|
if (rv < 2) {
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
space = sizeof(data);
|
||||||
|
rv = b32->decode (data, &space, buf + 1, rv - 1);
|
||||||
|
rv = MIN(rv, buflen);
|
||||||
|
memcpy(buf, data, rv);
|
||||||
|
break;
|
||||||
|
case 's': /* plain base64(Sixty-four) from TXT */
|
||||||
|
case 'S':
|
||||||
|
if (rv < 2) {
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
space = sizeof(data);
|
||||||
|
rv = b64->decode (data, &space, buf + 1, rv - 1);
|
||||||
|
rv = MIN(rv, buflen);
|
||||||
|
memcpy(buf, data, rv);
|
||||||
|
break;
|
||||||
|
case 'r': /* Raw binary from TXT */
|
||||||
|
case 'R':
|
||||||
|
rv--; /* rv>=1 already checked */
|
||||||
|
memmove(buf, buf+1, rv);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warnx("Received unsupported encoding");
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* decode the data header, update seqno and frag before next request */
|
/* decode the data header, update seqno and frag before next request */
|
||||||
if (rv >= 2) {
|
if (rv >= 2) {
|
||||||
downstream_seqno = (buf[1] >> 5) & 7;
|
downstream_seqno = (buf[1] >> 5) & 7;
|
||||||
|
@ -487,7 +614,7 @@ send_login(int fd, char *login, int len)
|
||||||
|
|
||||||
rand_seed++;
|
rand_seed++;
|
||||||
|
|
||||||
send_packet(fd, 'L', data, sizeof(data));
|
send_packet(fd, 'l', data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -496,9 +623,12 @@ send_fragsize_probe(int fd, int fragsize)
|
||||||
char probedata[256];
|
char probedata[256];
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
|
|
||||||
/* build a large query domain which is random and maximum size */
|
/*
|
||||||
memset(probedata, MIN(1, rand_seed & 0xff), sizeof(probedata));
|
* build a large query domain which is random and maximum size,
|
||||||
probedata[1] = MIN(1, (rand_seed >> 8) & 0xff);
|
* will also take up maximal space in the return packet
|
||||||
|
*/
|
||||||
|
memset(probedata, MAX(1, rand_seed & 0xff), sizeof(probedata));
|
||||||
|
probedata[1] = MAX(1, (rand_seed >> 8) & 0xff);
|
||||||
rand_seed++;
|
rand_seed++;
|
||||||
build_hostname(buf + 4, sizeof(buf) - 4, probedata, sizeof(probedata), topdomain, dataenc);
|
build_hostname(buf + 4, sizeof(buf) - 4, probedata, sizeof(probedata), topdomain, dataenc);
|
||||||
|
|
||||||
|
@ -525,7 +655,7 @@ send_set_downstream_fragsize(int fd, int fragsize)
|
||||||
|
|
||||||
rand_seed++;
|
rand_seed++;
|
||||||
|
|
||||||
send_packet(fd, 'N', data, sizeof(data));
|
send_packet(fd, 'n', data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -585,7 +715,7 @@ send_case_check(int fd)
|
||||||
static void
|
static void
|
||||||
send_codec_switch(int fd, int userid, int bits)
|
send_codec_switch(int fd, int userid, int bits)
|
||||||
{
|
{
|
||||||
char buf[512] = "S_____.";
|
char buf[512] = "s_____.";
|
||||||
buf[1] = b32_5to8(userid);
|
buf[1] = b32_5to8(userid);
|
||||||
buf[2] = b32_5to8(bits);
|
buf[2] = b32_5to8(bits);
|
||||||
|
|
||||||
|
@ -598,6 +728,23 @@ send_codec_switch(int fd, int userid, int bits)
|
||||||
send_query(fd, buf);
|
send_query(fd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_downenc_switch(int fd, int userid)
|
||||||
|
{
|
||||||
|
char buf[512] = "o_____.";
|
||||||
|
buf[1] = b32_5to8(userid);
|
||||||
|
buf[2] = tolower(downenc);
|
||||||
|
|
||||||
|
buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
|
||||||
|
buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
|
||||||
|
buf[5] = b32_5to8((rand_seed ) & 0x1f);
|
||||||
|
rand_seed++;
|
||||||
|
|
||||||
|
strncat(buf, topdomain, 512 - strlen(buf));
|
||||||
|
send_query(fd, buf);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_version(int dns_fd, int *seed)
|
handshake_version(int dns_fd, int *seed)
|
||||||
{
|
{
|
||||||
|
@ -657,7 +804,7 @@ handshake_version(int dns_fd, int *seed)
|
||||||
|
|
||||||
fprintf(stderr, "Retrying version check...\n");
|
fprintf(stderr, "Retrying version check...\n");
|
||||||
}
|
}
|
||||||
warnx("couldn't connect to server");
|
warnx("couldn't connect to server (maybe other -T options will work)");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,7 +1038,7 @@ handshake_switch_codec(int dns_fd)
|
||||||
int read;
|
int read;
|
||||||
|
|
||||||
dataenc = get_base64_encoder();
|
dataenc = get_base64_encoder();
|
||||||
fprintf(stderr, "Switching to %s codec\n", dataenc->name);
|
fprintf(stderr, "Switching upstream to %s codec\n", dataenc->name);
|
||||||
/* Send to server that this user will use base64 from now on */
|
/* Send to server that this user will use base64 from now on */
|
||||||
for (i=0; running && i<5 ;i++) {
|
for (i=0; running && i<5 ;i++) {
|
||||||
int bits;
|
int bits;
|
||||||
|
@ -922,7 +1069,7 @@ handshake_switch_codec(int dns_fd)
|
||||||
goto codec_revert;
|
goto codec_revert;
|
||||||
}
|
}
|
||||||
in[read] = 0; /* zero terminate */
|
in[read] = 0; /* zero terminate */
|
||||||
fprintf(stderr, "Server switched to codec %s\n", in);
|
fprintf(stderr, "Server switched upstream to codec %s\n", in);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -935,6 +1082,138 @@ codec_revert:
|
||||||
dataenc = get_base32_encoder();
|
dataenc = get_base32_encoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handshake_switch_downenc(int dns_fd)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
char in[4096];
|
||||||
|
fd_set fds;
|
||||||
|
int i;
|
||||||
|
int r;
|
||||||
|
int read;
|
||||||
|
char *dname;
|
||||||
|
|
||||||
|
dname = "Base32";
|
||||||
|
if (downenc == 'S')
|
||||||
|
dname = "Base64";
|
||||||
|
else if (downenc == 'R')
|
||||||
|
dname = "Raw";
|
||||||
|
|
||||||
|
fprintf(stderr, "Switching downstream to codec %s\n", dname);
|
||||||
|
for (i=0; running && i<5 ;i++) {
|
||||||
|
tv.tv_sec = i + 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
send_downenc_switch(dns_fd, userid);
|
||||||
|
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(dns_fd, &fds);
|
||||||
|
|
||||||
|
r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
if(r > 0) {
|
||||||
|
read = read_dns(dns_fd, 0, in, sizeof(in));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Retrying codec switch...\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "No reply from server on codec switch. ");
|
||||||
|
|
||||||
|
codec_revert:
|
||||||
|
fprintf(stderr, "Falling back to base32\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
fragsize_check(char *in, int read, int proposed_fragsize, int *max_fragsize)
|
||||||
|
/* Returns: 0: keep checking, 1: break loop (either okay or definitely wrong) */
|
||||||
|
{
|
||||||
|
int acked_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
|
||||||
|
static int nocheck_warned = 0;
|
||||||
|
|
||||||
|
if (read >= 5 && strncmp("BADIP", in, 5) == 0) {
|
||||||
|
fprintf(stderr, "got BADIP (Try iodined -c)..\n");
|
||||||
|
fflush(stderr);
|
||||||
|
return 0; /* maybe temporary error */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acked_fragsize != proposed_fragsize) {
|
||||||
|
/*
|
||||||
|
* got ack for wrong fragsize, maybe late response for
|
||||||
|
* earlier query, or ack corrupted
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read != proposed_fragsize) {
|
||||||
|
/*
|
||||||
|
* correctly acked fragsize but read too little (or too
|
||||||
|
* much): this fragsize is definitely not reliable
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* here: read == proposed_fragsize == acked_fragsize */
|
||||||
|
|
||||||
|
/* test: */
|
||||||
|
/* in[123] = 123; */
|
||||||
|
|
||||||
|
/* Check for corruption */
|
||||||
|
if ((in[2] & 0xff) == 107) {
|
||||||
|
int okay = 1;
|
||||||
|
int i;
|
||||||
|
unsigned int v = in[3] & 0xff;
|
||||||
|
|
||||||
|
for (i = 3; i < read; i++, v += 107)
|
||||||
|
if ((in[i] & 0xff) != (v & 0xff)) {
|
||||||
|
okay = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
fprintf(stderr, "%d corrupted at %d.. ", acked_fragsize, i);
|
||||||
|
fflush(stderr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} /* always returns */
|
||||||
|
|
||||||
|
/* here when uncheckable, so assume correct */
|
||||||
|
|
||||||
|
if (read >= 3 && nocheck_warned == 0) {
|
||||||
|
fprintf(stderr, "(Old server version, cannot check for corruption)\n");
|
||||||
|
fflush(stderr);
|
||||||
|
nocheck_warned = 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%d ok.. ", acked_fragsize);
|
||||||
|
fflush(stderr);
|
||||||
|
*max_fragsize = acked_fragsize;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_autoprobe_fragsize(int dns_fd)
|
handshake_autoprobe_fragsize(int dns_fd)
|
||||||
{
|
{
|
||||||
|
@ -946,11 +1225,12 @@ handshake_autoprobe_fragsize(int dns_fd)
|
||||||
int read;
|
int read;
|
||||||
int proposed_fragsize = 768;
|
int proposed_fragsize = 768;
|
||||||
int range = 768;
|
int range = 768;
|
||||||
int max_fragsize = 0;
|
int max_fragsize;
|
||||||
|
|
||||||
max_fragsize = 0;
|
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)) {
|
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++) {
|
for (i=0; running && i<3 ;i++) {
|
||||||
tv.tv_sec = 1;
|
tv.tv_sec = 1;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
@ -961,23 +1241,12 @@ handshake_autoprobe_fragsize(int dns_fd)
|
||||||
|
|
||||||
r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
|
r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
if(r > 0) {
|
if(r >= 2) {
|
||||||
read = read_dns(dns_fd, 0, in, sizeof(in));
|
read = read_dns(dns_fd, 0, in, sizeof(in));
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
/* We got a reply */
|
/* We got a reply */
|
||||||
int acked_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
|
if (fragsize_check(in, read, proposed_fragsize, &max_fragsize) == 1)
|
||||||
if (acked_fragsize == proposed_fragsize) {
|
|
||||||
if (read == proposed_fragsize) {
|
|
||||||
fprintf(stderr, "%d ok.. ", acked_fragsize);
|
|
||||||
fflush(stderr);
|
|
||||||
max_fragsize = acked_fragsize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (strncmp("BADIP", in, 5) == 0) {
|
|
||||||
fprintf(stderr, "got BADIP.. ");
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -997,17 +1266,22 @@ handshake_autoprobe_fragsize(int dns_fd)
|
||||||
}
|
}
|
||||||
if (!running) {
|
if (!running) {
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
warnx("stopped while autodetecting fragment size (Try probing manually with -m)");
|
warnx("stopped while autodetecting fragment size (Try setting manually with -m)");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (range == 0) {
|
if (max_fragsize <= 2) {
|
||||||
/* Tried all the way down to 2 and found no good size */
|
/* Tried all the way down to 2 and found no good size */
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
warnx("found no accepted fragment size. (Try probing manually with -m)");
|
warnx("found no accepted fragment size. (Try forcing with -m, or try other -T or -O options)");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "will use %d\n", max_fragsize);
|
/* data header adds 2 bytes */
|
||||||
return max_fragsize;
|
fprintf(stderr, "will use %d-2=%d\n", max_fragsize, max_fragsize - 2);
|
||||||
|
|
||||||
|
if (do_qtype != T_NULL && downenc == ' ')
|
||||||
|
fprintf(stderr, "(Maybe other -O options will increase throughput)\n");
|
||||||
|
|
||||||
|
return max_fragsize - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1084,6 +1358,10 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz
|
||||||
handshake_switch_codec(dns_fd);
|
handshake_switch_codec(dns_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (downenc != ' ') {
|
||||||
|
handshake_switch_downenc(dns_fd);
|
||||||
|
}
|
||||||
|
|
||||||
if (autodetect_frag_size) {
|
if (autodetect_frag_size) {
|
||||||
fragsize = handshake_autoprobe_fragsize(dns_fd);
|
fragsize = handshake_autoprobe_fragsize(dns_fd);
|
||||||
if (!fragsize) {
|
if (!fragsize) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ get_resolvconf_addr()
|
||||||
rv = NULL;
|
rv = NULL;
|
||||||
|
|
||||||
if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
|
if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
|
||||||
err(1, "/etc/resolve.conf");
|
err(1, "/etc/resolv.conf");
|
||||||
|
|
||||||
while (feof(fp) == 0) {
|
while (feof(fp) == 0) {
|
||||||
fgets(buf, sizeof(buf), fp);
|
fgets(buf, sizeof(buf), fp);
|
||||||
|
|
Loading…
Reference in a new issue