Skip to content
This repository has been archived by the owner on Aug 30, 2024. It is now read-only.

Commit

Permalink
Merge pull request #26 from matttbe/convert-cookie
Browse files Browse the repository at this point in the history
Add Cookie TLV support
  • Loading branch information
Gregory Vander Schueren authored May 3, 2021
2 parents 766290e + 7d46c3c commit 8209672
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 28 deletions.
42 changes: 18 additions & 24 deletions convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,45 +74,39 @@ struct convert_tlv {
} __attribute__((packed));

struct convert_connect {
uint8_t type;
uint8_t length;
uint16_t remote_port;
struct in6_addr remote_addr;
uint8_t options[0];
struct convert_tlv tlv_hdr;
uint16_t remote_port;
struct in6_addr remote_addr;
uint8_t options[0];
} __attribute__((packed));

struct convert_info {
uint8_t type;
uint8_t length;
uint16_t reserved;
struct convert_tlv tlv_hdr;
uint16_t reserved;
} __attribute__((packed));

struct convert_supported_opts {
uint8_t type;
uint8_t length;
uint16_t reserved;
uint8_t options_kind[0];
struct convert_tlv tlv_hdr;
uint16_t reserved;
uint8_t options_kind[0];
} __attribute__((packed));

struct convert_cookie {
uint8_t type;
uint8_t length;
uint16_t reserved;
uint32_t opaque[0];
struct convert_tlv tlv_hdr;
uint16_t reserved;
uint8_t opaque[0];
} __attribute__((packed));

struct convert_error {
uint8_t type;
uint8_t length;
uint8_t error_code;
uint8_t value[0];
struct convert_tlv tlv_hdr;
uint8_t error_code;
uint8_t value[0];
} __attribute__((packed));

struct convert_extended_tcp_hdr {
uint8_t type;
uint8_t length;
uint16_t unassigned;
uint8_t tcp_options[0];
struct convert_tlv tlv_hdr;
uint16_t unassigned;
uint8_t tcp_options[0];
} __attribute__((packed));

#endif
38 changes: 36 additions & 2 deletions convert_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void
convert_free_opts(struct convert_opts *opts)
{
free(opts->tcp_options);
free(opts->cookie_data);
free(opts);
}

Expand Down Expand Up @@ -109,7 +110,7 @@ convert_parse_tlvs(const uint8_t *buff, size_t buff_len)
goto error_and_free;

/* TODO support the options. */
if (CONVERT_TO_BYTES(conv_connect->length) !=
if (CONVERT_TO_BYTES(tlv->length) !=
CONVERT_ALIGN(sizeof(*conv_connect)))
goto error_and_free;

Expand Down Expand Up @@ -147,6 +148,22 @@ convert_parse_tlvs(const uint8_t *buff, size_t buff_len)

break;
}
case CONVERT_COOKIE: {
struct convert_cookie *cookie =
(struct convert_cookie *)buff;
size_t cookie_len =
tlv_len - sizeof(struct convert_cookie);

opts->flags |= CONVERT_F_COOKIE;

opts->cookie_len = cookie_len;
opts->cookie_data = malloc(cookie_len);
if (opts->cookie_data == NULL)
goto error_and_free;
memcpy(opts->cookie_data, cookie->opaque, cookie_len);

break;
}
/* TODO support other TLVs. */
default:
goto error_and_free;
Expand Down Expand Up @@ -221,6 +238,23 @@ _convert_write_tlv_extended_tcp_hdr(uint8_t *buff, size_t buff_len,
return length;
}

static ssize_t
_convert_write_tlv_cookie(uint8_t *buff, size_t buff_len,
const struct convert_opts *opts)
{
struct convert_cookie * cookie = (struct convert_cookie *)buff;
size_t length = CONVERT_ALIGN(sizeof(*cookie) +
opts->cookie_len);

if (buff_len < length)
return -1;

memset(cookie, '\0', length);
memcpy(cookie->opaque, opts->cookie_data, opts->cookie_len);

return length;
}

static struct {
uint32_t flag;
uint8_t type;
Expand Down Expand Up @@ -250,7 +284,7 @@ static struct {
[_CONVERT_F_COOKIE] = {
.flag = CONVERT_F_COOKIE,
.type = CONVERT_COOKIE,
.cb = _convert_write_tlv_not_supp,
.cb = _convert_write_tlv_cookie,
},
[_CONVERT_F_ERROR] = {
.flag = CONVERT_F_ERROR,
Expand Down
4 changes: 4 additions & 0 deletions convert_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ struct convert_opts {
uint8_t * tcp_options;
size_t tcp_options_len;

/* if CONVERT_F_COOKIE is set in flags */
uint8_t * cookie_data;
size_t cookie_len;

/* TODO extend to support more TLVs. */
};

Expand Down
56 changes: 54 additions & 2 deletions tests/check_convert_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,25 @@ sample_convert_tcp_ext_hdr_tlv(size_t *len)
return ext_tcp_hdr;
}

struct convert_cookie *
sample_convert_cookie_tlv(size_t *len)
{
unsigned int i = 0;
size_t cookie_len = 8;

*len = sizeof(struct convert_cookie) + cookie_len;
struct convert_cookie * cookie = malloc(*len);
struct convert_tlv * tlv = (struct convert_tlv *)cookie;

tlv->length = 3; /* In 32-bit words */
tlv->type = CONVERT_COOKIE;
cookie->reserved = 0;
for (i = 0; i < cookie_len; i++)
cookie->opaque[i] = rand() % 256;

return cookie;
}

START_TEST (test_convert_parse_header) {
int ret;
struct convert_header hdr;
Expand Down Expand Up @@ -236,6 +255,37 @@ START_TEST (test_convert_parse_tlvs_ext_tcp_hdr) {
}
END_TEST

START_TEST (test_convert_parse_tlvs_cookie) {
struct convert_opts * opts;
uint8_t * buff;
size_t buff_len;
struct convert_cookie * cookie;
unsigned int i;
size_t cookie_len;

buff = (uint8_t *)sample_convert_cookie_tlv(&buff_len);
cookie = (struct convert_cookie *)buff;

opts = convert_parse_tlvs(buff, sizeof(struct convert_cookie) - 1);
ck_assert_msg(opts == NULL,
"Should fail: buff len shorter than Cookie TLV");

opts = convert_parse_tlvs(buff, buff_len);
ck_assert_msg(opts != NULL, "Should parse valid Convert Cookie TLV");
ck_assert_msg(opts->flags & CONVERT_F_COOKIE, "Should set COOKIE flag");

cookie_len = buff_len - sizeof(struct convert_cookie);
ck_assert_msg(opts->cookie_len == cookie_len, "Should set cookie_len");

for (i = 0; i < cookie_len; ++i)
ck_assert_msg(opts->cookie_data[i] == cookie->opaque[i],
"Should return exact copy TCP options");

convert_free_opts(opts);
free(buff);
}
END_TEST

START_TEST (test_convert_parse_tlvs_multiple) {
struct convert_opts * opts;
uint8_t * buff;
Expand Down Expand Up @@ -266,10 +316,11 @@ END_TEST

START_TEST (test_convert_write_tlvs) {
unsigned int i;
uint8_t * (*tlv_builders[3])(size_t *len) = {
uint8_t * (*tlv_builders[4])(size_t *len) = {
(uint8_t * (*)(size_t *))sample_convert_connect_tlv,
(uint8_t * (*)(size_t *))sample_convert_error_tlv,
(uint8_t * (*)(size_t *))sample_convert_tcp_ext_hdr_tlv
(uint8_t * (*)(size_t *))sample_convert_tcp_ext_hdr_tlv,
(uint8_t * (*)(size_t *))sample_convert_cookie_tlv,
};

/* For each TLV type, we expect convert_write(convert_read(TLV)) == TLV,
Expand Down Expand Up @@ -322,6 +373,7 @@ convert_util_suite(void)
tcase_add_test(tc_core, test_convert_parse_tlvs_connect);
tcase_add_test(tc_core, test_convert_parse_tlvs_error);
tcase_add_test(tc_core, test_convert_parse_tlvs_ext_tcp_hdr);
tcase_add_test(tc_core, test_convert_parse_tlvs_cookie);
tcase_add_test(tc_core, test_convert_parse_tlvs_multiple);
tcase_add_test(tc_core, test_convert_write_tlvs);
/* TODO:
Expand Down

0 comments on commit 8209672

Please sign in to comment.