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_blksize_raw();
static int base128_blksize_enc();
static size_t base128_encoded_length(size_t inputlen);
static struct encoder base128_encoder =
{
@ -66,7 +67,9 @@ static struct encoder base128_encoder =
base128_handles_dots,
base128_handles_dots,
base128_blksize_raw,
base128_blksize_enc
base128_blksize_enc,
base128_encoded_length,
base128_raw_length
};
struct encoder
@ -93,6 +96,18 @@ base128_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
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_blksize_raw();
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 =
{
@ -47,7 +50,9 @@ static struct encoder base32_encoder =
base32_handles_dots,
base32_handles_dots,
base32_blksize_raw,
base32_blksize_enc
base32_blksize_enc,
base32_encoded_length,
base32_raw_length
};
struct encoder
@ -74,6 +79,19 @@ base32_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
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_blksize_raw();
static int base64_blksize_enc();
static size_t base64_encoded_length(size_t inputlen);
static struct encoder base64_encoder =
{
@ -47,7 +48,9 @@ static struct encoder base64_encoder =
base64_handles_dots,
base64_handles_dots,
base64_blksize_raw,
base64_blksize_enc
base64_blksize_enc,
base64_encoded_length,
base64_raw_length
};
struct encoder
@ -74,6 +77,18 @@ base64_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
base64_reverse_init()
{

View File

@ -19,19 +19,43 @@
#include "common.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
build_hostname(char *buf, size_t buflen,
const char *data, const size_t datalen,
const char *topdomain, struct encoder *encoder, size_t maxlen)
build_hostname(char *buf, size_t buflen, const char *data, const size_t datalen,
const char *topdomain, struct encoder *encoder, size_t maxlen, size_t header_len)
/* 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;
char *b;
space = MIN(maxlen, buflen) - strlen(topdomain) - DOWNSTREAM_HDR + 3;
/* max header length + 1 dot before topdomain + 2 safety */
if (!encoder->places_dots())
space -= (space / 57); /* space for dots */
space = get_encoded_length(MIN(maxlen, buflen), encoder, topdomain);
buf += header_len;
buflen -= header_len;
maxlen -= header_len;
memset(buf, 0, buflen);
@ -72,7 +96,7 @@ inline_dotify(char *buf, size_t buflen)
char *reader, *writer;
total = strlen(buf);
dots = total / 57;
dots = total / 63;
writer = buf;
writer += total;
@ -91,7 +115,7 @@ inline_dotify(char *buf, size_t buflen)
while (dots) {
*writer-- = *reader--;
pos--;
if (pos % 57 == 0) {
if (pos % 63 == 0) {
*writer-- = '.';
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_LEN 48
#define DNS_MAXLABEL 63
struct encoder {
char name[8];
int (*encode) (char *, size_t *, const void *, size_t);
@ -33,8 +35,13 @@ struct encoder {
int (*eats_dots) (void);
int (*blocksize_raw)(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 unpack_data(char *, size_t, char *, size_t, struct encoder *);
int inline_dotify(char *, size_t);