Added encoder length calculation functions

This commit is contained in:
frekky 2015-08-23 22:10:50 +08:00
parent 96f9270b7f
commit 5df91ed775
5 changed files with 92 additions and 13 deletions

View File

@ -57,6 +57,7 @@ static int base128_decode(void *, size_t *, const char *, size_t);
static int base128_handles_dots(); static int base128_handles_dots();
static int base128_blksize_raw(); static int base128_blksize_raw();
static int base128_blksize_enc(); static int base128_blksize_enc();
static size_t base128_encoded_length(size_t inputlen);
static struct encoder base128_encoder = static struct encoder base128_encoder =
{ {
@ -66,7 +67,9 @@ static struct encoder base128_encoder =
base128_handles_dots, base128_handles_dots,
base128_handles_dots, base128_handles_dots,
base128_blksize_raw, base128_blksize_raw,
base128_blksize_enc base128_blksize_enc,
base128_encoded_length,
base128_raw_length
}; };
struct encoder struct encoder
@ -93,6 +96,18 @@ base128_blksize_enc()
return BLKSIZE_ENC; return BLKSIZE_ENC;
} }
static size_t
base128_encoded_length(size_t inputlen)
{
return (BLKSIZE_ENC * inputlen) / BLKSIZE_RAW + ((BLKSIZE_ENC * inputlen) % BLKSIZE_RAW) ? 1 : 0;
}
static size_t
base128_raw_length(size_t inputlen)
{
return (BLKSIZE_RAW * inputlen) / BLKSIZE_ENC + ((BLKSIZE_RAW * inputlen) % BLKSIZE_ENC) ? 1 : 0;
}
inline static void inline static void
base128_reverse_init() base128_reverse_init()
{ {

View File

@ -38,6 +38,9 @@ static int base32_decode(void *, size_t *, const char *, size_t);
static int base32_handles_dots(); static int base32_handles_dots();
static int base32_blksize_raw(); static int base32_blksize_raw();
static int base32_blksize_enc(); static int base32_blksize_enc();
static size_t base32_encoded_length(size_t inputlen);
static size_t base32_raw_length(size_t inputlen);
static struct encoder base32_encoder = static struct encoder base32_encoder =
{ {
@ -47,7 +50,9 @@ static struct encoder base32_encoder =
base32_handles_dots, base32_handles_dots,
base32_handles_dots, base32_handles_dots,
base32_blksize_raw, base32_blksize_raw,
base32_blksize_enc base32_blksize_enc,
base32_encoded_length,
base32_raw_length
}; };
struct encoder struct encoder
@ -74,6 +79,19 @@ base32_blksize_enc()
return BLKSIZE_ENC; return BLKSIZE_ENC;
} }
static size_t
base32_encoded_length(size_t inputlen)
{
return (BLKSIZE_ENC * inputlen) / BLKSIZE_RAW + ((BLKSIZE_ENC * inputlen) % BLKSIZE_RAW) ? 1 : 0;
}
static size_t
base32_raw_length(size_t inputlen)
{
return (BLKSIZE_RAW * inputlen) / BLKSIZE_ENC + ((BLKSIZE_RAW * inputlen) % BLKSIZE_ENC) ? 1 : 0;
}
inline static void inline static void
base32_reverse_init() base32_reverse_init()
{ {

View File

@ -38,6 +38,7 @@ static int base64_decode(void *, size_t *, const char *, size_t);
static int base64_handles_dots(); static int base64_handles_dots();
static int base64_blksize_raw(); static int base64_blksize_raw();
static int base64_blksize_enc(); static int base64_blksize_enc();
static size_t base64_encoded_length(size_t inputlen);
static struct encoder base64_encoder = static struct encoder base64_encoder =
{ {
@ -47,7 +48,9 @@ static struct encoder base64_encoder =
base64_handles_dots, base64_handles_dots,
base64_handles_dots, base64_handles_dots,
base64_blksize_raw, base64_blksize_raw,
base64_blksize_enc base64_blksize_enc,
base64_encoded_length,
base64_raw_length
}; };
struct encoder struct encoder
@ -74,6 +77,18 @@ base64_blksize_enc()
return BLKSIZE_ENC; return BLKSIZE_ENC;
} }
static size_t
base64_encoded_length(size_t inputlen)
{
return (BLKSIZE_ENC * inputlen) / BLKSIZE_RAW + ((BLKSIZE_ENC * inputlen) % BLKSIZE_RAW) ? 1 : 0;
}
static size_t
base64_raw_length(size_t inputlen)
{
return (BLKSIZE_RAW * inputlen) / BLKSIZE_ENC + ((BLKSIZE_RAW * inputlen) % BLKSIZE_ENC) ? 1 : 0;
}
inline static void inline static void
base64_reverse_init() base64_reverse_init()
{ {

View File

@ -19,19 +19,43 @@
#include "common.h" #include "common.h"
#include "encoding.h" #include "encoding.h"
size_t
get_raw_length(size_t enc_bytes, struct encoder *enc, const char *topdomain)
/* Returns the maximum length of raw data that can be encoded into max_enc_bytes */
{
size_t enc_datalen = enc_bytes - strlen(topdomain);
/* Number of dots in length of encoded data */
size_t dots = enc_datalen / (DNS_MAXLABEL + 1);
if (!enc->eats_dots()) /* Dots are not included in encoded data length */
enc_datalen -= dots;
return enc->get_raw_length(enc_datalen);
}
size_t
get_encoded_length(size_t raw_bytes, struct encoder *enc, const char *topdomain)
/* Returns length of encoded data from original data length orig_len; */
{
size_t dots = 1; /* dot before topdomain */
size_t len = enc->get_encoded_length(raw_bytes) + strlen(topdomain);
if (!enc->places_dots())
dots += len / 63; /* number of dots needed in data */
return len;
}
int int
build_hostname(char *buf, size_t buflen, build_hostname(char *buf, size_t buflen, const char *data, const size_t datalen,
const char *data, const size_t datalen, const char *topdomain, struct encoder *encoder, size_t maxlen, size_t header_len)
const char *topdomain, struct encoder *encoder, size_t maxlen) /* Builds DNS-compatible hostname for data using specified encoder and topdomain
* NB: Does not account for header length. Data is encoded at start of buf to
* (buf + MIN(maxlen, buflen)). */
{ {
size_t space; size_t space;
char *b; char *b;
space = MIN(maxlen, buflen) - strlen(topdomain) - DOWNSTREAM_HDR + 3; space = get_encoded_length(MIN(maxlen, buflen), encoder, topdomain);
/* max header length + 1 dot before topdomain + 2 safety */ buf += header_len;
buflen -= header_len;
if (!encoder->places_dots()) maxlen -= header_len;
space -= (space / 57); /* space for dots */
memset(buf, 0, buflen); memset(buf, 0, buflen);
@ -72,7 +96,7 @@ inline_dotify(char *buf, size_t buflen)
char *reader, *writer; char *reader, *writer;
total = strlen(buf); total = strlen(buf);
dots = total / 57; dots = total / 63;
writer = buf; writer = buf;
writer += total; writer += total;
@ -91,7 +115,7 @@ inline_dotify(char *buf, size_t buflen)
while (dots) { while (dots) {
*writer-- = *reader--; *writer-- = *reader--;
pos--; pos--;
if (pos % 57 == 0) { if (pos % 63 == 0) {
*writer-- = '.'; *writer-- = '.';
dots--; dots--;
} }

View File

@ -25,6 +25,8 @@
#define DOWNCODECCHECK1 "\000\000\000\000\377\377\377\377\125\125\125\125\252\252\252\252\201\143\310\322\307\174\262\027\137\117\316\311\111\055\122\041\141\251\161\040\045\263\006\163\346\330\104\060\171\120\127\277" #define DOWNCODECCHECK1 "\000\000\000\000\377\377\377\377\125\125\125\125\252\252\252\252\201\143\310\322\307\174\262\027\137\117\316\311\111\055\122\041\141\251\161\040\045\263\006\163\346\330\104\060\171\120\127\277"
#define DOWNCODECCHECK1_LEN 48 #define DOWNCODECCHECK1_LEN 48
#define DNS_MAXLABEL 63
struct encoder { struct encoder {
char name[8]; char name[8];
int (*encode) (char *, size_t *, const void *, size_t); int (*encode) (char *, size_t *, const void *, size_t);
@ -33,8 +35,13 @@ struct encoder {
int (*eats_dots) (void); int (*eats_dots) (void);
int (*blocksize_raw)(void); int (*blocksize_raw)(void);
int (*blocksize_encoded)(void); int (*blocksize_encoded)(void);
size_t (*get_encoded_length)(size_t);
size_t (*get_raw_length)(size_t);
}; };
size_t get_raw_length(size_t enc_bytes, struct encoder *enc, const char *topdomain);
size_t get_encoded_length(size_t raw_bytes, struct encoder *enc, const char *topdomain);
int build_hostname(char *, size_t, const char *, const size_t, const char *, struct encoder *, size_t); int build_hostname(char *, size_t, const char *, const size_t, const char *, struct encoder *, size_t);
int unpack_data(char *, size_t, char *, size_t, struct encoder *); int unpack_data(char *, size_t, char *, size_t, struct encoder *);
int inline_dotify(char *, size_t); int inline_dotify(char *, size_t);