Skip to content

Commit af024f9

Browse files
committed
Connection-ID: Only change source port when CID has been negotiated
Only support changing the client's source port if the DTLS library has support / configured for CID. Used when debugging server handling source address changes and CID is in use. Add in support for TinyDTLS (Client only) if TinyDTLS is patched appropriately (not currently available on TinyDTLS main branch). Add in new function coap_dtls_cid_is_supported().
1 parent 83718a6 commit af024f9

18 files changed

+351
-23
lines changed

examples/coap-client.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -1924,8 +1924,12 @@ main(int argc, char **argv) {
19241924
coap_register_nack_handler(ctx, nack_handler);
19251925
if (the_token.length > COAP_TOKEN_DEFAULT_MAX)
19261926
coap_context_set_max_token_size(ctx, the_token.length);
1927-
if (cid_every)
1928-
coap_context_set_cid_tuple_change(ctx, cid_every);
1927+
if (cid_every) {
1928+
if (!coap_context_set_cid_tuple_change(ctx, cid_every)) {
1929+
coap_log_warn("coap_context_set_cid_tuple_change: "
1930+
"Unable to set CID tuple change\n");
1931+
}
1932+
}
19291933

19301934
session = get_session(ctx,
19311935
node_str[0] ? node_str : NULL,

include/coap3/coap_dtls.h

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
* @{
3030
*/
3131

32+
int coap_dtls_cid_is_supported(void);
33+
3234
typedef struct coap_dtls_pki_t coap_dtls_pki_t;
3335

3436
#ifndef COAP_DTLS_HINT_LENGTH

include/coap3/coap_dtls_internal.h

+11
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,17 @@ int coap_dtls_define_issue(coap_define_issue_key_t type,
481481
coap_dtls_key_t *key,
482482
const coap_dtls_role_t role,
483483
int ret);
484+
485+
/**
486+
* Set the Connection ID client tuple frequency change for testing CIDs.
487+
*
488+
* @param context The coap_context_t object.
489+
* @param every Change the client's source port @p every packets sent.
490+
*
491+
* @return @c 1 if frequency change set (CID supported), else @c 0.
492+
*/
493+
int coap_dtls_set_cid_tuple_change(coap_context_t *context, uint8_t every);
494+
484495
/** @} */
485496

486497
#endif /* COAP_DTLS_INTERNAL_H */

include/coap3/coap_net.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,10 @@ void coap_context_set_keepalive(coap_context_t *context, unsigned int seconds);
235235
*
236236
* @param context The coap_context_t object.
237237
* @param every Change the client's source port @p every packets sent.
238+
*
239+
* @return @c 1 if frequency change set (CID supported), else @c 0.
238240
*/
239-
void coap_context_set_cid_tuple_change(coap_context_t *context, uint8_t every);
241+
int coap_context_set_cid_tuple_change(coap_context_t *context, uint8_t every);
240242

241243
/**
242244
* Set the maximum token size (RFC8974).

include/coap3/coap_session_internal.h

+4
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ struct coap_session_t {
203203
#endif /* COAP_OSCORE_SUPPORT */
204204
volatile uint8_t max_token_checked; /**< Check for max token size
205205
coap_ext_token_check_t */
206+
#if COAP_CLIENT_SUPPORT
207+
uint8_t negotiated_cid; /**< Set for a client if CID negotiated */
208+
#endif /* COAP_CLIENT_SUPPORT */
209+
uint8_t is_dtls13; /**< Set if session is DTLS1.3 */
206210
coap_mid_t remote_test_mid; /**< mid used for checking remote
207211
support */
208212
uint32_t max_token_size; /**< Largest token size supported RFC8974 */

libcoap-3.map

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ global:
8181
coap_delete_str_const;
8282
coap_delete_string;
8383
coap_delete_uri;
84+
coap_dtls_cid_is_supported;
8485
coap_dtls_get_log_level;
8586
coap_dtls_is_supported;
8687
coap_dtls_pkcs11_is_supported;

libcoap-3.sym

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ coap_delete_resource
7979
coap_delete_str_const
8080
coap_delete_string
8181
coap_delete_uri
82+
coap_dtls_cid_is_supported
8283
coap_dtls_get_log_level
8384
coap_dtls_is_supported
8485
coap_dtls_pkcs11_is_supported

man/coap_context.txt.in

+5-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ size_t _max_token_size_);*
6565

6666
*void *coap_context_get_app_data(const coap_context_t *_context_);*
6767

68-
*void coap_context_set_cid_tuple_change(coap_context_t *_context_context, uint8_t _every_);*
68+
*int coap_context_set_cid_tuple_change(coap_context_t *_context_context, uint8_t _every_);*
6969

7070
For specific (D)TLS library support, link with
7171
*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*,
@@ -190,7 +190,8 @@ pointer previously defined by *coap_context_set_app_data*().
190190

191191
The *coap_context_set_cid_tuple_change*() function is used to define to a client
192192
to force the client's port to change _every_ packets sent, providing the ability
193-
to test a CID (RFC9146) enabled server.
193+
to test a CID (RFC9146) enabled server. Only supported by DTLS libraries that
194+
support CID.
194195

195196
RETURN VALUES
196197
-------------
@@ -211,6 +212,8 @@ out an idle server session.
211212

212213
*coap_context_get_app_data*() returns a previously defined pointer.
213214

215+
*coap_context_set_cid_tuple_change*() returns 1 on success, else 0;
216+
214217
SEE ALSO
215218
--------
216219
*coap_session*(3)

src/coap_debug.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ coap_string_tls_support(char *buffer, size_t bufsize) {
12331233
const int have_pki = coap_dtls_pki_is_supported();
12341234
const int have_pkcs11 = coap_dtls_pkcs11_is_supported();
12351235
const int have_rpk = coap_dtls_rpk_is_supported();
1236+
const int have_cid = coap_dtls_cid_is_supported();
12361237
const int have_oscore = coap_oscore_is_supported();
12371238
const int have_ws = coap_ws_is_supported();
12381239

@@ -1241,13 +1242,14 @@ coap_string_tls_support(char *buffer, size_t bufsize) {
12411242
return buffer;
12421243
}
12431244
snprintf(buffer, bufsize,
1244-
"(%sDTLS and %sTLS support; %sPSK, %sPKI, %sPKCS11, and %sRPK support)\n(%sOSCORE)\n(%sWebSockets)",
1245+
"(%sDTLS and %sTLS support; %sPSK, %sPKI, %sPKCS11, %sRPK and %sCID support)\n(%sOSCORE)\n(%sWebSockets)",
12451246
have_dtls ? "" : "No ",
12461247
have_tls ? "" : "no ",
12471248
have_psk ? "" : "no ",
12481249
have_pki ? "" : "no ",
12491250
have_pkcs11 ? "" : "no ",
12501251
have_rpk ? "" : "no ",
1252+
have_cid ? "" : "no ",
12511253
have_oscore ? "Have " : "No ",
12521254
have_ws ? "Have " : "No ");
12531255
return buffer;

src/coap_gnutls.c

+18
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,24 @@ coap_dtls_rpk_is_supported(void) {
243243
#endif /* GNUTLS_VERSION_NUMBER < 0x030606 */
244244
}
245245

246+
/*
247+
* return 0 failed
248+
* 1 passed
249+
*/
250+
int
251+
coap_dtls_cid_is_supported(void) {
252+
return 0;
253+
}
254+
255+
#if COAP_CLIENT_SUPPORT
256+
int
257+
coap_dtls_set_cid_tuple_change(coap_context_t *c_context, uint8_t every) {
258+
(void)c_context;
259+
(void)every;
260+
return 0;
261+
}
262+
#endif /* COAP_CLIENT_SUPPORT */
263+
246264
coap_tls_version_t *
247265
coap_get_tls_library_version(void) {
248266
static coap_tls_version_t version;

src/coap_io.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,9 @@ static uint32_t cid_track_counter;
782782
static void
783783
coap_test_cid_tuple_change(coap_session_t *session) {
784784
if (session->type == COAP_SESSION_TYPE_CLIENT &&
785+
session->negotiated_cid &&
785786
session->state == COAP_SESSION_STATE_ESTABLISHED &&
786-
COAP_PROTO_NOT_RELIABLE(session->proto) && session->context->testing_cids) {
787+
session->proto == COAP_PROTO_DTLS && session->context->testing_cids) {
787788
if ((++cid_track_counter) % session->context->testing_cids == 0) {
788789
coap_address_t local_if = session->addr_info.local;
789790
uint16_t port = coap_address_get_port(&local_if);

src/coap_mbedtls.c

+52
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,31 @@ do_mbedtls_handshake(coap_session_t *c_session,
14671467
coap_log_debug("* %s: Mbed TLS established\n",
14681468
coap_session_str(c_session));
14691469
ret = 1;
1470+
#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1471+
#if COAP_CLIENT_SUPPORT
1472+
if (c_session->type == COAP_SESSION_TYPE_CLIENT &&
1473+
c_session->proto == COAP_PROTO_DTLS) {
1474+
coap_mbedtls_context_t *m_context;
1475+
1476+
m_context = (coap_mbedtls_context_t *)c_session->context->dtls_context;
1477+
if ((m_context->psk_pki_enabled & IS_PSK && c_session->cpsk_setup_data.use_cid) ||
1478+
m_context->setup_data.use_cid) {
1479+
unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];
1480+
int enabled;
1481+
size_t peer_cid_len;
1482+
1483+
/* See whether CID was negotiated */
1484+
if (mbedtls_ssl_get_peer_cid(&m_env->ssl, &enabled, peer_cid, &peer_cid_len) == 0 &&
1485+
enabled == MBEDTLS_SSL_CID_ENABLED) {
1486+
c_session->negotiated_cid = 1;
1487+
} else {
1488+
coap_log_info("** %s: CID was not negotiated\n", coap_session_str(c_session));
1489+
c_session->negotiated_cid = 0;
1490+
}
1491+
}
1492+
}
1493+
#endif /* COAP_CLIENT_SUPPORT */
1494+
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
14701495
break;
14711496
case MBEDTLS_ERR_SSL_WANT_READ:
14721497
case MBEDTLS_ERR_SSL_WANT_WRITE:
@@ -1886,6 +1911,33 @@ coap_dtls_rpk_is_supported(void) {
18861911
return 0;
18871912
}
18881913

1914+
/*
1915+
* return 0 failed
1916+
* 1 passed
1917+
*/
1918+
int
1919+
coap_dtls_cid_is_supported(void) {
1920+
#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1921+
return 1;
1922+
#else /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1923+
return 0;
1924+
#endif /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1925+
}
1926+
1927+
#if COAP_CLIENT_SUPPORT
1928+
int
1929+
coap_dtls_set_cid_tuple_change(coap_context_t *c_context, uint8_t every) {
1930+
#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1931+
c_context->testing_cids = every;
1932+
return 1;
1933+
#else /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1934+
(void)c_context;
1935+
(void)every;
1936+
return 0;
1937+
#endif /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1938+
}
1939+
#endif /* COAP_CLIENT_SUPPORT */
1940+
18891941
void *
18901942
coap_dtls_new_context(coap_context_t *c_context) {
18911943
coap_mbedtls_context_t *m_context;

src/coap_net.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -459,13 +459,14 @@ coap_context_set_keepalive(coap_context_t *context, unsigned int seconds) {
459459
context->ping_timeout = seconds;
460460
}
461461

462-
void
462+
int
463463
coap_context_set_cid_tuple_change(coap_context_t *context, uint8_t every) {
464464
#if COAP_CLIENT_SUPPORT
465-
context->testing_cids = every;
465+
return coap_dtls_set_cid_tuple_change(context, every);
466466
#else /* ! COAP_CLIENT_SUPPORT */
467467
(void)context;
468468
(void)every;
469+
return 0;
469470
#endif /* ! COAP_CLIENT_SUPPORT */
470471
}
471472

src/coap_notls.c

+18
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,24 @@ coap_dtls_rpk_is_supported(void) {
7878
return 0;
7979
}
8080

81+
/*
82+
* return 0 failed
83+
* 1 passed
84+
*/
85+
int
86+
coap_dtls_cid_is_supported(void) {
87+
return 0;
88+
}
89+
90+
#if COAP_CLIENT_SUPPORT
91+
int
92+
coap_dtls_set_cid_tuple_change(coap_context_t *c_context, uint8_t every) {
93+
(void)c_context;
94+
(void)every;
95+
return 0;
96+
}
97+
#endif /* COAP_CLIENT_SUPPORT */
98+
8199
coap_tls_version_t *
82100
coap_get_tls_library_version(void) {
83101
static coap_tls_version_t version;

src/coap_openssl.c

+18
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,24 @@ coap_dtls_rpk_is_supported(void) {
256256
return 0;
257257
}
258258

259+
/*
260+
* return 0 failed
261+
* 1 passed
262+
*/
263+
int
264+
coap_dtls_cid_is_supported(void) {
265+
return 0;
266+
}
267+
268+
#if COAP_CLIENT_SUPPORT
269+
int
270+
coap_dtls_set_cid_tuple_change(coap_context_t *c_context, uint8_t every) {
271+
(void)c_context;
272+
(void)every;
273+
return 0;
274+
}
275+
#endif /* COAP_CLIENT_SUPPORT */
276+
259277
coap_tls_version_t *
260278
coap_get_tls_library_version(void) {
261279
static coap_tls_version_t version;

src/coap_session.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,7 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint,
11481148
#define DTLS_HT_CLIENT_HELLO 1 /* Client Hello handshake type */
11491149
#define DTLS_CT_CID 25 /* Content Type Connection ID */
11501150
#define OFF_CID 11 /* offset of CID in dtls_record_handshake_t */
1151+
#define OFF_CID_DTLS13 1 /* offset of CID in DTLS1.3 Unified Header */
11511152

11521153
const uint8_t *payload = (const uint8_t *)packet->payload;
11531154
size_t length = packet->length;
@@ -1157,18 +1158,24 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint,
11571158
OFF_HANDSHAKE_TYPE + 1);
11581159
return NULL;
11591160
}
1160-
if (payload[OFF_CONTENT_TYPE] == DTLS_CT_CID) {
1161+
if ((payload[OFF_CONTENT_TYPE] & 0x30) == 0x30 ||
1162+
payload[OFF_CONTENT_TYPE] == DTLS_CT_CID) {
11611163
/* Client may have changed its IP address */
11621164
int changed = 0;
11631165

11641166
SESSIONS_ITER(endpoint->sessions, session, rtmp) {
11651167
if (session->client_cid) {
1166-
if (memcmp(session->client_cid->s, &payload[OFF_CID],
1167-
session->client_cid->length) == 0) {
1168+
if ((session->is_dtls13 && (payload[OFF_CONTENT_TYPE] & 0x30) == 0x30 &&
1169+
memcmp(session->client_cid->s, &payload[OFF_CID_DTLS13],
1170+
session->client_cid->length) == 0) ||
1171+
(!session->is_dtls13 && payload[OFF_CONTENT_TYPE] == DTLS_CT_CID &&
1172+
memcmp(session->client_cid->s, &payload[OFF_CID],
1173+
session->client_cid->length) == 0)) {
11681174
/* Updating IP address */
11691175
coap_log_info("***%s: CID: Old Client Session\n", coap_session_str(session));
11701176
SESSIONS_DELETE(endpoint->sessions, session);
11711177
session->addr_info = packet->addr_info;
1178+
memcpy(&session->addr_hash, &addr_hash, sizeof(session->addr_hash));
11721179
SESSIONS_ADD(endpoint->sessions, session);
11731180
coap_log_info("***%s: CID: New Client Session\n", coap_session_str(session));
11741181
return session;
@@ -1184,7 +1191,8 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint,
11841191
/* only log if not a late alert */
11851192
if (payload[OFF_CONTENT_TYPE] != DTLS_CT_ALERT)
11861193
coap_log_debug("coap_dtls_hello: ContentType %d Handshake %d dropped\n",
1187-
payload[OFF_CONTENT_TYPE], payload[OFF_HANDSHAKE_TYPE]);
1194+
payload[OFF_CONTENT_TYPE],
1195+
payload[OFF_HANDSHAKE_TYPE]);
11881196
return NULL;
11891197
}
11901198
}

0 commit comments

Comments
 (0)