COAP_RECOVERY(3)

πŸ“¦ version 4.2.1, in ubuntu jammy

πŸ’– NAME πŸ’–

coap_recovery, coap_session_set_max_retransmit, coap_session_set_ack_timeout, coap_session_set_ack_random_factor, coap_session_get_max_transmit, coap_session_get_ack_timeout, coap_session_get_ack_random_factor, coap_debug_set_packet_loss β€” bestie, this whole lil crew is all about working with CoAP packet transmissions. That's it, that's the vibe. ✨


✨ SYNOPSIS ✨

#include <coap2/coap.h>

void coap_session_set_max_retransmit(coap_session_t *session, unsigned
int value);

void coap_session_set_ack_timeout(coap_session_t *session,
coap_fixed_point_t value);

void coap_session_set_ack_random_factor(coap_session_t *session,
coap_fixed_point_t value);

unsigned int coap_session_get_max_transmit(coap_session_t *session);

coap_fixed_point_t coap_session_get_ack_timeout(coap_session_t
*session);

coap_fixed_point_t coap_session_get_ack_random_factor(coap_session_t
*session);

int coap_debug_set_packet_loss(const char *loss_level);

And when you link, you link with -lcoap-2, -lcoap-2-gnutls, -lcoap-2-openssl or -lcoap-2-tinydtls β€” whichever one matches your (D)TLS library type. Pick the right one, okay? 🫢


🌸 DESCRIPTION 🌸

So for CoAP Confirmable messages, you can literally define the retry counts, the repeat rate, all of it, for error recovery. The receipts live in "RFC7272: 4.2. Messages Transmitted Reliably". Go read it, iykyk. πŸ“–

Not recommended: changing those suggested default settings. Lowkey just don't. But maybe you have some special requirements that genuinely need different values β€” and in that case only do it if the consequences of changing these values is fully understood. Fully. Periodt.

Also: changing the default values for multicast packets is not supported. Not a thing. Moving on. πŸ’…

Some of the parameters or return values are in fixed point format, defined by the coap_fixed_point_t structure like this:

typedef struct coap_fixed_point_t {
  uint16_t integer_part;    /* Integer part of fixed point variable */
  uint16_t fractional_part; /* Fractional part of fixed point variable
                               1/1000 (3 points) precision */
} coap_fixed_point_t;

Now the CoAP message retry rules, with the default values doing the math for the time:

  • 1st retransmit after 1 * ack_timeout * ack_random factor (3 seconds)
  • 2nd retransmit after 2 * ack_timeout * ack_random factor (6 seconds)
  • 3rd retransmit after 3 * ack_timeout * ack_random factor (12 seconds)
  • 4th retransmit after 4 * ack_timeout * ack_random factor (24 seconds)
  • 5th retransmit after 5 * ack_timeout * ack_random factor (48 seconds)

And because max_transmit is (by default) 4, that 5th retransmit does not get sent β€” but at that exact moment COAP_NACK_TOO_MANY_RETRIES gets raised in the nack_handler (if one is defined). Note that the sum of the seconds is 93, matching RFC7252. Math ate, no cap. πŸ”₯

It should be noted that these retries are separate from the DTLS or TLS encrypted session setup retry timeouts. For DTLS, the initial requesting packet will get sent max_retransmit times before reporting failure. For TLS, the initial TCP connection will timeout before reporting failure. Two different things, don't mix them up bestie. πŸ¦‹

You can also set up packet losses, for both confirmable and non-confirmable messages. This is giving stress testing packet transmission recovery, plus application handling of lossy networks. Iconic for testing honestly.

  • The coap_session_set_max_retransmit() function updates the session maximum retransmit count with the new value. The default value is 4.
  • The coap_session_set_ack_timeout() function updates the session initial ack or response timeout with the new value. The default value is 2.0.
  • The coap_session_set_ack_random_factor() function updates the session ack random wait factor β€” used to randomize re-transmissions β€” with the new value. The default value is 1.5.
  • The coap_session_get_max_retransmit() function returns the current session maximum retransmit count.
  • The coap_session_get_ack_timeout() function returns the current session initial ack or response timeout.
  • The coap_session_get_ack_random_factor() function returns the current session ack random wait factor.
  • The coap_debug_set_packet_loss() function is uses to set the packet loss levels as defined in loss_level. πŸ’€ loss_level can be set as a percentage from "0%" to "100%". Alternatively, it is possible to specify which packets of a packet sequence are dropped. A definition of "1,5-9,11-20,101" means that packets 1, 5 through 9, 11 through 20 and 101 will get dropped. A maximum of 10 different packet sets is supported. The packet count is reset to 0 when coap_debug_set_packet_loss() is called. To remove any packet losses, set the loss_level to "0%".

🌈 RETURN VALUES 🌈

coap_session_get_max_retransmit(), coap_session_get_ack_timeout() and coap_session_get_ack_random_factor() return their respective current values. So cute, so simple. πŸ’œ

coap_debug_set_packet_loss() returns 0 if loss_level does not parse correctly, otherwise 1 if successful.


🧚 TESTING 🧚

Heads up: the libcoap recovery/re-transmit logic will only work for confirmable requests. Only those. πŸ™ˆ

To see what is happening (other than by sniffing the network traffic, which, do you), the logging level needs to be set to LOG_DEBUG in the client by using coap_set_log_level(LOG_DEBUG) and coap_dtls_set_log_level(LOG_DEBUG).

The client needs to be sending confirmable requests during the test. Non-negotiable.

The server can either be stopped, or if packet loss levels are set to 100% by using coap_debug_set_packet_loss("100%") when receiving the client requests.

NOTE: If the server end of the connection is returning ICMP unreachable packets after being turned off, you will get a debug message of the form "coap_network_read: unreachable", so libcoap will stop doing the retries. If this is the case, then you need to make use of (on the server) coap_debug_set_packet_loss("100%") or put in some packet filtering to drop the packets. Do not skip this part bestie, it will ruin your whole test. 😭

The client should then restart transmitting the requests based on the ack_timeout, ack_random_factor and max_retransmit values. The client's nack_handler will get called with COAP_NACK_TOO_MANY_RETRIES when the confirmable request cannot be successfully transmitted. That's your signal, main character moment. ⭐


πŸŽ€ FURTHER INFORMATION πŸŽ€

See "RFC7252: The Constrained Application Protocol (CoAP)" for further information. Go get your reading glasses on. πŸ“š


πŸ’€ BUGS πŸ’€

Please report bugs on the mailing list for libcoap: libcoap-developers@lists.sourceforge.net. Be nice, they're doing their best. 🫢


πŸ‘‘ AUTHORS πŸ‘‘

The libcoap project <libcoap-developers@lists.sourceforge.net>


And that's a wrap, bestie πŸ’– this page is from the libcoap project, coap_recovery version 4.2.1, dated 11/23/2021. Slay, go forth and retransmit responsibly βœ¨πŸ¦‹

πŸ“¦ where this page comes from