diff --git a/src/base128.c b/src/base128.c index 8f926ed..30b6034 100644 --- a/src/base128.c +++ b/src/base128.c @@ -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 +}; diff --git a/src/base128.h b/src/base128.h index f4c55f6..f967134 100644 --- a/src/base128.h +++ b/src/base128.h @@ -17,6 +17,6 @@ #ifndef __BASE128_H__ #define __BASE128_H__ -struct encoder *get_base128_encoder(void); +const struct encoder base128_ops; #endif diff --git a/src/base32.c b/src/base32.c index bf540eb..809115a 100644 --- a/src/base32.c +++ b/src/base32.c @@ -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, +}; diff --git a/src/base32.h b/src/base32.h index 83ba784..89f78ad 100644 --- a/src/base32.h +++ b/src/base32.h @@ -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 diff --git a/src/base64.c b/src/base64.c index 133fcb4..875c8c9 100644 --- a/src/base64.c +++ b/src/base64.c @@ -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, +}; diff --git a/src/base64.h b/src/base64.h index 8ce4742..376ea2d 100644 --- a/src/base64.h +++ b/src/base64.h @@ -18,6 +18,6 @@ #ifndef __BASE64_H__ #define __BASE64_H__ -struct encoder *get_base64_encoder(void); +extern const struct encoder base64_ops; #endif diff --git a/src/client.c b/src/client.c index ea243fb..db792c1 100644 --- a/src/client.c +++ b/src/client.c @@ -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); diff --git a/src/iodined.c b/src/iodined.c index bd5afdb..534325f 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -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