base encoder: simplify structures

We don't need complex getters. Just expose basic operations as they are.

Signed-off-by: Ralf Ramsauer <ralf@ramses-pyramidenbau.de>
This commit is contained in:
Ralf Ramsauer 2017-03-11 15:04:26 -08:00
parent d05923d2b1
commit b517121f1c
8 changed files with 86 additions and 133 deletions

View File

@ -52,28 +52,6 @@ static const unsigned char cb128[] =
static unsigned char rev128[256];
static int reverse_init = 0;
static int base128_encode(char *, size_t *, const void *, size_t);
static int base128_decode(void *, size_t *, const char *, size_t);
static int base128_handles_dots(void);
static int base128_blksize_raw(void);
static int base128_blksize_enc(void);
static struct encoder base128_encoder =
{
"Base128",
base128_encode,
base128_decode,
base128_handles_dots,
base128_handles_dots,
base128_blksize_raw,
base128_blksize_enc
};
struct encoder *get_base128_encoder(void)
{
return &base128_encoder;
}
static int base128_handles_dots(void)
{
return 0;
@ -284,3 +262,16 @@ static int base128_decode(void *buf, size_t *buflen, const char *str,
return iout;
}
const struct encoder base128_ops = {
.name = "Base128",
.encode = base128_encode,
.decode = base128_decode,
.places_dots = base128_handles_dots,
.eats_dots = base128_handles_dots,
.blocksize_raw = base128_blksize_raw,
.blocksize_encoded = base128_blksize_enc
};

View File

@ -17,6 +17,6 @@
#ifndef __BASE128_H__
#define __BASE128_H__
struct encoder *get_base128_encoder(void);
const struct encoder base128_ops;
#endif

View File

@ -33,28 +33,6 @@ static const char cb32_ucase[] =
static unsigned char rev32[256];
static int reverse_init = 0;
static int base32_encode(char *, size_t *, const void *, size_t);
static int base32_decode(void *, size_t *, const char *, size_t);
static int base32_handles_dots(void);
static int base32_blksize_raw(void);
static int base32_blksize_enc(void);
static struct encoder base32_encoder =
{
"Base32",
base32_encode,
base32_decode,
base32_handles_dots,
base32_handles_dots,
base32_blksize_raw,
base32_blksize_enc
};
struct encoder *get_base32_encoder(void)
{
return &base32_encoder;
}
static int base32_handles_dots(void)
{
return 0;
@ -261,3 +239,16 @@ static int base32_decode(void *buf, size_t *buflen, const char *str,
return iout;
}
const struct encoder base32_ops = {
.name = "Base32",
.encode = base32_encode,
.decode = base32_decode,
.places_dots = base32_handles_dots,
.eats_dots = base32_handles_dots,
.blocksize_raw = base32_blksize_raw,
.blocksize_encoded = base32_blksize_enc,
};

View File

@ -18,8 +18,8 @@
#ifndef __BASE32_H__
#define __BASE32_H__
struct encoder *get_base32_encoder(void);
int b32_5to8(int);
int b32_8to5(int);
extern const struct encoder base32_ops;
#endif

View File

@ -33,28 +33,6 @@ static const char cb64[] =
static unsigned char rev64[256];
static int reverse_init = 0;
static int base64_encode(char *, size_t *, const void *, size_t);
static int base64_decode(void *, size_t *, const char *, size_t);
static int base64_handles_dots(void);
static int base64_blksize_raw(void);
static int base64_blksize_enc(void);
static struct encoder base64_encoder =
{
"Base64",
base64_encode,
base64_decode,
base64_handles_dots,
base64_handles_dots,
base64_blksize_raw,
base64_blksize_enc
};
struct encoder *get_base64_encoder(void)
{
return &base64_encoder;
}
static int base64_handles_dots(void)
{
return 0;
@ -199,3 +177,16 @@ static int base64_decode(void *buf, size_t *buflen, const char *str,
return iout;
}
const struct encoder base64_ops = {
.name = "Base64",
.encode = base64_encode,
.decode = base64_decode,
.places_dots = base64_handles_dots,
.eats_dots = base64_handles_dots,
.blocksize_raw = base64_blksize_raw,
.blocksize_encoded = base64_blksize_enc,
};

View File

@ -18,6 +18,6 @@
#ifndef __BASE64_H__
#define __BASE64_H__
struct encoder *get_base64_encoder(void);
extern const struct encoder base64_ops;
#endif

View File

@ -85,16 +85,9 @@ static uint16_t chunkid;
static uint16_t chunkid_prev;
static uint16_t chunkid_prev2;
/* Base32 encoder used for non-data packets and replies */
static struct encoder *b32;
/* Base64 etc encoders for replies */
static struct encoder *b64;
static struct encoder *b64u;
static struct encoder *b128;
/* The encoder used for data packets
* Defaults to Base32, can be changed after handshake */
static struct encoder *dataenc;
const static struct encoder *dataenc = &base32_ops;
/* The encoder to use for downstream data */
static char downenc = ' ';
@ -117,11 +110,6 @@ void
client_init()
{
running = 1;
b32 = get_base32_encoder();
b64 = get_base64_encoder();
b64u = get_base64u_encoder();
b128 = get_base128_encoder();
dataenc = get_base32_encoder();
rand_seed = ((unsigned int) rand()) & 0xFFFF;
send_ping_soon = 1; /* send ping immediately after startup */
conn = CONN_DNS_NULL;
@ -342,7 +330,7 @@ send_packet(int fd, char cmd, const char *data, const size_t datalen)
buf[0] = cmd;
build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain,
b32, hostname_maxlen);
&base32_ops, hostname_maxlen);
send_query(fd, buf);
}
@ -480,7 +468,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
/* this also does undotify */
return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
b32);
&base32_ops);
case 'i': /* Hostname++ with base64 */
case 'I':
@ -490,7 +478,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
/* this also does undotify */
return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
b64);
&base64_ops);
case 'j': /* Hostname++ with base64u */
case 'J':
@ -500,7 +488,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
/* this also does undotify */
return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
b64u);
&base64u_ops);
case 'k': /* Hostname++ with base128 */
case 'K':
@ -510,35 +498,35 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
/* this also does undotify */
return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
b128);
&base128_ops);
case 't': /* plain base32(Thirty-two) from TXT */
case 'T':
if (buflen < 2)
return 0;
return b32->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
return base32_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
case 's': /* plain base64(Sixty-four) from TXT */
case 'S':
if (buflen < 2)
return 0;
return b64->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
return base64_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
case 'u': /* plain base64u (Underscore) from TXT */
case 'U':
if (buflen < 2)
return 0;
return b64u->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
return base64_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
case 'v': /* plain base128 from TXT */
case 'V':
if (buflen < 2)
return 0;
return b128->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
return base128_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
case 'r': /* Raw binary from TXT */
case 'R':
@ -2020,16 +2008,16 @@ handshake_switch_codec(int dns_fd, int bits)
char in[4096];
int i;
int read;
struct encoder *tempenc;
const struct encoder *tempenc;
if (bits == 5)
tempenc = get_base32_encoder();
tempenc = &base32_ops;
else if (bits == 6)
tempenc = get_base64_encoder();
tempenc = &base64_ops;
else if (bits == 26) /* "2nd" 6 bits per byte, with underscore */
tempenc = get_base64u_encoder();
tempenc = &base64u_ops;
else if (bits == 7)
tempenc = get_base128_encoder();
tempenc = &base128_ops;
else return;
fprintf(stderr, "Switching upstream to codec %s\n", tempenc->name);

View File

@ -87,10 +87,6 @@ WSADATA wsa_data;
static int running = 1;
static char *topdomain;
static char password[33];
static struct encoder *b32;
static struct encoder *b64;
static struct encoder *b64u;
static struct encoder *b128;
static int created_users;
static int check_ip;
@ -478,7 +474,7 @@ static inline void save_to_qmem_pingordata(int userid, struct query *q)
/* We already unpacked in handle_null_request(), but that's
lost now... Note: b32 directly, we want no undotify here! */
i = b32->decode(cmc, &cmcsize, q->name + 1, (cp - q->name) - 1);
i = base32_ops.decode(cmc, &cmcsize, q->name + 1, (cp - q->name) - 1);
if (i < 4)
return; /* illegal ping; shouldn't happen */
@ -796,7 +792,7 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
if(in[0] == 'V' || in[0] == 'v') {
int version = 0;
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32);
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, &base32_ops);
/* Version greeting, compare and send ack/nak */
if (read > 4) {
/* Received V + 32bits version */
@ -817,7 +813,7 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
users[userid].hostlen = q->fromlen;
memcpy(&(users[userid].q), q, sizeof(struct query));
users[userid].encoder = get_base32_encoder();
users[userid].encoder = &base32_ops;
users[userid].downenc = 'T';
send_version_response(dns_fd, VERSION_ACK, users[userid].seed, userid, q);
syslog(LOG_INFO, "accepted version for user #%d from %s",
@ -872,7 +868,7 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
}
return;
} else if(in[0] == 'L' || in[0] == 'l') {
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32);
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, &base32_ops);
if (read < 17) {
write_dns(dns_fd, q, "BADLEN", 6, 'T');
return;
@ -954,7 +950,8 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
return;
} else if(in[0] == 'S' || in[0] == 's') {
int codec;
struct encoder *enc;
const struct encoder *enc;
if (domain_len < 3) { /* len at least 3, example: "S15" */
write_dns(dns_fd, q, "BADLEN", 6, 'T');
return;
@ -971,22 +968,22 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
switch (codec) {
case 5: /* 5 bits per byte = base32 */
enc = get_base32_encoder();
enc = &base32_ops;
user_switch_codec(userid, enc);
write_dns(dns_fd, q, enc->name, strlen(enc->name), users[userid].downenc);
break;
case 6: /* 6 bits per byte = base64 */
enc = get_base64_encoder();
enc = &base64_ops;
user_switch_codec(userid, enc);
write_dns(dns_fd, q, enc->name, strlen(enc->name), users[userid].downenc);
break;
case 26: /* "2nd" 6 bits per byte = base64u, with underscore */
enc = get_base64u_encoder();
enc = &base64u_ops;
user_switch_codec(userid, enc);
write_dns(dns_fd, q, enc->name, strlen(enc->name), users[userid].downenc);
break;
case 7: /* 7 bits per byte = base128 */
enc = get_base128_encoder();
enc = &base128_ops;
user_switch_codec(userid, enc);
write_dns(dns_fd, q, enc->name, strlen(enc->name), users[userid].downenc);
break;
@ -1157,7 +1154,7 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
} else if(in[0] == 'N' || in[0] == 'n') {
int max_frag_size;
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32);
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, &base32_ops);
if (read < 3) {
write_dns(dns_fd, q, "BADLEN", 6, 'T');
@ -1193,7 +1190,7 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
if (q->id == 0)
return;
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32);
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, &base32_ops);
if (read < 4)
return;
@ -2143,31 +2140,31 @@ write_dns_nameenc(char *buf, size_t buflen, const char *data, int datalen, char
if (downenc == 'S') {
buf[0] = 'i';
if (!b64->places_dots())
if (!base64_ops.places_dots())
space -= (space / 57); /* space for dots */
b64->encode(buf+1, &space, data, datalen);
if (!b64->places_dots())
base64_ops.encode(buf+1, &space, data, datalen);
if (!base64_ops.places_dots())
inline_dotify(buf, buflen);
} else if (downenc == 'U') {
buf[0] = 'j';
if (!b64u->places_dots())
if (!base64u_ops.places_dots())
space -= (space / 57); /* space for dots */
b64u->encode(buf+1, &space, data, datalen);
if (!b64u->places_dots())
base64u_ops.encode(buf+1, &space, data, datalen);
if (!base64u_ops.places_dots())
inline_dotify(buf, buflen);
} else if (downenc == 'V') {
buf[0] = 'k';
if (!b128->places_dots())
if (!base128_ops.places_dots())
space -= (space / 57); /* space for dots */
b128->encode(buf+1, &space, data, datalen);
if (!b128->places_dots())
base128_ops.encode(buf+1, &space, data, datalen);
if (!base128_ops.places_dots())
inline_dotify(buf, buflen);
} else {
buf[0] = 'h';
if (!b32->places_dots())
if (!base32_ops.places_dots())
space -= (space / 57); /* space for dots */
b32->encode(buf+1, &space, data, datalen);
if (!b32->places_dots())
base32_ops.encode(buf+1, &space, data, datalen);
if (!base32_ops.places_dots())
inline_dotify(buf, buflen);
}
@ -2238,15 +2235,15 @@ write_dns(int fd, struct query *q, const char *data, int datalen, char downenc)
if (downenc == 'S') {
txtbuf[0] = 's'; /* plain base64(Sixty-four) */
len = b64->encode(txtbuf+1, &space, data, datalen);
len = base64_ops.encode(txtbuf+1, &space, data, datalen);
}
else if (downenc == 'U') {
txtbuf[0] = 'u'; /* Base64 with Underscore */
len = b64u->encode(txtbuf+1, &space, data, datalen);
len = base64u_ops.encode(txtbuf+1, &space, data, datalen);
}
else if (downenc == 'V') {
txtbuf[0] = 'v'; /* Base128 */
len = b128->encode(txtbuf+1, &space, data, datalen);
len = base128_ops.encode(txtbuf+1, &space, data, datalen);
}
else if (downenc == 'R') {
txtbuf[0] = 'r'; /* Raw binary data */
@ -2254,7 +2251,7 @@ write_dns(int fd, struct query *q, const char *data, int datalen, char downenc)
memcpy(txtbuf + 1, data, len);
} else {
txtbuf[0] = 't'; /* plain base32(Thirty-two) */
len = b32->encode(txtbuf+1, &space, data, datalen);
len = base32_ops.encode(txtbuf+1, &space, data, datalen);
}
len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, txtbuf, len+1);
} else {
@ -2417,11 +2414,6 @@ main(int argc, char **argv)
netmask = 27;
pidfile = NULL;
b32 = get_base32_encoder();
b64 = get_base64_encoder();
b64u = get_base64u_encoder();
b128 = get_base128_encoder();
retval = 0;
#ifdef WINDOWS32