mirror of
https://github.com/yarrick/iodine.git
synced 2024-12-22 13:23:32 +02:00
#7, set max fragsize with -m in the client
This commit is contained in:
parent
d4e077aff4
commit
9ababcaa96
3 changed files with 111 additions and 7 deletions
|
@ -46,6 +46,18 @@ Server sends:
|
|||
be encoded with the new codec.
|
||||
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:
|
||||
Upstream data header:
|
||||
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_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 inpkt;
|
||||
|
||||
|
@ -406,6 +409,22 @@ send_ping(int fd)
|
|||
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
|
||||
send_version(int fd, uint32_t version)
|
||||
{
|
||||
|
@ -612,7 +631,7 @@ perform_case_check:
|
|||
printf("No reply on case check, continuing\n");
|
||||
switch_codec:
|
||||
if (!case_preserved)
|
||||
return 0;
|
||||
goto set_downstream_fragment_size;
|
||||
|
||||
dataenc = get_base64_encoder();
|
||||
printf("Switching to %s codec\n", dataenc->name);
|
||||
|
@ -647,7 +666,7 @@ switch_codec:
|
|||
}
|
||||
in[read] = 0; /* zero terminate */
|
||||
printf("Server switched to codec %s\n", in);
|
||||
return 0;
|
||||
goto autodetect_max_fragsize;
|
||||
}
|
||||
}
|
||||
printf("Retrying codec switch...\n");
|
||||
|
@ -656,9 +675,49 @@ switch_codec:
|
|||
codec_revert:
|
||||
printf("Falling back to base32\n");
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
get_resolvconf_addr()
|
||||
{
|
||||
|
@ -705,7 +764,7 @@ usage() {
|
|||
extern char *__progname;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -715,7 +774,7 @@ help() {
|
|||
|
||||
printf("iodine IP over DNS tunneling client\n");
|
||||
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(" -h to print this help and exit\n");
|
||||
printf(" -f to keep running in foreground\n");
|
||||
|
@ -723,6 +782,7 @@ help() {
|
|||
printf(" -t dir to chroot to directory dir\n");
|
||||
printf(" -d device to set tunnel device name\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("topdomain is the FQDN that is delegated to the tunnel endpoint.\n");
|
||||
|
||||
|
@ -764,6 +824,9 @@ main(int argc, char **argv)
|
|||
outpkt.seqno = 0;
|
||||
inpkt.len = 0;
|
||||
|
||||
autodetect_frag_size = 1;
|
||||
max_downstream_frag_size = 3072;
|
||||
|
||||
b32 = get_base32_encoder();
|
||||
dataenc = get_base32_encoder();
|
||||
|
||||
|
@ -775,7 +838,7 @@ main(int argc, char **argv)
|
|||
__progname++;
|
||||
#endif
|
||||
|
||||
while ((choice = getopt(argc, argv, "vfhu:t:d:P:")) != -1) {
|
||||
while ((choice = getopt(argc, argv, "vfhu:t:d:P:m:")) != -1) {
|
||||
switch(choice) {
|
||||
case 'v':
|
||||
version();
|
||||
|
@ -804,6 +867,10 @@ main(int argc, char **argv)
|
|||
/* XXX: find better way of cleaning up ps(1) */
|
||||
memset(optarg, 0, strlen(optarg));
|
||||
break;
|
||||
case 'm':
|
||||
autodetect_frag_size = 0;
|
||||
max_downstream_frag_size = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
|
@ -833,6 +900,12 @@ main(int argc, char **argv)
|
|||
/* 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);
|
||||
|
||||
if(strlen(topdomain) <= 128) {
|
||||
|
|
|
@ -377,6 +377,25 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
|||
break;
|
||||
}
|
||||
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') {
|
||||
int dn_seq;
|
||||
int dn_frag;
|
||||
|
|
Loading…
Reference in a new issue