#7, set max fragsize with -m in the client

This commit is contained in:
Erik Ekman 2009-01-05 19:47:59 +00:00 committed by Erik Ekman
parent d4e077aff4
commit 9ababcaa96
3 changed files with 111 additions and 7 deletions

View file

@ -46,6 +46,18 @@ Server sends:
be encoded with the new codec. be encoded with the new codec.
BADCODEC if not accepted. Client must then revert to Base32 BADCODEC if not accepted. Client must then revert to Base32
Set downstream fragment size:
Client sends:
First byte n or N
Rest encoded with base32:
1 byte userid
2 bytes new downstream fragment size
CMC
Server sends:
2 bytes new downstream fragment size. After this all downstream
payloads will be max (fragsize + 2) bytes long.
BADFRAG if not accepted.
Data: Data:
Upstream data header: Upstream data header:
3210 432 10 43 210 4321 0 3210 432 10 43 210 4321 0

View file

@ -64,7 +64,10 @@ static int downstream_fragment;
static int down_ack_seqno; static int down_ack_seqno;
static int down_ack_fragment; static int down_ack_fragment;
/* Current IP packet */ static int max_downstream_frag_size;
static int autodetect_frag_size;
/* Current up/downstream IP packet */
static struct packet outpkt; static struct packet outpkt;
static struct packet inpkt; static struct packet inpkt;
@ -406,6 +409,22 @@ send_ping(int fd)
send_packet(fd, 'P', data, sizeof(data)); send_packet(fd, 'P', data, sizeof(data));
} }
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) send_version(int fd, uint32_t version)
{ {
@ -612,7 +631,7 @@ perform_case_check:
printf("No reply on case check, continuing\n"); printf("No reply on case check, continuing\n");
switch_codec: switch_codec:
if (!case_preserved) if (!case_preserved)
return 0; goto set_downstream_fragment_size;
dataenc = get_base64_encoder(); dataenc = get_base64_encoder();
printf("Switching to %s codec\n", dataenc->name); printf("Switching to %s codec\n", dataenc->name);
@ -647,7 +666,7 @@ switch_codec:
} }
in[read] = 0; /* zero terminate */ in[read] = 0; /* zero terminate */
printf("Server switched to codec %s\n", in); printf("Server switched to codec %s\n", in);
return 0; goto autodetect_max_fragsize;
} }
} }
printf("Retrying codec switch...\n"); printf("Retrying codec switch...\n");
@ -656,9 +675,49 @@ switch_codec:
codec_revert: codec_revert:
printf("Falling back to base32\n"); printf("Falling back to base32\n");
dataenc = get_base32_encoder(); dataenc = get_base32_encoder();
autodetect_max_fragsize:
if (autodetect_frag_size) {
printf("Autoprobing max downstream fragment size...\n");
/* TODO */
}
set_downstream_fragment_size:
printf("Setting downstream fragment size to max %d...\n", max_downstream_frag_size);
for (i=0; running && i<5 ;i++) {
tv.tv_sec = i + 1;
tv.tv_usec = 0;
send_set_downstream_fragsize(dns_fd, max_downstream_frag_size);
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, in, sizeof(in));
if (read > 0) {
int accepted_fragsize;
if (strncmp("BADFRAG", in, 7) == 0) {
printf("Server rejected fragsize. Keeping default.");
goto done;
} else if (strncmp("BADIP", in, 5) == 0) {
printf("Server rejected sender IP address.\n");
goto done;
}
accepted_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
goto done;
}
}
printf("Retrying set fragsize...\n");
}
printf("No reply from server when setting fragsize. Keeping default.\n");
done:
return 0; return 0;
} }
static char * static char *
get_resolvconf_addr() get_resolvconf_addr()
{ {
@ -705,7 +764,7 @@ usage() {
extern char *__progname; extern char *__progname;
printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] " printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
"[nameserver] topdomain\n", __progname); "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
exit(2); exit(2);
} }
@ -715,7 +774,7 @@ help() {
printf("iodine IP over DNS tunneling client\n"); printf("iodine IP over DNS tunneling client\n");
printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] " printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
"[-P password] [nameserver] topdomain\n", __progname); "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
printf(" -v to print version info and exit\n"); printf(" -v to print version info and exit\n");
printf(" -h to print this help and exit\n"); printf(" -h to print this help and exit\n");
printf(" -f to keep running in foreground\n"); printf(" -f to keep running in foreground\n");
@ -723,6 +782,7 @@ help() {
printf(" -t dir to chroot to directory dir\n"); printf(" -t dir to chroot to directory dir\n");
printf(" -d device to set tunnel device name\n"); printf(" -d device to set tunnel device name\n");
printf(" -P password used for authentication (max 32 chars will be used)\n"); printf(" -P password used for authentication (max 32 chars will be used)\n");
printf(" -m maxfragsize, to limit size of downstream packets\n");
printf("nameserver is the IP number of the relaying nameserver, if absent /etc/resolv.conf is used\n"); printf("nameserver is the IP number of the relaying nameserver, if absent /etc/resolv.conf is used\n");
printf("topdomain is the FQDN that is delegated to the tunnel endpoint.\n"); printf("topdomain is the FQDN that is delegated to the tunnel endpoint.\n");
@ -764,6 +824,9 @@ main(int argc, char **argv)
outpkt.seqno = 0; outpkt.seqno = 0;
inpkt.len = 0; inpkt.len = 0;
autodetect_frag_size = 1;
max_downstream_frag_size = 3072;
b32 = get_base32_encoder(); b32 = get_base32_encoder();
dataenc = get_base32_encoder(); dataenc = get_base32_encoder();
@ -775,7 +838,7 @@ main(int argc, char **argv)
__progname++; __progname++;
#endif #endif
while ((choice = getopt(argc, argv, "vfhu:t:d:P:")) != -1) { while ((choice = getopt(argc, argv, "vfhu:t:d:P:m:")) != -1) {
switch(choice) { switch(choice) {
case 'v': case 'v':
version(); version();
@ -804,6 +867,10 @@ main(int argc, char **argv)
/* XXX: find better way of cleaning up ps(1) */ /* XXX: find better way of cleaning up ps(1) */
memset(optarg, 0, strlen(optarg)); memset(optarg, 0, strlen(optarg));
break; break;
case 'm':
autodetect_frag_size = 0;
max_downstream_frag_size = atoi(optarg);
break;
default: default:
usage(); usage();
/* NOTREACHED */ /* NOTREACHED */
@ -833,6 +900,12 @@ main(int argc, char **argv)
/* NOTREACHED */ /* NOTREACHED */
} }
if (max_downstream_frag_size < 1 || max_downstream_frag_size > 0xffff) {
warnx("Use a max frag size between 1 and 65535 bytes.\n");
usage();
/* NOTREACHED */
}
set_nameserver(nameserv_addr); set_nameserver(nameserv_addr);
if(strlen(topdomain) <= 128) { if(strlen(topdomain) <= 128) {

View file

@ -377,6 +377,25 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
break; break;
} }
return; return;
} else if(in[0] == 'N' || in[0] == 'n') {
int max_frag_size;
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32);
/* Downstream fragsize packet */
userid = unpacked[0];
if (userid < 0 || userid >= USERS || ip_cmp(userid, q) != 0) {
write_dns(dns_fd, q, "BADIP", 5);
return; /* illegal id */
}
max_frag_size = ((unpacked[1] & 0xff) << 8) | (unpacked[2] & 0xff);
if (max_frag_size < 1) {
write_dns(dns_fd, q, "BADFRAG", 7);
} else {
users[userid].fragsize = max_frag_size;
write_dns(dns_fd, q, &unpacked[1], 2);
}
return;
} else if(in[0] == 'P' || in[0] == 'p') { } else if(in[0] == 'P' || in[0] == 'p') {
int dn_seq; int dn_seq;
int dn_frag; int dn_frag;