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

Commit

Permalink
tlv: add parsing Cookie TLV support
Browse files Browse the repository at this point in the history
This is linked to "Cookie TLV" section from RFC8803:

https://www.rfc-editor.org/rfc/rfc8803.html#name-the-cookie-tlv

  The Cookie TLV (Figure 21) is an optional TLV that is similar to the
  TCP Fast Open Cookie [RFC7413]. A Transport Converter may want to
  verify that a Client can receive the packets that it sends to prevent
  attacks from spoofed addresses. This verification can be done by using
  a Cookie that is bound to, for example, the IP address(es) of the
  Client. This Cookie can be configured on the Client by means that are
  outside of this document or provided by the Transport Converter.

  A Transport Converter that has been configured to use the optional
  Cookie TLV MUST verify the presence of this TLV in the payload of the
  received SYN. If this TLV is present, the Transport Converter MUST
  validate the Cookie by means similar to those in Section 4.1.2 of
  [RFC7413] (i.e., IsCookieValid). If the Cookie is valid, the
  connection establishment procedure can continue. Otherwise, the
  Transport Converter MUST return an Error TLV set to "Not Authorized"
  and close the connection.

  If the received SYN did not contain a Cookie TLV, and cookie
  validation is required, the Transport Converter MAY compute a Cookie
  bound to this Client address. In such case, the Transport Converter
  MUST return an Error TLV set to "Missing Cookie" and the computed
  Cookie and close the connection. The Client will react to this error
  by first issuing a reset to terminate the connection. It also stores
  the received Cookie in its cache and attempts to reestablish a new
  connection to the Transport Converter that includes the Cookie TLV.

  The format of the Cookie TLV is shown in Figure 21.

                        0                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+-------------------------------+
   |     Type=0x16 |     Length    |             Zero              |
   +---------------+---------------+-------------------------------+
   /                        Opaque  Cookie                         /
   /                              ...                              /
   +---------------------------------------------------------------+

  Figure 21: The Cookie TLV

In this commit, only the parsing part has been added.

Signed-off-by: Matthieu Baerts <[email protected]>
  • Loading branch information
matttbe committed Apr 30, 2021
1 parent 0944881 commit 6a34c7b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 1 deletion.
2 changes: 1 addition & 1 deletion convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct convert_supported_opts {
struct convert_cookie {
struct convert_tlv tlv_hdr;
uint16_t reserved;
uint32_t opaque[0];
uint8_t opaque[0];
} __attribute__((packed));

struct convert_error {
Expand Down
17 changes: 17 additions & 0 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 @@ -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
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
51 changes: 51 additions & 0 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 @@ -322,6 +372,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 6a34c7b

Please sign in to comment.