mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-21 23:59:19 +02:00
#7, set max fragsize with -m in the client
This commit is contained in:
parent
d4e077aff4
commit
9ababcaa96
|
@ -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
|
||||||
|
|
87
src/iodine.c
87
src/iodine.c
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue