Home | History | Annotate | Line # | Download | only in isc
proxyheader_test.c revision 1.1.1.1
      1 /*	$NetBSD: proxyheader_test.c,v 1.1.1.1 2025/01/26 16:12:36 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #include <sched.h> /* IWYU pragma: keep */
     17 #include <setjmp.h>
     18 #include <stdarg.h>
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 
     22 #define UNIT_TESTING
     23 #include <cmocka.h>
     24 
     25 #include <isc/buffer.h>
     26 #include <isc/mem.h>
     27 #include <isc/os.h>
     28 #include <isc/proxy2.h>
     29 #include <isc/random.h>
     30 
     31 #include "proxyheader_test_data.h"
     32 
     33 #include <tests/isc.h>
     34 
     35 typedef struct dummy_handler_cbarg {
     36 	isc_proxy2_command_t cmd;
     37 	int socktype;
     38 	isc_sockaddr_t src_addr;
     39 	isc_sockaddr_t dst_addr;
     40 	size_t no_more_calls;
     41 	size_t tlvs;
     42 	size_t tls_subtlvs;
     43 	uint8_t tls_client_flags;
     44 	bool client_cert_verified;
     45 	isc_region_t tlv_data;
     46 	isc_region_t extra;
     47 	isc_region_t tls_version;
     48 	isc_region_t tls_common_name;
     49 } dummy_handler_cbarg_t;
     50 
     51 static bool
     52 dummy_subtlv_iter_cb(const uint8_t client, const bool client_cert_verified,
     53 		     const isc_proxy2_tlv_subtype_tls_t tls_subtlv_type,
     54 		     const isc_region_t *restrict data, void *cbarg) {
     55 	dummy_handler_cbarg_t *arg = (dummy_handler_cbarg_t *)cbarg;
     56 
     57 	UNUSED(client);
     58 	UNUSED(client_cert_verified);
     59 
     60 	arg->tls_subtlvs++;
     61 
     62 	switch (tls_subtlv_type) {
     63 	case ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION:
     64 		arg->tls_version = *data;
     65 		break;
     66 	case ISC_PROXY2_TLV_SUBTYPE_TLS_CN:
     67 		arg->tls_common_name = *data;
     68 		break;
     69 	default:
     70 		break;
     71 	};
     72 
     73 	return true;
     74 }
     75 
     76 static bool
     77 dummy_tlv_iter_cb(const isc_proxy2_tlv_type_t tlv_type,
     78 		  const isc_region_t *restrict data, void *cbarg) {
     79 	dummy_handler_cbarg_t *arg = (dummy_handler_cbarg_t *)cbarg;
     80 
     81 	if (arg != NULL) {
     82 		arg->tlvs++;
     83 	}
     84 
     85 	if (tlv_type == ISC_PROXY2_TLV_TYPE_TLS) {
     86 		isc_result_t result = isc_proxy2_subtlv_tls_header_data(
     87 			data, &arg->tls_client_flags,
     88 			&arg->client_cert_verified);
     89 
     90 		assert_true(result == ISC_R_SUCCESS);
     91 
     92 		result = isc_proxy2_subtlv_tls_iterate(
     93 			data, dummy_subtlv_iter_cb, cbarg);
     94 
     95 		assert_true(result == ISC_R_SUCCESS);
     96 	}
     97 	return true;
     98 }
     99 
    100 static void
    101 proxy2_handler_dummy(const isc_result_t result, const isc_proxy2_command_t cmd,
    102 		     const int socktype,
    103 		     const isc_sockaddr_t *restrict src_addr,
    104 		     const isc_sockaddr_t *restrict dst_addr,
    105 		     const isc_region_t *restrict tlv_blob,
    106 		     const isc_region_t *restrict extra, void *cbarg) {
    107 	dummy_handler_cbarg_t *arg = (dummy_handler_cbarg_t *)cbarg;
    108 
    109 	UNUSED(extra);
    110 
    111 	if (result == ISC_R_NOMORE && arg != NULL) {
    112 		arg->no_more_calls++;
    113 		return;
    114 	} else if (result != ISC_R_SUCCESS) {
    115 		return;
    116 	}
    117 
    118 	if (cmd == ISC_PROXY2_CMD_PROXY && socktype != 0 /* unspec */) {
    119 		INSIST(src_addr != NULL);
    120 		INSIST(dst_addr != NULL);
    121 	} else if (cmd == ISC_PROXY2_CMD_LOCAL) {
    122 		INSIST(tlv_blob == NULL);
    123 		INSIST(src_addr == NULL);
    124 		INSIST(dst_addr == NULL);
    125 	}
    126 
    127 	if (arg != NULL) {
    128 		arg->cmd = cmd;
    129 		arg->socktype = socktype;
    130 		if (src_addr != NULL) {
    131 			INSIST(dst_addr != NULL);
    132 			arg->src_addr = *src_addr;
    133 			arg->dst_addr = *dst_addr;
    134 		}
    135 	}
    136 
    137 	if (tlv_blob) {
    138 		assert_true(isc_proxy2_tlv_data_verify(tlv_blob) ==
    139 			    ISC_R_SUCCESS);
    140 		if (cbarg != NULL) {
    141 			isc_proxy2_tlv_iterate(tlv_blob, dummy_tlv_iter_cb,
    142 					       cbarg);
    143 		}
    144 	}
    145 }
    146 
    147 static int
    148 setup_test_proxy(void **state) {
    149 	isc_proxy2_handler_t **handler = (isc_proxy2_handler_t **)state;
    150 	*handler = isc_proxy2_handler_new(mctx, 0, proxy2_handler_dummy, NULL);
    151 	return 0;
    152 }
    153 
    154 static int
    155 teardown_test_proxy(void **state) {
    156 	isc_proxy2_handler_free((isc_proxy2_handler_t **)state);
    157 
    158 	return 0;
    159 }
    160 
    161 static void
    162 test_header_data(isc_proxy2_handler_t *handler, const void *data,
    163 		 const size_t size, const bool tear_apart,
    164 		 const bool tear_randomly) {
    165 	isc_region_t region = { 0 };
    166 	isc_result_t result;
    167 
    168 	if (tear_apart) {
    169 		isc_buffer_t databuf = { 0 };
    170 		isc_buffer_init(&databuf, (void *)data, size);
    171 		isc_buffer_add(&databuf, size);
    172 
    173 		for (; isc_buffer_remaininglength(&databuf) > 0;) {
    174 			isc_region_t remaining = { 0 };
    175 			size_t sz = 1;
    176 
    177 			if (tear_randomly) {
    178 				sz = 1 + isc_random_uniform(
    179 						 isc_buffer_remaininglength(
    180 							 &databuf));
    181 			}
    182 
    183 			isc_buffer_remainingregion(&databuf, &remaining);
    184 			remaining.length = sz;
    185 
    186 			result = isc_proxy2_handler_push(handler, &remaining);
    187 			assert_true(isc_proxy2_handler_result(handler) ==
    188 				    result);
    189 
    190 			isc_buffer_forward(&databuf, sz);
    191 			if (result == ISC_R_SUCCESS) {
    192 				break;
    193 			}
    194 		}
    195 
    196 	} else {
    197 		result = isc_proxy2_handler_push_data(handler, data, size);
    198 		assert_true(isc_proxy2_handler_result(handler) == result);
    199 	}
    200 
    201 	assert_true(isc_proxy2_handler_result(handler) == ISC_R_SUCCESS);
    202 	isc_proxy2_handler_header(handler, &region);
    203 	assert_true(region.length == size);
    204 	assert_true(memcmp(region.base, data, region.length) == 0);
    205 }
    206 
    207 static void
    208 verify_proxy_v2_header(isc_proxy2_handler_t *handler,
    209 		       dummy_handler_cbarg_t *cbarg) {
    210 	char sabuf[ISC_SOCKADDR_FORMATSIZE] = { 0 };
    211 	isc_sockaddr_t src_addr = { 0 }, dst_addr = { 0 };
    212 	isc_result_t result;
    213 	int socktype = -1;
    214 
    215 	assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY);
    216 	assert_true(cbarg->socktype == SOCK_STREAM);
    217 	assert_true(isc_sockaddr_pf(&cbarg->dst_addr) == AF_INET);
    218 	assert_true(isc_sockaddr_pf(&cbarg->src_addr) == AF_INET);
    219 
    220 	isc_sockaddr_format(&cbarg->dst_addr, sabuf, sizeof(sabuf));
    221 	assert_true(strcmp(sabuf, "127.0.0.66#11883") == 0);
    222 	isc_sockaddr_format(&cbarg->src_addr, sabuf, sizeof(sabuf));
    223 	assert_true(strcmp(sabuf, "127.0.0.1#56784") == 0);
    224 
    225 	if (handler != NULL) {
    226 		result = isc_proxy2_handler_addresses(handler, &socktype,
    227 						      &src_addr, &dst_addr);
    228 		assert_true(result == ISC_R_SUCCESS);
    229 		assert_true(isc_sockaddr_equal(&src_addr, &cbarg->src_addr));
    230 		assert_true(isc_sockaddr_equal(&dst_addr, &cbarg->dst_addr));
    231 		assert_true(socktype == cbarg->socktype);
    232 	}
    233 
    234 	assert_true(cbarg->tlvs == 0);
    235 	assert_true(cbarg->tls_subtlvs == 0);
    236 	assert_true(cbarg->tls_client_flags == 0);
    237 	assert_true(cbarg->client_cert_verified == false);
    238 }
    239 
    240 static void
    241 verify_proxy_v2_header_with_TLS(isc_proxy2_handler_t *handler,
    242 				dummy_handler_cbarg_t *cbarg) {
    243 	char sabuf[ISC_SOCKADDR_FORMATSIZE] = { 0 };
    244 	isc_sockaddr_t src_addr = { 0 }, dst_addr = { 0 };
    245 	isc_result_t result;
    246 	int socktype = -1;
    247 
    248 	assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY);
    249 	assert_true(cbarg->socktype == SOCK_STREAM);
    250 	assert_true(isc_sockaddr_pf(&cbarg->dst_addr) == AF_INET);
    251 	assert_true(isc_sockaddr_pf(&cbarg->src_addr) == AF_INET);
    252 
    253 	isc_sockaddr_format(&cbarg->dst_addr, sabuf, sizeof(sabuf));
    254 	assert_true(strcmp(sabuf, "127.0.0.67#11883") == 0);
    255 	isc_sockaddr_format(&cbarg->src_addr, sabuf, sizeof(sabuf));
    256 	assert_true(strcmp(sabuf, "127.0.0.1#39754") == 0);
    257 
    258 	if (handler != NULL) {
    259 		result = isc_proxy2_handler_addresses(handler, &socktype,
    260 						      &src_addr, &dst_addr);
    261 		assert_true(result == ISC_R_SUCCESS);
    262 		assert_true(isc_sockaddr_equal(&src_addr, &cbarg->src_addr));
    263 		assert_true(isc_sockaddr_equal(&dst_addr, &cbarg->dst_addr));
    264 		assert_true(socktype == cbarg->socktype);
    265 	}
    266 
    267 	assert_true(cbarg->tlvs == 1);
    268 	assert_true(cbarg->tls_subtlvs == 1);
    269 	assert_true(cbarg->tls_client_flags == ISC_PROXY2_CLIENT_TLS);
    270 	assert_true(cbarg->client_cert_verified == true);
    271 
    272 	/* "TLSv1.2" (w/o trailing '\0') */
    273 	assert_true(cbarg->tls_version.length == 7);
    274 	assert_true(memcmp(cbarg->tls_version.base, "TLSv1.2", 7) == 0);
    275 }
    276 
    277 static void
    278 verify_proxy_v2_header_with_TLS_CN(isc_proxy2_handler_t *handler,
    279 				   dummy_handler_cbarg_t *cbarg) {
    280 	char sabuf[ISC_SOCKADDR_FORMATSIZE] = { 0 };
    281 	isc_sockaddr_t src_addr = { 0 }, dst_addr = { 0 };
    282 	isc_result_t result;
    283 	int socktype = -1;
    284 
    285 	assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY);
    286 	assert_true(cbarg->socktype == SOCK_STREAM);
    287 	assert_true(isc_sockaddr_pf(&cbarg->dst_addr) == AF_INET);
    288 	assert_true(isc_sockaddr_pf(&cbarg->src_addr) == AF_INET);
    289 
    290 	isc_sockaddr_format(&cbarg->dst_addr, sabuf, sizeof(sabuf));
    291 	assert_true(strcmp(sabuf, "127.0.0.67#11883") == 0);
    292 	isc_sockaddr_format(&cbarg->src_addr, sabuf, sizeof(sabuf));
    293 	assert_true(strcmp(sabuf, "127.0.0.1#40402") == 0);
    294 
    295 	if (handler != NULL) {
    296 		result = isc_proxy2_handler_addresses(handler, &socktype,
    297 						      &src_addr, &dst_addr);
    298 		assert_true(result == ISC_R_SUCCESS);
    299 		assert_true(isc_sockaddr_equal(&src_addr, &cbarg->src_addr));
    300 		assert_true(isc_sockaddr_equal(&dst_addr, &cbarg->dst_addr));
    301 		assert_true(socktype == cbarg->socktype);
    302 	}
    303 
    304 	assert_true(cbarg->tlvs == 1);
    305 	assert_true(cbarg->tls_subtlvs == 2); /* version and common name */
    306 	assert_true(cbarg->tls_client_flags ==
    307 		    (ISC_PROXY2_CLIENT_TLS | ISC_PROXY2_CLIENT_CERT_SESS |
    308 		     ISC_PROXY2_CLIENT_CERT_CONN));
    309 	assert_true(cbarg->client_cert_verified == true);
    310 
    311 	/* "TLSv1.2" (w/o trailing '\0') */
    312 	assert_true(cbarg->tls_version.length == 7);
    313 	assert_true(memcmp(cbarg->tls_version.base, "TLSv1.2", 7) == 0);
    314 
    315 	/* "mqttuser1" (w/o trailing '\0') */
    316 	assert_true(cbarg->tls_common_name.length == 9);
    317 	assert_true(memcmp(cbarg->tls_common_name.base, "mqttuser1", 9) == 0);
    318 }
    319 
    320 static void
    321 verify_proxy_v2_header_with_AF_UNIX(isc_proxy2_handler_t *handler,
    322 				    dummy_handler_cbarg_t *cbarg) {
    323 	assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY);
    324 	assert_true(cbarg->socktype == 0);
    325 
    326 	if (handler != NULL) {
    327 		int socktype = -1;
    328 		isc_result_t result;
    329 
    330 		result = isc_proxy2_handler_addresses(handler, &socktype, NULL,
    331 						      NULL);
    332 
    333 		assert_int_equal(result, ISC_R_SUCCESS);
    334 
    335 		assert_int_equal(socktype, 0);
    336 	}
    337 }
    338 
    339 ISC_RUN_TEST_IMPL(proxyheader_generic_test) {
    340 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    341 	dummy_handler_cbarg_t cbarg = { 0 };
    342 
    343 	isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg);
    344 
    345 	test_header_data(handler, proxy_v2_header, sizeof(proxy_v2_header),
    346 			 false, false);
    347 	verify_proxy_v2_header(handler, &cbarg);
    348 
    349 	cbarg = (dummy_handler_cbarg_t){ 0 };
    350 	test_header_data(handler, (void *)proxy_v2_header_with_TLS,
    351 			 sizeof(proxy_v2_header_with_TLS), false, false);
    352 	verify_proxy_v2_header_with_TLS(handler, &cbarg);
    353 
    354 	cbarg = (dummy_handler_cbarg_t){ 0 };
    355 	test_header_data(handler, (void *)proxy_v2_header_with_TLS_CN,
    356 			 sizeof(proxy_v2_header_with_TLS_CN), false, false);
    357 	verify_proxy_v2_header_with_TLS_CN(handler, &cbarg);
    358 
    359 	cbarg = (dummy_handler_cbarg_t){ 0 };
    360 	test_header_data(handler, (void *)proxy_v2_header_with_AF_UNIX,
    361 			 sizeof(proxy_v2_header_with_AF_UNIX), false, false);
    362 	verify_proxy_v2_header_with_AF_UNIX(handler, &cbarg);
    363 }
    364 
    365 ISC_RUN_TEST_IMPL(proxyheader_generic_byte_by_byte_test) {
    366 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    367 	dummy_handler_cbarg_t cbarg = { 0 };
    368 
    369 	isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg);
    370 
    371 	test_header_data(handler, proxy_v2_header, sizeof(proxy_v2_header),
    372 			 true, false);
    373 	verify_proxy_v2_header(handler, &cbarg);
    374 	assert_true(cbarg.no_more_calls == sizeof(proxy_v2_header) - 1);
    375 
    376 	cbarg = (dummy_handler_cbarg_t){ 0 };
    377 	test_header_data(handler, (void *)proxy_v2_header_with_TLS,
    378 			 sizeof(proxy_v2_header_with_TLS), true, false);
    379 	verify_proxy_v2_header_with_TLS(handler, &cbarg);
    380 	assert_true(cbarg.no_more_calls ==
    381 		    sizeof(proxy_v2_header_with_TLS) - 1);
    382 
    383 	cbarg = (dummy_handler_cbarg_t){ 0 };
    384 	test_header_data(handler, (void *)proxy_v2_header_with_TLS_CN,
    385 			 sizeof(proxy_v2_header_with_TLS_CN), true, false);
    386 	verify_proxy_v2_header_with_TLS_CN(handler, &cbarg);
    387 	assert_true(cbarg.no_more_calls ==
    388 		    sizeof(proxy_v2_header_with_TLS_CN) - 1);
    389 
    390 	cbarg = (dummy_handler_cbarg_t){ 0 };
    391 	test_header_data(handler, (void *)proxy_v2_header_with_AF_UNIX,
    392 			 sizeof(proxy_v2_header_with_AF_UNIX), true, false);
    393 	verify_proxy_v2_header_with_AF_UNIX(handler, &cbarg);
    394 	assert_true(cbarg.no_more_calls ==
    395 		    sizeof(proxy_v2_header_with_AF_UNIX) - 1);
    396 }
    397 
    398 ISC_RUN_TEST_IMPL(proxyheader_generic_torn_apart_randomly_test) {
    399 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    400 	dummy_handler_cbarg_t cbarg = { 0 };
    401 
    402 	isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg);
    403 
    404 	test_header_data(handler, proxy_v2_header, sizeof(proxy_v2_header),
    405 			 true, true);
    406 	verify_proxy_v2_header(handler, &cbarg);
    407 
    408 	cbarg = (dummy_handler_cbarg_t){ 0 };
    409 	test_header_data(handler, (void *)proxy_v2_header_with_TLS,
    410 			 sizeof(proxy_v2_header_with_TLS), true, true);
    411 	verify_proxy_v2_header_with_TLS(handler, &cbarg);
    412 
    413 	cbarg = (dummy_handler_cbarg_t){ 0 };
    414 	test_header_data(handler, (void *)proxy_v2_header_with_TLS_CN,
    415 			 sizeof(proxy_v2_header_with_TLS_CN), true, true);
    416 	verify_proxy_v2_header_with_TLS_CN(handler, &cbarg);
    417 
    418 	cbarg = (dummy_handler_cbarg_t){ 0 };
    419 	test_header_data(handler, (void *)proxy_v2_header_with_AF_UNIX,
    420 			 sizeof(proxy_v2_header_with_AF_UNIX), true, true);
    421 	verify_proxy_v2_header_with_AF_UNIX(handler, &cbarg);
    422 }
    423 
    424 ISC_RUN_TEST_IMPL(proxyheader_direct_test) {
    425 	isc_result_t result;
    426 	isc_region_t region = { 0 };
    427 	dummy_handler_cbarg_t cbarg = { 0 };
    428 
    429 	cbarg = (dummy_handler_cbarg_t){ 0 };
    430 	region.base = (uint8_t *)proxy_v2_header;
    431 	region.length = sizeof(proxy_v2_header);
    432 	result = isc_proxy2_header_handle_directly(
    433 		&region, proxy2_handler_dummy, &cbarg);
    434 	assert_true(result == ISC_R_SUCCESS);
    435 	assert_true(cbarg.no_more_calls == 0);
    436 	verify_proxy_v2_header(NULL, &cbarg);
    437 
    438 	cbarg = (dummy_handler_cbarg_t){ 0 };
    439 	region.base = (uint8_t *)proxy_v2_header_with_TLS;
    440 	region.length = sizeof(proxy_v2_header_with_TLS);
    441 	result = isc_proxy2_header_handle_directly(
    442 		&region, proxy2_handler_dummy, &cbarg);
    443 	assert_true(result == ISC_R_SUCCESS);
    444 	assert_true(cbarg.no_more_calls == 0);
    445 	isc_proxy2_tlv_iterate(&cbarg.tlv_data, dummy_tlv_iter_cb, &cbarg);
    446 	verify_proxy_v2_header_with_TLS(NULL, &cbarg);
    447 
    448 	cbarg = (dummy_handler_cbarg_t){ 0 };
    449 	region.base = (uint8_t *)proxy_v2_header_with_TLS_CN;
    450 	region.length = sizeof(proxy_v2_header_with_TLS_CN);
    451 	result = isc_proxy2_header_handle_directly(
    452 		&region, proxy2_handler_dummy, &cbarg);
    453 	assert_true(result == ISC_R_SUCCESS);
    454 	assert_true(cbarg.no_more_calls == 0);
    455 	isc_proxy2_tlv_iterate(&cbarg.tlv_data, dummy_tlv_iter_cb, &cbarg);
    456 	verify_proxy_v2_header_with_TLS_CN(NULL, &cbarg);
    457 
    458 	cbarg = (dummy_handler_cbarg_t){ 0 };
    459 	region.base = (uint8_t *)proxy_v2_header_with_AF_UNIX;
    460 	region.length = sizeof(proxy_v2_header_with_AF_UNIX);
    461 	result = isc_proxy2_header_handle_directly(
    462 		&region, proxy2_handler_dummy, &cbarg);
    463 	assert_true(result == ISC_R_SUCCESS);
    464 	assert_true(cbarg.no_more_calls == 0);
    465 	verify_proxy_v2_header_with_AF_UNIX(NULL, &cbarg);
    466 }
    467 
    468 ISC_RUN_TEST_IMPL(proxyheader_detect_bad_signature_test) {
    469 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    470 
    471 	for (size_t i = 0; i < ISC_PROXY2_HEADER_SIGNATURE_SIZE; i++) {
    472 		isc_result_t result;
    473 		uint8_t sig[ISC_PROXY2_HEADER_SIGNATURE_SIZE];
    474 		memmove(sig, ISC_PROXY2_HEADER_SIGNATURE,
    475 			ISC_PROXY2_HEADER_SIGNATURE_SIZE);
    476 
    477 		sig[i] = 0x0C; /* it is not present in the valid signature */
    478 
    479 		/*
    480 		 * We are expected to detect bad signature as early as possible,
    481 		 * so we are passing only a part of the header.
    482 		 */
    483 		result = isc_proxy2_handler_push_data(handler, sig, i + 1);
    484 		assert_true(result == ISC_R_UNEXPECTED);
    485 	}
    486 }
    487 
    488 ISC_RUN_TEST_IMPL(proxyheader_extra_data_test) {
    489 	isc_result_t result;
    490 	isc_buffer_t databuf;
    491 	isc_region_t region = { 0 };
    492 	size_t sz;
    493 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    494 	uint8_t header[] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x51,
    495 			     0x55, 0x49, 0x54, 0x0a, 0x21, 0x11, 0x00, 0x1e,
    496 			     0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x43,
    497 			     0x9b, 0x4a, 0x2e, 0x6b, 0x20, 0x00, 0x0f, 0x01,
    498 			     0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x07, 0x54,
    499 			     0x4c, 0x53, 0x76, 0x31, 0x2e, 0x32 };
    500 	uint8_t extra_data[] = { 0x10, 0x1a, 0x00, 0x04, 0x4d, 0x51, 0x54,
    501 				 0x54, 0x04, 0x02, 0x00, 0x3c, 0x00, 0x0e,
    502 				 0x4d, 0x51, 0x54, 0x54, 0x5f, 0x46, 0x58,
    503 				 0x5f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74 };
    504 	uint8_t data[sizeof(header) + sizeof(extra_data)];
    505 
    506 	isc_buffer_init(&databuf, (void *)data, sizeof(data));
    507 
    508 	isc_buffer_putmem(&databuf, header, sizeof(header));
    509 	isc_buffer_putmem(&databuf, extra_data, sizeof(extra_data));
    510 
    511 	isc_buffer_remainingregion(&databuf, &region);
    512 
    513 	result = isc_proxy2_handler_push(handler, &region);
    514 	assert_true(result == ISC_R_SUCCESS);
    515 
    516 	region = (isc_region_t){ 0 };
    517 	sz = isc_proxy2_handler_header(handler, &region);
    518 	assert_true(sz == sizeof(header));
    519 	assert_true(sz == region.length);
    520 	assert_true(memcmp(header, region.base, sz) == 0);
    521 
    522 	region = (isc_region_t){ 0 };
    523 	sz = isc_proxy2_handler_extra(handler, &region);
    524 	assert_true(sz == sizeof(extra_data));
    525 	assert_true(sz == region.length);
    526 	assert_true(memcmp(extra_data, region.base, sz) == 0);
    527 }
    528 
    529 ISC_RUN_TEST_IMPL(proxyheader_max_size_test) {
    530 	isc_result_t result;
    531 	isc_proxy2_handler_t handler;
    532 
    533 	UNUSED(state);
    534 
    535 	isc_proxy2_handler_init(&handler, mctx, sizeof(proxy_v2_header),
    536 				proxy2_handler_dummy, NULL);
    537 
    538 	result = isc_proxy2_handler_push_data(&handler, proxy_v2_header,
    539 					      sizeof(proxy_v2_header));
    540 
    541 	assert_true(result == ISC_R_SUCCESS);
    542 
    543 	isc_proxy2_handler_uninit(&handler);
    544 
    545 	isc_proxy2_handler_init(&handler, mctx, sizeof(proxy_v2_header) - 1,
    546 				proxy2_handler_dummy, NULL);
    547 
    548 	result = isc_proxy2_handler_push_data(&handler, proxy_v2_header,
    549 					      sizeof(proxy_v2_header));
    550 
    551 	assert_true(result == ISC_R_RANGE);
    552 
    553 	isc_proxy2_handler_uninit(&handler);
    554 }
    555 
    556 ISC_RUN_TEST_IMPL(proxyheader_make_header_test) {
    557 	isc_result_t result;
    558 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    559 	isc_buffer_t databuf;
    560 	uint8_t data[ISC_PROXY2_MAX_SIZE];
    561 	isc_buffer_t sslbuf;
    562 	uint8_t ssldata[ISC_PROXY2_MAX_SIZE];
    563 	isc_region_t region = { 0 };
    564 	uint8_t extra[256] = { 0 };
    565 	const char *tls_version = "TLSv1.3";
    566 	const char *tls_cn = "name.test";
    567 	dummy_handler_cbarg_t cbarg = { 0 };
    568 	struct in_addr localhost4 = { 0 };
    569 	isc_sockaddr_t src_addrv4 = { 0 }, dst_addrv4 = { 0 },
    570 		       src_addrv6 = { 0 }, dst_addrv6 = { 0 };
    571 	const uint16_t src_port = 1236;
    572 	const uint16_t dst_port = 9582;
    573 
    574 	localhost4.s_addr = htonl(INADDR_LOOPBACK);
    575 
    576 	isc_sockaddr_fromin(&src_addrv4, &localhost4, src_port);
    577 	isc_sockaddr_fromin(&dst_addrv4, &localhost4, dst_port);
    578 	isc_sockaddr_fromin6(&src_addrv6, &in6addr_loopback, src_port);
    579 	isc_sockaddr_fromin6(&dst_addrv6, &in6addr_loopback, dst_port);
    580 	isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg);
    581 
    582 	isc_buffer_init(&databuf, (void *)data, sizeof(data));
    583 	isc_buffer_init(&sslbuf, (void *)ssldata, sizeof(ssldata));
    584 
    585 	/* unspec */
    586 	result = isc_proxy2_make_header(&databuf, ISC_PROXY2_CMD_LOCAL, 0, NULL,
    587 					NULL, NULL);
    588 	assert_true(result == ISC_R_SUCCESS);
    589 
    590 	isc_buffer_usedregion(&databuf, &region);
    591 	assert_true(region.length == ISC_PROXY2_HEADER_SIZE);
    592 
    593 	region = (isc_region_t){ .base = extra, .length = sizeof(extra) };
    594 	result = isc_proxy2_header_append_tlv(
    595 		&databuf, ISC_PROXY2_TLV_TYPE_NOOP, &region);
    596 	assert_true(result == ISC_R_SUCCESS);
    597 
    598 	isc_buffer_usedregion(&databuf, &region);
    599 	assert_true(region.length == ISC_PROXY2_HEADER_SIZE + sizeof(extra) +
    600 					     ISC_PROXY2_TLV_HEADER_SIZE);
    601 
    602 	result = isc_proxy2_handler_push(handler, &region);
    603 	assert_true(result == ISC_R_SUCCESS);
    604 	assert_true(cbarg.tlvs == 0); /* in unspec mode we ignore TLVs */
    605 
    606 	/* AF_INET, SOCK_STREAM */
    607 	cbarg = (dummy_handler_cbarg_t){ 0 };
    608 	isc_buffer_clear(&databuf);
    609 
    610 	result = isc_proxy2_make_header(&databuf, ISC_PROXY2_CMD_PROXY,
    611 					SOCK_STREAM, &src_addrv4, &dst_addrv4,
    612 					NULL);
    613 	assert_true(result == ISC_R_SUCCESS);
    614 
    615 	isc_buffer_usedregion(&databuf, &region);
    616 	assert_true(region.length == ISC_PROXY2_MIN_AF_INET_SIZE);
    617 
    618 	region = (isc_region_t){ .base = extra, .length = sizeof(extra) };
    619 	result = isc_proxy2_header_append_tlv(
    620 		&databuf, ISC_PROXY2_TLV_TYPE_NOOP, &region);
    621 	assert_true(result == ISC_R_SUCCESS);
    622 
    623 	isc_buffer_usedregion(&databuf, &region);
    624 	assert_true(region.length == ISC_PROXY2_MIN_AF_INET_SIZE +
    625 					     sizeof(extra) +
    626 					     ISC_PROXY2_TLV_HEADER_SIZE);
    627 
    628 	result = isc_proxy2_handler_push(handler, &region);
    629 	assert_true(result == ISC_R_SUCCESS);
    630 	assert_true(cbarg.tlvs == 1); /* ISC_PROXY2_TLV_TYPE_NOOP */
    631 
    632 	assert_true(cbarg.socktype == SOCK_STREAM);
    633 	assert_true(isc_sockaddr_pf(&cbarg.src_addr) == AF_INET);
    634 	assert_true(isc_sockaddr_pf(&cbarg.dst_addr) == AF_INET);
    635 
    636 	assert_true(isc_sockaddr_equal(&cbarg.src_addr, &src_addrv4));
    637 	assert_true(isc_sockaddr_equal(&cbarg.dst_addr, &dst_addrv4));
    638 
    639 	/* AF_INET6, SOCK_STREAM (+ TLS version and CN) */
    640 	cbarg = (dummy_handler_cbarg_t){ 0 };
    641 	isc_buffer_clear(&databuf);
    642 
    643 	result = isc_proxy2_make_header(&databuf, ISC_PROXY2_CMD_PROXY,
    644 					SOCK_STREAM, &src_addrv6, &dst_addrv6,
    645 					NULL);
    646 	assert_true(result == ISC_R_SUCCESS);
    647 
    648 	isc_buffer_usedregion(&databuf, &region);
    649 	assert_true(region.length == ISC_PROXY2_MIN_AF_INET6_SIZE);
    650 
    651 	region = (isc_region_t){ .base = extra, .length = sizeof(extra) };
    652 	result = isc_proxy2_header_append_tlv(
    653 		&databuf, ISC_PROXY2_TLV_TYPE_NOOP, &region);
    654 	assert_true(result == ISC_R_SUCCESS);
    655 
    656 	result = isc_proxy2_make_tls_subheader(
    657 		&sslbuf, ISC_PROXY2_CLIENT_TLS | ISC_PROXY2_CLIENT_CERT_CONN,
    658 		true, NULL);
    659 	assert_true(result == ISC_R_SUCCESS);
    660 	result = isc_proxy2_append_tlv_string(
    661 		&sslbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version);
    662 	assert_true(result == ISC_R_SUCCESS);
    663 	result = isc_proxy2_append_tlv_string(
    664 		&sslbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_CN, tls_cn);
    665 	assert_true(result == ISC_R_SUCCESS);
    666 
    667 	isc_buffer_usedregion(&sslbuf, &region);
    668 	result = isc_proxy2_header_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
    669 					      &region);
    670 	assert_true(result == ISC_R_SUCCESS);
    671 
    672 	isc_buffer_usedregion(&databuf, &region);
    673 	size_t expected = ISC_PROXY2_MIN_AF_INET6_SIZE + sizeof(extra) +
    674 			  (4 * ISC_PROXY2_TLV_HEADER_SIZE) +
    675 			  ISC_PROXY2_TLS_SUBHEADER_MIN_SIZE +
    676 			  strlen(tls_version) + strlen(tls_cn);
    677 	assert_true(region.length == expected);
    678 
    679 	result = isc_proxy2_handler_push(handler, &region);
    680 	assert_true(result == ISC_R_SUCCESS);
    681 
    682 	assert_true(cbarg.socktype == SOCK_STREAM);
    683 	assert_true(isc_sockaddr_pf(&cbarg.src_addr) == AF_INET6);
    684 	assert_true(isc_sockaddr_pf(&cbarg.dst_addr) == AF_INET6);
    685 
    686 	assert_true(isc_sockaddr_equal(&cbarg.src_addr, &src_addrv6));
    687 	assert_true(isc_sockaddr_equal(&cbarg.dst_addr, &dst_addrv6));
    688 
    689 	region = (isc_region_t){ 0 };
    690 	(void)isc_proxy2_handler_tlvs(handler, &region);
    691 	assert_true(isc_proxy2_tlv_data_verify(&region) == ISC_R_SUCCESS);
    692 	/* ISC_PROXY2_TLV_TYPE_NOOP+ISC_PROXY2_TLV_TYPE_TLS */
    693 	assert_true(cbarg.tlvs == 2);
    694 	/* ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION+ISC_PROXY2_TLV_SUBTYPE_TLS_CN */
    695 	assert_true(cbarg.tls_subtlvs == 2);
    696 
    697 	assert_true(cbarg.tls_version.length == strlen(tls_version));
    698 	assert_true(memcmp(cbarg.tls_version.base, tls_version,
    699 			   strlen(tls_version)) == 0);
    700 
    701 	assert_true(cbarg.tls_common_name.length == strlen(tls_cn));
    702 	assert_true(memcmp(cbarg.tls_common_name.base, tls_cn,
    703 			   strlen(tls_cn)) == 0);
    704 }
    705 
    706 static bool
    707 rebuild_subtlv_iter_cb(const uint8_t client, const bool client_cert_verified,
    708 		       const isc_proxy2_tlv_subtype_tls_t tls_subtlv_type,
    709 		       const isc_region_t *restrict data, void *cbarg) {
    710 	isc_result_t result;
    711 	isc_buffer_t *outbuf = (isc_buffer_t *)cbarg;
    712 
    713 	UNUSED(client);
    714 	UNUSED(client_cert_verified);
    715 
    716 	result = isc_proxy2_append_tlv(outbuf, tls_subtlv_type, data);
    717 	assert_true(result == ISC_R_SUCCESS);
    718 
    719 	return true;
    720 }
    721 
    722 static bool
    723 rebuild_tlv_iter_cb(const isc_proxy2_tlv_type_t tlv_type,
    724 		    const isc_region_t *restrict data, void *cbarg) {
    725 	isc_result_t result;
    726 	isc_buffer_t *outbuf = (isc_buffer_t *)cbarg;
    727 
    728 	if (tlv_type == ISC_PROXY2_TLV_TYPE_TLS) {
    729 		uint8_t client_flags = 0;
    730 		bool client_cert_verified = false;
    731 		isc_buffer_t databuf = { 0 };
    732 		isc_region_t region = { 0 };
    733 		uint8_t storage[ISC_PROXY2_MAX_SIZE];
    734 
    735 		isc_buffer_init(&databuf, (void *)storage, sizeof(storage));
    736 
    737 		/* get flags values */
    738 		result = isc_proxy2_subtlv_tls_header_data(
    739 			data, &client_flags, &client_cert_verified);
    740 		assert_true(result == ISC_R_SUCCESS);
    741 
    742 		/* create header */
    743 		result = isc_proxy2_make_tls_subheader(
    744 			&databuf, client_flags, client_cert_verified, NULL);
    745 		assert_true(result == ISC_R_SUCCESS);
    746 
    747 		/* process and append values */
    748 		result = isc_proxy2_subtlv_tls_iterate(
    749 			data, rebuild_subtlv_iter_cb, &databuf);
    750 		assert_true(result == ISC_R_SUCCESS);
    751 
    752 		isc_buffer_usedregion(&databuf, &region);
    753 		result = isc_proxy2_header_append_tlv(outbuf, tlv_type,
    754 						      &region);
    755 		assert_true(result == ISC_R_SUCCESS);
    756 	} else {
    757 		result = isc_proxy2_header_append_tlv(outbuf, tlv_type, data);
    758 		assert_true(result == ISC_R_SUCCESS);
    759 	}
    760 
    761 	return true;
    762 }
    763 
    764 static void
    765 proxy2_handler_rebuild_cb(const isc_result_t header_result,
    766 			  const isc_proxy2_command_t cmd, const int socktype,
    767 			  const isc_sockaddr_t *restrict src_addr,
    768 			  const isc_sockaddr_t *restrict dst_addr,
    769 			  const isc_region_t *restrict tlv_blob,
    770 			  const isc_region_t *restrict extra, void *cbarg) {
    771 	isc_result_t result;
    772 	isc_buffer_t *outbuf = (isc_buffer_t *)cbarg;
    773 
    774 	if (header_result != ISC_R_SUCCESS) {
    775 		return;
    776 	}
    777 
    778 	result = isc_proxy2_make_header(outbuf, cmd, socktype, src_addr,
    779 					dst_addr, NULL);
    780 	assert_true(result == ISC_R_SUCCESS);
    781 
    782 	if (tlv_blob != NULL) {
    783 		isc_proxy2_tlv_iterate(tlv_blob, rebuild_tlv_iter_cb, outbuf);
    784 	}
    785 
    786 	if (extra != NULL) {
    787 		result = isc_proxy2_tlv_data_verify(tlv_blob);
    788 		assert_true(result == ISC_R_SUCCESS);
    789 		isc_buffer_putmem(outbuf, extra->base, extra->length);
    790 	}
    791 }
    792 
    793 static void
    794 proxy2_handler_rebuild(isc_buffer_t *restrict outbuf, const void *data,
    795 		       const size_t size) {
    796 	isc_proxy2_handler_t handler = { 0 };
    797 
    798 	isc_proxy2_handler_init(&handler, mctx, 0, proxy2_handler_rebuild_cb,
    799 				outbuf);
    800 
    801 	isc_proxy2_handler_push_data(&handler, data, size);
    802 
    803 	isc_proxy2_handler_uninit(&handler);
    804 }
    805 
    806 static void
    807 try_rebuild_header(const void *data, size_t size) {
    808 	isc_buffer_t databuf = { 0 };
    809 	isc_region_t region = { 0 };
    810 	uint8_t storage[ISC_PROXY2_MAX_SIZE];
    811 
    812 	isc_buffer_init(&databuf, (void *)storage, sizeof(storage));
    813 
    814 	proxy2_handler_rebuild(&databuf, data, size);
    815 	isc_buffer_usedregion(&databuf, &region);
    816 	assert_true(region.length == size);
    817 	assert_true(memcmp(region.base, data, size) == 0);
    818 }
    819 
    820 ISC_RUN_TEST_IMPL(proxyheader_rebuild_header_test) {
    821 	try_rebuild_header(proxy_v2_header, sizeof(proxy_v2_header));
    822 	try_rebuild_header(proxy_v2_header_with_TLS,
    823 			   sizeof(proxy_v2_header_with_TLS));
    824 	try_rebuild_header(proxy_v2_header_with_TLS_CN,
    825 			   sizeof(proxy_v2_header_with_TLS_CN));
    826 }
    827 
    828 ISC_RUN_TEST_IMPL(proxyheader_bad_header_signature_test) {
    829 	size_t i;
    830 	isc_result_t result;
    831 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    832 
    833 	for (i = 0; i < ISC_PROXY2_HEADER_SIGNATURE_SIZE; i++) {
    834 		uint8_t sig[ISC_PROXY2_HEADER_SIGNATURE_SIZE];
    835 		memmove(sig, ISC_PROXY2_HEADER_SIGNATURE,
    836 			ISC_PROXY2_HEADER_SIGNATURE_SIZE);
    837 		sig[i] = 0x0C; /* 0x0C cannot be found in the signature */
    838 		result = isc_proxy2_handler_push_data(handler, sig,
    839 						      sizeof(sig));
    840 		assert_true(result == ISC_R_UNEXPECTED);
    841 		isc_proxy2_handler_clear(handler);
    842 	}
    843 
    844 	result = isc_proxy2_handler_push_data(handler,
    845 					      ISC_PROXY2_HEADER_SIGNATURE,
    846 					      ISC_PROXY2_HEADER_SIGNATURE_SIZE);
    847 	assert_true(result == ISC_R_NOMORE);
    848 }
    849 
    850 ISC_RUN_TEST_IMPL(proxyheader_bad_proto_version_command_test) {
    851 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    852 	isc_result_t result;
    853 	uint8_t *pver_cmd = NULL;
    854 	uint8_t botched_header[sizeof(proxy_v2_header)] = { 0 };
    855 
    856 	memmove(botched_header, proxy_v2_header, sizeof(proxy_v2_header));
    857 
    858 	pver_cmd = &botched_header[ISC_PROXY2_HEADER_SIGNATURE_SIZE];
    859 
    860 	assert_true(*pver_cmd == 0x21);
    861 
    862 	*pver_cmd = 0x31; /* unexpected version (3) followed by PROXY command */
    863 
    864 	result = isc_proxy2_handler_push_data(handler, botched_header,
    865 					      sizeof(botched_header));
    866 	assert_true(result == ISC_R_NOTIMPLEMENTED);
    867 
    868 	*pver_cmd = 0x22; /* version two followed by unexpected command (2) */
    869 
    870 	result = isc_proxy2_handler_push_data(handler, botched_header,
    871 					      sizeof(botched_header));
    872 	assert_true(result == ISC_R_UNEXPECTED);
    873 }
    874 
    875 ISC_RUN_TEST_IMPL(proxyheader_bad_family_socktype_test) {
    876 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    877 	isc_result_t result;
    878 	uint8_t *pfam = NULL;
    879 	uint8_t botched_header[sizeof(proxy_v2_header)] = { 0 };
    880 
    881 	memmove(botched_header, proxy_v2_header, sizeof(proxy_v2_header));
    882 
    883 	pfam = &botched_header[ISC_PROXY2_HEADER_SIGNATURE_SIZE + 1];
    884 
    885 	assert_true(*pfam == 0x11);
    886 
    887 	*pfam = 0x41; /* unexpected family (4) followed by SOCK_STREAM (1)*/
    888 
    889 	result = isc_proxy2_handler_push_data(handler, botched_header,
    890 					      sizeof(botched_header));
    891 	assert_true(result == ISC_R_UNEXPECTED);
    892 
    893 	*pfam = 0x13; /* AF_INET (1) followed by unexpected sock type (3) */
    894 
    895 	result = isc_proxy2_handler_push_data(handler, botched_header,
    896 					      sizeof(botched_header));
    897 	assert_true(result == ISC_R_UNEXPECTED);
    898 }
    899 
    900 static inline void
    901 update_header_length(uint8_t *botched_header, uint16_t newlen) {
    902 	newlen = htons(newlen);
    903 	memmove(&botched_header[ISC_PROXY2_HEADER_SIGNATURE_SIZE + 2], &newlen,
    904 		sizeof(newlen));
    905 }
    906 
    907 ISC_RUN_TEST_IMPL(proxyheader_bad_unexpected_not_enough_length_test) {
    908 	isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state;
    909 	isc_result_t result;
    910 	uint8_t botched_header[sizeof(proxy_v2_header)] = { 0 };
    911 
    912 	memmove(botched_header, proxy_v2_header, sizeof(proxy_v2_header));
    913 
    914 	update_header_length(botched_header, 0);
    915 	result = isc_proxy2_handler_push_data(handler, botched_header,
    916 					      sizeof(botched_header));
    917 	assert_true(result == ISC_R_RANGE);
    918 
    919 	update_header_length(botched_header, 4); /* not enough */
    920 	result = isc_proxy2_handler_push_data(handler, botched_header,
    921 					      sizeof(botched_header));
    922 	assert_true(result == ISC_R_RANGE);
    923 
    924 	update_header_length(botched_header, UINT16_MAX); /* no more */
    925 	result = isc_proxy2_handler_push_data(handler, botched_header,
    926 					      sizeof(botched_header));
    927 	assert_true(result == ISC_R_NOMORE);
    928 	isc_proxy2_handler_clear(handler);
    929 }
    930 
    931 ISC_RUN_TEST_IMPL(proxyheader_tlv_data_test) {
    932 	isc_result_t result;
    933 	isc_buffer_t databuf = { 0 };
    934 	isc_buffer_t tlsbuf = { 0 };
    935 	uint8_t data[ISC_PROXY2_MAX_SIZE] = { 0 };
    936 	uint8_t tlsdata[ISC_PROXY2_MAX_SIZE] = { 0 };
    937 	uint8_t zerodata[0xff] = { 0 };
    938 	isc_region_t region = { 0 };
    939 	const char *alpn = "dot";
    940 	const char *tls_version = "TLSv1.3";
    941 	const char *tls_cn = "name.test";
    942 
    943 	isc_buffer_init(&databuf, (void *)data, sizeof(data));
    944 	isc_buffer_init(&tlsbuf, (void *)tlsdata, sizeof(tlsdata));
    945 
    946 	/* zero filled data is not fine */
    947 	region.base = zerodata;
    948 	region.length = sizeof(zerodata);
    949 	result = isc_proxy2_tlv_data_verify(&region);
    950 	assert_true(result == ISC_R_UNEXPECTED);
    951 
    952 	/* crc32c must be 4 bytes long */
    953 	isc_buffer_clear(&databuf);
    954 	region.base = (uint8_t *)zerodata;
    955 	region.length = sizeof(zerodata);
    956 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_CRC32C,
    957 				       &region);
    958 	assert_true(result == ISC_R_SUCCESS);
    959 	isc_buffer_usedregion(&databuf, &region);
    960 
    961 	result = isc_proxy2_tlv_data_verify(&region);
    962 	assert_true(result == ISC_R_RANGE);
    963 
    964 	isc_buffer_clear(&databuf);
    965 	region.base = (uint8_t *)zerodata;
    966 	region.length = 4;
    967 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_CRC32C,
    968 				       &region);
    969 	assert_true(result == ISC_R_SUCCESS);
    970 	isc_buffer_usedregion(&databuf, &region);
    971 
    972 	result = isc_proxy2_tlv_data_verify(&region);
    973 	assert_true(result == ISC_R_SUCCESS);
    974 
    975 	/* unique id must be <= 128 bytes long */
    976 	isc_buffer_clear(&databuf);
    977 	region.base = (uint8_t *)zerodata;
    978 	region.length = sizeof(zerodata);
    979 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_UNIQUE_ID,
    980 				       &region);
    981 	assert_true(result == ISC_R_SUCCESS);
    982 	isc_buffer_usedregion(&databuf, &region);
    983 
    984 	result = isc_proxy2_tlv_data_verify(&region);
    985 	assert_true(result == ISC_R_RANGE);
    986 
    987 	isc_buffer_clear(&databuf);
    988 	region.base = (uint8_t *)zerodata;
    989 	region.length = 128;
    990 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_UNIQUE_ID,
    991 				       &region);
    992 	assert_true(result == ISC_R_SUCCESS);
    993 	isc_buffer_usedregion(&databuf, &region);
    994 
    995 	result = isc_proxy2_tlv_data_verify(&region);
    996 	assert_true(result == ISC_R_SUCCESS);
    997 
    998 	/* two noops is fine */
    999 	isc_buffer_clear(&databuf);
   1000 	region = (isc_region_t){ 0 };
   1001 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_NOOP,
   1002 				       &region);
   1003 	assert_true(result == ISC_R_SUCCESS);
   1004 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_NOOP,
   1005 				       &region);
   1006 	assert_true(result == ISC_R_SUCCESS);
   1007 	isc_buffer_usedregion(&databuf, &region);
   1008 
   1009 	result = isc_proxy2_tlv_data_verify(&region);
   1010 	assert_true(result == ISC_R_SUCCESS);
   1011 
   1012 	/* one ALPN tag is fine */
   1013 	isc_buffer_clear(&databuf);
   1014 	result = isc_proxy2_append_tlv_string(&databuf,
   1015 					      ISC_PROXY2_TLV_TYPE_ALPN, alpn);
   1016 	assert_true(result == ISC_R_SUCCESS);
   1017 
   1018 	isc_buffer_usedregion(&databuf, &region);
   1019 	result = isc_proxy2_tlv_data_verify(&region);
   1020 	assert_true(result == ISC_R_SUCCESS);
   1021 
   1022 	/* two ALPN tags is not fine */
   1023 	result = isc_proxy2_append_tlv_string(&databuf,
   1024 					      ISC_PROXY2_TLV_TYPE_ALPN, alpn);
   1025 	assert_true(result == ISC_R_SUCCESS);
   1026 
   1027 	isc_buffer_usedregion(&databuf, &region);
   1028 	result = isc_proxy2_tlv_data_verify(&region);
   1029 	assert_true(result == ISC_R_UNEXPECTED);
   1030 
   1031 	/* empty TLS subheader is tolerable */
   1032 	isc_buffer_clear(&databuf);
   1033 	isc_buffer_clear(&tlsbuf);
   1034 	result = isc_proxy2_make_tls_subheader(&tlsbuf, 0, false, NULL);
   1035 	assert_true(result == ISC_R_SUCCESS);
   1036 	isc_buffer_usedregion(&tlsbuf, &region);
   1037 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1038 				       &region);
   1039 	assert_true(result == ISC_R_SUCCESS);
   1040 	isc_buffer_usedregion(&databuf, &region);
   1041 	result = isc_proxy2_tlv_data_verify(&region);
   1042 	assert_true(result == ISC_R_SUCCESS);
   1043 
   1044 	/* empty TLS subheader with no TLS version while one is expected */
   1045 	isc_buffer_clear(&databuf);
   1046 	isc_buffer_clear(&tlsbuf);
   1047 	result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS,
   1048 					       false, NULL);
   1049 	assert_true(result == ISC_R_SUCCESS);
   1050 	isc_buffer_usedregion(&tlsbuf, &region);
   1051 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1052 				       &region);
   1053 	assert_true(result == ISC_R_SUCCESS);
   1054 	isc_buffer_usedregion(&databuf, &region);
   1055 	result = isc_proxy2_tlv_data_verify(&region);
   1056 	assert_true(result == ISC_R_UNEXPECTED);
   1057 
   1058 	/* TLS subheader with TLS version */
   1059 	isc_buffer_clear(&databuf);
   1060 	isc_buffer_clear(&tlsbuf);
   1061 	result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS,
   1062 					       false, NULL);
   1063 	assert_true(result == ISC_R_SUCCESS);
   1064 	region.length = sizeof(tls_version);
   1065 	result = isc_proxy2_append_tlv_string(
   1066 		&tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version);
   1067 	assert_true(result == ISC_R_SUCCESS);
   1068 	isc_buffer_usedregion(&tlsbuf, &region);
   1069 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1070 				       &region);
   1071 	assert_true(result == ISC_R_SUCCESS);
   1072 	isc_buffer_usedregion(&databuf, &region);
   1073 	result = isc_proxy2_tlv_data_verify(&region);
   1074 	assert_true(result == ISC_R_SUCCESS);
   1075 
   1076 	/* TLS subheader with multiple TLS versions is not fine */
   1077 	isc_buffer_clear(&databuf);
   1078 	isc_buffer_clear(&tlsbuf);
   1079 	result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS,
   1080 					       false, NULL);
   1081 	assert_true(result == ISC_R_SUCCESS);
   1082 	result = isc_proxy2_append_tlv_string(
   1083 		&tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version);
   1084 	assert_true(result == ISC_R_SUCCESS);
   1085 	result = isc_proxy2_append_tlv(
   1086 		&tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, &region);
   1087 	assert_true(result == ISC_R_SUCCESS);
   1088 	isc_buffer_usedregion(&tlsbuf, &region);
   1089 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1090 				       &region);
   1091 	assert_true(result == ISC_R_SUCCESS);
   1092 	isc_buffer_usedregion(&databuf, &region);
   1093 	result = isc_proxy2_tlv_data_verify(&region);
   1094 	assert_true(result == ISC_R_UNEXPECTED);
   1095 
   1096 	/* TLS subheader with unexpected TLS version */
   1097 	isc_buffer_clear(&databuf);
   1098 	isc_buffer_clear(&tlsbuf);
   1099 	result = isc_proxy2_make_tls_subheader(&tlsbuf, 0, false, NULL);
   1100 	assert_true(result == ISC_R_SUCCESS);
   1101 	result = isc_proxy2_append_tlv_string(
   1102 		&tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version);
   1103 	assert_true(result == ISC_R_SUCCESS);
   1104 	isc_buffer_usedregion(&tlsbuf, &region);
   1105 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1106 				       &region);
   1107 	assert_true(result == ISC_R_SUCCESS);
   1108 	isc_buffer_usedregion(&databuf, &region);
   1109 	result = isc_proxy2_tlv_data_verify(&region);
   1110 	assert_true(result == ISC_R_UNEXPECTED);
   1111 
   1112 	/* TLS subheader with no CN while expected */
   1113 	isc_buffer_clear(&databuf);
   1114 	isc_buffer_clear(&tlsbuf);
   1115 	result = isc_proxy2_make_tls_subheader(
   1116 		&tlsbuf, ISC_PROXY2_CLIENT_TLS | ISC_PROXY2_CLIENT_CERT_CONN,
   1117 		false, NULL);
   1118 	assert_true(result == ISC_R_SUCCESS);
   1119 	result = isc_proxy2_append_tlv_string(
   1120 		&tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version);
   1121 	assert_true(result == ISC_R_SUCCESS);
   1122 	isc_buffer_usedregion(&tlsbuf, &region);
   1123 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1124 				       &region);
   1125 	assert_true(result == ISC_R_SUCCESS);
   1126 	isc_buffer_usedregion(&databuf, &region);
   1127 	result = isc_proxy2_tlv_data_verify(&region);
   1128 	assert_true(result == ISC_R_UNEXPECTED);
   1129 
   1130 	/* TLS subheader with unexpected CN */
   1131 	isc_buffer_clear(&databuf);
   1132 	isc_buffer_clear(&tlsbuf);
   1133 	result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS,
   1134 					       false, NULL);
   1135 	assert_true(result == ISC_R_SUCCESS);
   1136 	result = isc_proxy2_append_tlv_string(
   1137 		&tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_CN, tls_cn);
   1138 	assert_true(result == ISC_R_SUCCESS);
   1139 	isc_buffer_usedregion(&tlsbuf, &region);
   1140 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1141 				       &region);
   1142 	assert_true(result == ISC_R_SUCCESS);
   1143 	isc_buffer_usedregion(&databuf, &region);
   1144 	result = isc_proxy2_tlv_data_verify(&region);
   1145 	assert_true(result == ISC_R_UNEXPECTED);
   1146 
   1147 	/* TLS subheader with CN unexpected (because TLS flag is not set) */
   1148 	isc_buffer_clear(&databuf);
   1149 	isc_buffer_clear(&tlsbuf);
   1150 	result = isc_proxy2_make_tls_subheader(
   1151 		&tlsbuf,
   1152 		ISC_PROXY2_CLIENT_CERT_CONN | ISC_PROXY2_CLIENT_CERT_SESS,
   1153 		false, NULL);
   1154 	assert_true(result == ISC_R_SUCCESS);
   1155 	result = isc_proxy2_append_tlv_string(
   1156 		&tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_CN, tls_cn);
   1157 	assert_true(result == ISC_R_SUCCESS);
   1158 	isc_buffer_usedregion(&tlsbuf, &region);
   1159 	assert_true(result == ISC_R_SUCCESS);
   1160 	isc_buffer_usedregion(&tlsbuf, &region);
   1161 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1162 				       &region);
   1163 	assert_true(result == ISC_R_SUCCESS);
   1164 	isc_buffer_usedregion(&databuf, &region);
   1165 	result = isc_proxy2_tlv_data_verify(&region);
   1166 	assert_true(result == ISC_R_UNEXPECTED);
   1167 
   1168 	/* botched TLV header */
   1169 	isc_buffer_clear(&databuf);
   1170 	region.base = (uint8_t *)zerodata;
   1171 	region.length = sizeof(zerodata);
   1172 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_NOOP,
   1173 				       &region);
   1174 	isc_buffer_subtract(&databuf, region.length / 2);
   1175 	isc_buffer_usedregion(&databuf, &region);
   1176 	result = isc_proxy2_tlv_data_verify(&region);
   1177 	assert_true(result == ISC_R_RANGE);
   1178 }
   1179 
   1180 ISC_TEST_LIST_START
   1181 ISC_TEST_ENTRY_CUSTOM(proxyheader_generic_test, setup_test_proxy,
   1182 		      teardown_test_proxy)
   1183 ISC_TEST_ENTRY_CUSTOM(proxyheader_generic_byte_by_byte_test, setup_test_proxy,
   1184 		      teardown_test_proxy)
   1185 ISC_TEST_ENTRY_CUSTOM(proxyheader_generic_torn_apart_randomly_test,
   1186 		      setup_test_proxy, teardown_test_proxy)
   1187 ISC_TEST_ENTRY_CUSTOM(proxyheader_direct_test, setup_test_proxy,
   1188 		      teardown_test_proxy)
   1189 ISC_TEST_ENTRY_CUSTOM(proxyheader_detect_bad_signature_test, setup_test_proxy,
   1190 		      teardown_test_proxy)
   1191 ISC_TEST_ENTRY_CUSTOM(proxyheader_extra_data_test, setup_test_proxy,
   1192 		      teardown_test_proxy)
   1193 ISC_TEST_ENTRY_CUSTOM(proxyheader_max_size_test, setup_test_proxy,
   1194 		      teardown_test_proxy)
   1195 ISC_TEST_ENTRY_CUSTOM(proxyheader_make_header_test, setup_test_proxy,
   1196 		      teardown_test_proxy)
   1197 ISC_TEST_ENTRY_CUSTOM(proxyheader_rebuild_header_test, setup_test_proxy,
   1198 		      teardown_test_proxy)
   1199 ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_header_signature_test, setup_test_proxy,
   1200 		      teardown_test_proxy)
   1201 ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_proto_version_command_test,
   1202 		      setup_test_proxy, teardown_test_proxy)
   1203 ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_family_socktype_test, setup_test_proxy,
   1204 		      teardown_test_proxy)
   1205 ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_unexpected_not_enough_length_test,
   1206 		      setup_test_proxy, teardown_test_proxy)
   1207 ISC_TEST_ENTRY_CUSTOM(proxyheader_tlv_data_test, setup_test_proxy,
   1208 		      teardown_test_proxy)
   1209 ISC_TEST_LIST_END
   1210 
   1211 ISC_TEST_MAIN
   1212