Check accepted and rejected MTU boundaries in both UDP handshake directions
This commit is contained in:
1 parent
b8021efed8
commit
942736d604
1 file changed
+35
-4
@@ -252,12 +252,12 @@ static void request_boundaries(unsigned established) {
|
||||
request.code = variant ? ETCP_INIT_REQUEST_NOINIT : ETCP_INIT_REQUEST;
|
||||
for (unsigned invalid = 0; invalid < sizeof(request) + sizeof(request.node_id) + 5; invalid++) {
|
||||
unsigned length = invalid < sizeof(request) ? invalid : sizeof(request);
|
||||
unsigned fault = invalid - sizeof(request);
|
||||
unsigned fault = invalid < sizeof(request) ? 0 : invalid - sizeof(request);
|
||||
uint8_t saved_mtu[2]; memcpy(saved_mtu, request.mtu, 2);
|
||||
uint8_t saved_id = request.link_id;
|
||||
if (invalid >= sizeof(request) && fault < 8) request.node_id[fault] ^= 1;
|
||||
if (invalid >= sizeof(request) && fault >= 8 && fault < 12) {
|
||||
const uint16_t values[] = {0, 1, 100, WIRE_OVERHEAD(AF_INET) + ETCP_PAYLOAD_HEADER_SIZE + ACK_REZERV + 2};
|
||||
const uint16_t values[] = {0, 1, 100, ETCP_MIN_UDP_MTU(AF_INET) - 1};
|
||||
request.mtu[0] = values[fault - 8] >> 8; request.mtu[1] = values[fault - 8];
|
||||
}
|
||||
if (invalid >= sizeof(request) && fault == 12) request.link_id = 0;
|
||||
@@ -294,6 +294,16 @@ static void request_boundaries(unsigned established) {
|
||||
CHECK(link->initialized && link->remote_keepalive == flag && link->recv_keepalive);
|
||||
accepted++;
|
||||
}
|
||||
const uint16_t mtus[] = {ETCP_MIN_UDP_MTU(AF_INET), PACKET_DATA_MAX_MTU, UINT16_MAX};
|
||||
for (unsigned i = 0; i < 3; i++) {
|
||||
request.mtu[0] = mtus[i] >> 8; request.mtu[1] = mtus[i];
|
||||
size_t errors = ep[1].socket->pkt_format_errors;
|
||||
send_init_request_body(&request, sizeof(request), 1);
|
||||
CHECK(ep[1].socket->pkt_format_errors == errors);
|
||||
CHECK(first_link(1)->mtu_remote == (mtus[i] > PACKET_DATA_MAX_MTU ? PACKET_DATA_MAX_MTU : mtus[i]));
|
||||
CHECK(ep[1].conn->normalizer->frag_size >= 3 && ep[1].conn->normalizer->frag_size < PACKET_DATA_SIZE);
|
||||
accepted++;
|
||||
}
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "INIT_REQUEST boundaries established=%u: rejected=%u accepted=%u", established, rejected, accepted);
|
||||
teardown();
|
||||
@@ -318,10 +328,20 @@ static void response_boundaries(void) {
|
||||
unsigned rejected = 0, accepted = 0;
|
||||
for (unsigned variant = 0; variant < 2; variant++) {
|
||||
response.code = variant ? ETCP_INIT_RESPONSE_NOINIT : ETCP_INIT_RESPONSE;
|
||||
for (unsigned len = 1; len <= sizeof(response) + 1; len++) {
|
||||
for (unsigned invalid = 1; invalid <= sizeof(response) + 1 + 5; invalid++) {
|
||||
unsigned len = invalid <= sizeof(response) + 1 ? invalid : sizeof(response);
|
||||
struct ETCP_DGRAM* pkt = memory_pool_alloc(ep[0].inst->pkt_pool); CHECK(pkt);
|
||||
memcpy(pkt->data, &response, sizeof(response)); pkt->data[sizeof(response)] = 0;
|
||||
if (len >= sizeof(response)) pkt->data[1] ^= 1; /* Полное тело с чужим node_id тоже недопустимо. */
|
||||
if (invalid <= sizeof(response) + 1 && len >= sizeof(response)) pkt->data[1] ^= 1;
|
||||
if (invalid > sizeof(response) + 1) {
|
||||
unsigned fault = invalid - sizeof(response) - 2;
|
||||
struct ETCP_INIT_RESPONSE_PKT *bad = (struct ETCP_INIT_RESPONSE_PKT*)pkt->data;
|
||||
if (fault == 4) bad->link_id = 0;
|
||||
else {
|
||||
const uint16_t values[] = {0, 1, 100, ETCP_MIN_UDP_MTU(AF_INET) - 1};
|
||||
bad->mtu[0] = values[fault] >> 8; bad->mtu[1] = values[fault];
|
||||
}
|
||||
}
|
||||
pkt->timestamp = 123; pkt->flag_up = 0;
|
||||
struct ETCP_LINK before_link;
|
||||
struct ETCP_CONN before_conn;
|
||||
@@ -346,6 +366,17 @@ static void response_boundaries(void) {
|
||||
CHECK(link->last_recv_timestamp == 456 && !ep[0].conn->callbacks_running);
|
||||
CHECK(ep[0].conn->reset_id == epoch && !ep[0].reinit); accepted++;
|
||||
}
|
||||
const uint16_t mtus[] = {ETCP_MIN_UDP_MTU(AF_INET), PACKET_DATA_MAX_MTU, UINT16_MAX};
|
||||
for (unsigned i = 0; i < 3; i++) {
|
||||
struct ETCP_DGRAM *pkt = memory_pool_alloc(ep[0].inst->pkt_pool); CHECK(pkt);
|
||||
memcpy(pkt->data, &response, sizeof(response)); pkt->timestamp = 456; pkt->flag_up = 1;
|
||||
struct ETCP_INIT_RESPONSE_PKT *valid = (struct ETCP_INIT_RESPONSE_PKT*)pkt->data;
|
||||
valid->mtu[0] = mtus[i] >> 8; valid->mtu[1] = mtus[i];
|
||||
CHECK(etcp_packet_decrypted(ep[0].socket, pkt, link, sizeof(response) + ETCP_ENCRYPTED_HDR_SIZE) == 0);
|
||||
CHECK(link->mtu_remote == (mtus[i] > PACKET_DATA_MAX_MTU ? PACKET_DATA_MAX_MTU : mtus[i]));
|
||||
CHECK(ep[0].conn->normalizer->frag_size >= 3 && ep[0].conn->normalizer->frag_size < PACKET_DATA_SIZE);
|
||||
accepted++;
|
||||
}
|
||||
}
|
||||
CHECK(ep[0].down == 6 && ep[0].up == 7);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "INIT_RESPONSE boundaries: rejected=%u accepted=%u (both codes, padding, flag_up=0/1)",
|
||||
|
||||
Reference in new issue
Block a user