1 /* coap_session.h -- Session management for libcoap 2 * 3 * Copyright (C) 2017 Jean-Claue Michelou <jcm@spinetix.com> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 * 7 * This file is part of the CoAP library libcoap. Please see 8 * README for terms of use. 9 */ 10 11 /** 12 * @file coap_session.h 13 * @brief Defines the application visible session information 14 */ 15 16 #ifndef COAP_SESSION_H_ 17 #define COAP_SESSION_H_ 18 19 /** 20 * @defgroup session Sessions 21 * API functions for CoAP Sessions 22 * @{ 23 */ 24 25 /** 26 * Abstraction of a fixed point number that can be used where necessary instead 27 * of a float. 1,000 fractional bits equals one integer 28 */ 29 typedef struct coap_fixed_point_t { 30 uint16_t integer_part; /**< Integer part of fixed point variable */ 31 uint16_t fractional_part; /**< Fractional part of fixed point variable 32 1/1000 (3 points) precision */ 33 } coap_fixed_point_t; 34 35 #define COAP_PROTO_NOT_RELIABLE(p) ((p)==COAP_PROTO_UDP || (p)==COAP_PROTO_DTLS) 36 #define COAP_PROTO_RELIABLE(p) ((p)==COAP_PROTO_TCP || (p)==COAP_PROTO_TLS) 37 38 /** 39 * coap_session_type_t values 40 */ 41 typedef enum coap_session_type_t { 42 COAP_SESSION_TYPE_NONE = 0, /**< Not defined */ 43 COAP_SESSION_TYPE_CLIENT, /**< client-side */ 44 COAP_SESSION_TYPE_SERVER, /**< server-side */ 45 COAP_SESSION_TYPE_HELLO, /**< server-side ephemeral session for 46 responding to a client hello */ 47 } coap_session_type_t; 48 49 /** 50 * coap_session_state_t values 51 */ 52 typedef enum coap_session_state_t { 53 COAP_SESSION_STATE_NONE = 0, 54 COAP_SESSION_STATE_CONNECTING, 55 COAP_SESSION_STATE_HANDSHAKE, 56 COAP_SESSION_STATE_CSM, 57 COAP_SESSION_STATE_ESTABLISHED, 58 } coap_session_state_t; 59 60 /** 61 * Increment reference counter on a session. 62 * 63 * @param session The CoAP session. 64 * @return same as session 65 */ 66 coap_session_t *coap_session_reference(coap_session_t *session); 67 68 /** 69 * Decrement reference counter on a session. 70 * Note that the session may be deleted as a result and should not be used 71 * after this call. 72 * 73 * @param session The CoAP session. 74 */ 75 void coap_session_release(coap_session_t *session); 76 77 /** 78 * Notify session that it has failed. This cleans up any outstanding / queued 79 * transmissions, observations etc.. 80 * 81 * @param session The CoAP session. 82 * @param reason The reason why the session was disconnected. 83 */ 84 void coap_session_disconnected(coap_session_t *session, 85 coap_nack_reason_t reason); 86 87 /** 88 * Stores @p data with the given session. This function overwrites any value 89 * that has previously been stored with @p session. 90 * 91 * @param session The CoAP session. 92 * @param data The pointer to the data to store. 93 */ 94 void coap_session_set_app_data(coap_session_t *session, void *data); 95 96 /** 97 * Returns any application-specific data that has been stored with @p 98 * session using the function coap_session_set_app_data(). This function will 99 * return @c NULL if no data has been stored. 100 * 101 * @param session The CoAP session. 102 * 103 * @return Pointer to the stored data or @c NULL. 104 */ 105 void *coap_session_get_app_data(const coap_session_t *session); 106 107 /** 108 * Get the remote IP address from the session. 109 * 110 * @param session The CoAP session. 111 * 112 * @return The session's remote address or @c NULL on failure. 113 */ 114 const coap_address_t *coap_session_get_addr_remote( 115 const coap_session_t *session); 116 117 /** 118 * Get the local IP address from the session. 119 * 120 * @param session The CoAP session. 121 * 122 * @return The session's local address or @c NULL on failure. 123 */ 124 const coap_address_t *coap_session_get_addr_local( 125 const coap_session_t *session); 126 127 /** 128 * Get the session protocol type 129 * 130 * @param session The CoAP session. 131 * 132 * @return The session's protocol type 133 */ 134 coap_proto_t coap_session_get_proto(const coap_session_t *session); 135 136 /** 137 * Get the session type 138 * 139 * @param session The CoAP session. 140 * 141 * @return The session's type 142 */ 143 coap_session_type_t coap_session_get_type(const coap_session_t *session); 144 145 /** 146 * Get the session state 147 * 148 * @param session The CoAP session. 149 * 150 * @return The session's state 151 */ 152 coap_session_state_t coap_session_get_state(const coap_session_t *session); 153 154 /** 155 * Get the session if index 156 * 157 * @param session The CoAP session. 158 * 159 * @return The session's if index, or @c -1 on error. 160 */ 161 int coap_session_get_ifindex(const coap_session_t *session); 162 163 /** 164 * Get the session TLS security ptr (TLS type dependent) 165 * 166 * OpenSSL: SSL* 167 * GnuTLS: gnutls_session_t (implicit *) 168 * Mbed TLS: mbedtls_ssl_context* 169 * TinyDTLS: struct dtls_context* 170 * 171 * @param session The CoAP session. 172 * @param tls_lib Updated with the library type. 173 * 174 * @return The session TLS ptr or @c NULL if not set up 175 */ 176 void *coap_session_get_tls(const coap_session_t *session, 177 coap_tls_library_t *tls_lib); 178 179 /** 180 * Get the session context 181 * 182 * @param session The CoAP session. 183 * 184 * @return The session's context 185 */ 186 coap_context_t *coap_session_get_context(const coap_session_t *session); 187 188 /** 189 * Set the session type to client. Typically used in a call-home server. 190 * The session needs to be of type COAP_SESSION_TYPE_SERVER. 191 * Note: If this function is successful, the session reference count is 192 * incremented and a subsequent coap_session_release() taking the 193 * reference count to 0 will cause the session to be freed off. 194 * 195 * @param session The CoAP session. 196 * 197 * @return @c 1 if updated, @c 0 on failure. 198 */ 199 int coap_session_set_type_client(coap_session_t *session); 200 201 /** 202 * Set the session MTU. This is the maximum message size that can be sent, 203 * excluding IP and UDP overhead. 204 * 205 * @param session The CoAP session. 206 * @param mtu maximum message size 207 */ 208 void coap_session_set_mtu(coap_session_t *session, unsigned mtu); 209 210 /** 211 * Get maximum acceptable PDU size 212 * 213 * @param session The CoAP session. 214 * @return maximum PDU size, not including header (but including token). 215 */ 216 size_t coap_session_max_pdu_size(const coap_session_t *session); 217 218 /** 219 * Creates a new client session to the designated server. 220 * @param ctx The CoAP context. 221 * @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. 222 * @param server The server's address. If the port number is zero, the default port for the protocol will be used. 223 * @param proto Protocol. 224 * 225 * @return A new CoAP session or NULL if failed. Call coap_session_release to free. 226 */ 227 coap_session_t *coap_new_client_session( 228 coap_context_t *ctx, 229 const coap_address_t *local_if, 230 const coap_address_t *server, 231 coap_proto_t proto 232 ); 233 234 /** 235 * Creates a new client session to the designated server with PSK credentials 236 * @param ctx The CoAP context. 237 * @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. 238 * @param server The server's address. If the port number is zero, the default port for the protocol will be used. 239 * @param proto Protocol. 240 * @param identity PSK client identity 241 * @param key PSK shared key 242 * @param key_len PSK shared key length 243 * 244 * @return A new CoAP session or NULL if failed. Call coap_session_release to free. 245 */ 246 coap_session_t *coap_new_client_session_psk( 247 coap_context_t *ctx, 248 const coap_address_t *local_if, 249 const coap_address_t *server, 250 coap_proto_t proto, 251 const char *identity, 252 const uint8_t *key, 253 unsigned key_len 254 ); 255 256 /** 257 * Creates a new client session to the designated server with PSK credentials 258 * @param ctx The CoAP context. 259 * @param local_if Address of local interface. It is recommended to use NULL to 260 * let the operating system choose a suitable local interface. 261 * If an address is specified, the port number should be zero, 262 * which means that a free port is automatically selected. 263 * @param server The server's address. If the port number is zero, the default 264 * port for the protocol will be used. 265 * @param proto CoAP Protocol. 266 * @param setup_data PSK parameters. 267 * 268 * @return A new CoAP session or NULL if failed. Call coap_session_release() 269 * to free. 270 */ 271 coap_session_t *coap_new_client_session_psk2( 272 coap_context_t *ctx, 273 const coap_address_t *local_if, 274 const coap_address_t *server, 275 coap_proto_t proto, 276 coap_dtls_cpsk_t *setup_data 277 ); 278 279 /** 280 * Get the server session's current Identity Hint (PSK). 281 * 282 * @param session The current coap_session_t object. 283 * 284 * @return @c hint if successful, else @c NULL. 285 */ 286 const coap_bin_const_t * coap_session_get_psk_hint( 287 const coap_session_t *session); 288 289 /** 290 * Get the session's current pre-shared key (PSK). 291 * 292 * @param session The current coap_session_t object. 293 * 294 * @return @c psk_key if successful, else @c NULL. 295 */ 296 const coap_bin_const_t * coap_session_get_psk_key( 297 const coap_session_t *session); 298 299 /** 300 * Creates a new client session to the designated server with PKI credentials 301 * @param ctx The CoAP context. 302 * @param local_if Address of local interface. It is recommended to use NULL to 303 * let the operating system choose a suitable local interface. 304 * If an address is specified, the port number should be zero, 305 * which means that a free port is automatically selected. 306 * @param server The server's address. If the port number is zero, the default 307 * port for the protocol will be used. 308 * @param proto CoAP Protocol. 309 * @param setup_data PKI parameters. 310 * 311 * @return A new CoAP session or NULL if failed. Call coap_session_release() 312 * to free. 313 */ 314 coap_session_t *coap_new_client_session_pki( 315 coap_context_t *ctx, 316 const coap_address_t *local_if, 317 const coap_address_t *server, 318 coap_proto_t proto, 319 coap_dtls_pki_t *setup_data 320 ); 321 322 /** 323 * Initializes the token value to use as a starting point. 324 * 325 * @param session The current coap_session_t object. 326 * @param length The length of the token (0 - 8 bytes). 327 * @param token The token data. 328 * 329 */ 330 void coap_session_init_token(coap_session_t *session, size_t length, 331 const uint8_t *token); 332 333 /** 334 * Creates a new token for use. 335 * 336 * @param session The current coap_session_t object. 337 * @param length Updated with the length of the new token. 338 * @param token Updated with the new token data (must be 8 bytes long). 339 * 340 */ 341 void coap_session_new_token(coap_session_t *session, size_t *length, 342 uint8_t *token); 343 344 /** 345 * @ingroup logging 346 * Get session description. 347 * 348 * @param session The CoAP session. 349 * @return description string. 350 */ 351 const char *coap_session_str(const coap_session_t *session); 352 353 /** 354 * Create a new endpoint for communicating with peers. 355 * 356 * @param context The coap context that will own the new endpoint 357 * @param listen_addr Address the endpoint will listen for incoming requests on or originate outgoing requests from. Use NULL to specify that no incoming request will be accepted and use a random endpoint. 358 * @param proto Protocol used on this endpoint 359 */ 360 361 coap_endpoint_t *coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto); 362 363 /** 364 * Set the endpoint's default MTU. This is the maximum message size that can be 365 * sent, excluding IP and UDP overhead. 366 * 367 * @param endpoint The CoAP endpoint. 368 * @param mtu maximum message size 369 */ 370 void coap_endpoint_set_default_mtu(coap_endpoint_t *endpoint, unsigned mtu); 371 372 void coap_free_endpoint(coap_endpoint_t *ep); 373 374 /** @} */ 375 376 /** 377 * @ingroup logging 378 * Get endpoint description. 379 * 380 * @param endpoint The CoAP endpoint. 381 * @return description string. 382 */ 383 const char *coap_endpoint_str(const coap_endpoint_t *endpoint); 384 385 coap_session_t *coap_session_get_by_peer(const coap_context_t *ctx, 386 const coap_address_t *remote_addr, int ifindex); 387 388 /** 389 * @defgroup cc Rate Control 390 * The transmission parameters for CoAP rate control ("Congestion 391 * Control" in stream-oriented protocols) are defined in 392 * https://tools.ietf.org/html/rfc7252#section-4.8 393 * @{ 394 */ 395 396 /** 397 * Number of seconds when to expect an ACK or a response to an 398 * outstanding CON message. 399 * RFC 7252, Section 4.8 Default value of ACK_TIMEOUT is 2 400 * 401 * Configurable using coap_session_set_ack_timeout() 402 */ 403 #define COAP_DEFAULT_ACK_TIMEOUT ((coap_fixed_point_t){2,0}) 404 405 /** 406 * A factor that is used to randomize the wait time before a message 407 * is retransmitted to prevent synchronization effects. 408 * RFC 7252, Section 4.8 Default value of ACK_RANDOM_FACTOR is 1.5 409 * 410 * Configurable using coap_session_set_ack_random_factor() 411 */ 412 #define COAP_DEFAULT_ACK_RANDOM_FACTOR ((coap_fixed_point_t){1,500}) 413 414 /** 415 * Number of message retransmissions before message sending is stopped 416 * RFC 7252, Section 4.8 Default value of MAX_RETRANSMIT is 4 417 * 418 * Configurable using coap_session_set_max_retransmit() 419 */ 420 #define COAP_DEFAULT_MAX_RETRANSMIT 4 421 422 /** 423 * The number of simultaneous outstanding interactions that a client 424 * maintains to a given server. 425 * RFC 7252, Section 4.8 Default value of NSTART is 1 426 */ 427 #define COAP_DEFAULT_NSTART 1 428 429 /** 430 * The maximum number of seconds before sending back a response to a 431 * multicast request. 432 * RFC 7252, Section 4.8 DEFAULT_LEISURE is 5. 433 */ 434 #ifndef COAP_DEFAULT_LEISURE 435 #define COAP_DEFAULT_LEISURE (5U) 436 #endif /* COAP_DEFAULT_LEISURE */ 437 438 /** 439 * The MAX_TRANSMIT_SPAN definition for the session (s). 440 * 441 * RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_SPAN 442 * ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT)) - 1) * ACK_RANDOM_FACTOR 443 */ 444 #define COAP_MAX_TRANSMIT_SPAN(s) \ 445 ((s->ack_timeout.integer_part * 1000 + s->ack_timeout.fractional_part) * \ 446 ((1 << (s->max_retransmit)) -1) * \ 447 (s->ack_random_factor.integer_part * 1000 + \ 448 s->ack_random_factor.fractional_part) \ 449 / 1000000) 450 451 /** 452 * The MAX_TRANSMIT_WAIT definition for the session (s). 453 * 454 * RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_WAIT 455 * ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT + 1)) - 1) * ACK_RANDOM_FACTOR 456 */ 457 #define COAP_MAX_TRANSMIT_WAIT(s) \ 458 ((s->ack_timeout.integer_part * 1000 + s->ack_timeout.fractional_part) * \ 459 ((1 << (s->max_retransmit + 1)) -1) * \ 460 (s->ack_random_factor.integer_part * 1000 + \ 461 s->ack_random_factor.fractional_part) \ 462 / 1000000) 463 464 /** 465 * The MAX_LATENCY definition. 466 * RFC 7252, Section 4.8.2 MAX_LATENCY is 100. 467 */ 468 #define COAP_MAX_LATENCY 100 469 470 /** 471 * The PROCESSING_DELAY definition for the session (s). 472 * 473 * RFC 7252, Section 4.8.2 Calculation of PROCESSING_DELAY 474 * PROCESSING_DELAY set to ACK_TIMEOUT 475 */ 476 #define COAP_PROCESSING_DELAY(s) \ 477 ((s->ack_timeout.integer_part * 1000 + s->ack_timeout.fractional_part + 500) \ 478 / 1000) 479 480 /** 481 * The MAX_RTT definition for the session (s). 482 * 483 * RFC 7252, Section 4.8.2 Calculation of MAX_RTT 484 * (2 * MAX_LATENCY) + PROCESSING_DELAY 485 */ 486 #define COAP_MAX_RTT(s) \ 487 ((2 * COAP_MAX_LATENCY) + COAP_PROCESSING_DELAY(s)) 488 489 /** 490 * The EXCHANGE_LIFETIME definition for the session (s). 491 * 492 * RFC 7252, Section 4.8.2 Calculation of EXCHANGE_LIFETIME 493 * MAX_TRANSMIT_SPAN + (2 * MAX_LATENCY) + PROCESSING_DELAY 494 */ 495 #define COAP_EXCHANGE_LIFETIME(s) \ 496 (COAP_MAX_TRANSMIT_SPAN(s) + (2 * COAP_MAX_LATENCY) + COAP_PROCESSING_DELAY(s)) 497 498 /** 499 * The NON_LIFETIME definition for the session (s). 500 * 501 * RFC 7252, Section 4.8.2 Calculation of NON_LIFETIME 502 * MAX_TRANSMIT_SPAN + MAX_LATENCY 503 */ 504 #define COAP_NON_LIFETIME(s) \ 505 (COAP_MAX_TRANSMIT_SPAN(s) + COAP_MAX_LATENCY) 506 507 /** @} */ 508 509 /** 510 * Set the CoAP maximum retransmit count before failure 511 * 512 * Number of message retransmissions before message sending is stopped 513 * 514 * @param session The CoAP session. 515 * @param value The value to set to. The default is 4 and should not normally 516 * get changed. 517 */ 518 void coap_session_set_max_retransmit(coap_session_t *session, 519 unsigned int value); 520 521 /** 522 * Set the CoAP initial ack response timeout before the next re-transmit 523 * 524 * Number of seconds when to expect an ACK or a response to an 525 * outstanding CON message. 526 * 527 * @param session The CoAP session. 528 * @param value The value to set to. The default is 2 and should not normally 529 * get changed. 530 */ 531 void coap_session_set_ack_timeout(coap_session_t *session, 532 coap_fixed_point_t value); 533 534 /** 535 * Set the CoAP ack randomize factor 536 * 537 * A factor that is used to randomize the wait time before a message 538 * is retransmitted to prevent synchronization effects. 539 * 540 * @param session The CoAP session. 541 * @param value The value to set to. The default is 1.5 and should not normally 542 * get changed. 543 */ 544 void coap_session_set_ack_random_factor(coap_session_t *session, 545 coap_fixed_point_t value); 546 547 /** 548 * Get the CoAP maximum retransmit before failure 549 * 550 * Number of message retransmissions before message sending is stopped 551 * 552 * @param session The CoAP session. 553 * 554 * @return Current maximum retransmit value 555 */ 556 unsigned int coap_session_get_max_retransmit(const coap_session_t *session); 557 558 /** 559 * Get the CoAP initial ack response timeout before the next re-transmit 560 * 561 * Number of seconds when to expect an ACK or a response to an 562 * outstanding CON message. 563 * 564 * @param session The CoAP session. 565 * 566 * @return Current ack response timeout value 567 */ 568 coap_fixed_point_t coap_session_get_ack_timeout(const coap_session_t *session); 569 570 /** 571 * Get the CoAP ack randomize factor 572 * 573 * A factor that is used to randomize the wait time before a message 574 * is retransmitted to prevent synchronization effects. 575 * 576 * @param session The CoAP session. 577 * 578 * @return Current ack randomize value 579 */ 580 coap_fixed_point_t coap_session_get_ack_random_factor( 581 const coap_session_t *session); 582 583 /** 584 * Send a ping message for the session. 585 * @param session The CoAP session. 586 * 587 * @return COAP_INVALID_MID if there is an error 588 */ 589 coap_mid_t coap_session_send_ping(coap_session_t *session); 590 591 #endif /* COAP_SESSION_H */ 592