observe: Add in support for all observe responses to be non-confirmable

https://tools.ietf.org/html/rfc7641#section-4.5 requires that non-confirmable
observe responses should be sent as confirmable at least once every 24 hours.

However there is a requirement to override this periodical confirmable sending
behavior in lossy under DDoS attack type environments.

https://tools.ietf.org/html/draft-ietf-dots-signal-channel-41#section-4.4.2.1

Add in support for, and document, a new coap_resource_init() flag
COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS to handle this non RFC7641 requirement.
This commit is contained in:
Jon Shallow committed 2020-01-13 13:14:25 +00:00
1 parent 03cc5791c5
commit d2f7b4f23a
4 files changed
+38 -12

No files matched your search

+12 -1
View File
@@ -62,15 +62,26 @@ typedef struct coap_attr_t {
/**
* Notifications will be sent non-confirmable by default. RFC 7641 Section 4.5
* https://tools.ietf.org/html/rfc7641#section-4.5
* Libcoap will always send every fifth packet as confirmable.
*/
#define COAP_RESOURCE_FLAGS_NOTIFY_NON 0x0
/**
* Notifications will be sent confirmable by default. RFC 7641 Section 4.5
* Notifications will be sent confirmable. RFC 7641 Section 4.5
* https://tools.ietf.org/html/rfc7641#section-4.5
*/
#define COAP_RESOURCE_FLAGS_NOTIFY_CON 0x2
/**
* Notifications will always be sent non-confirmable. This is in
* violation of RFC 7641 Section 4.5
* https://tools.ietf.org/html/rfc7641#section-4.5
* but required by the DOTS signal channel protocol which needs to operate in
* lossy DDoS attack environments.
* https://tools.ietf.org/html/draft-ietf-dots-signal-channel-41#section-4.4.2.1
*/
#define COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS 0x4
typedef struct coap_resource_t {
unsigned int dirty:1; /**< set to 1 if resource has changed */
unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet
+12 -6
View File
@@ -94,13 +94,19 @@ manage the deletion of the resource at the appropriate time.
*NOTE:* The type (confirmable or non-confirmable) of the triggered observe
GET response is determined not by the initial GET request, but independently
by the server as per RFC 7641 3.5. Transmission. This is controlled by the
flags (one of COAP_RESOURCE_FLAGS_NOTIFY_NON or COAP_RESOURCE_FLAGS_NOTIFY_CON)
by the server as per https://tools.ietf.org/html/rfc7641#section-3.5.
This is controlled by the flags (one of COAP_RESOURCE_FLAGS_NOTIFY_NON,
COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS or COAP_RESOURCE_FLAGS_NOTIFY_CON)
used when creating the resource using *coap_resource_init*(3).
Furthermore, the server must send at least one "observe" response as
confirmable, when generally sending non-confirmable, every 24 hours.
libcoap handles this by sending every fifth (COAP_OBS_MAX_NON) response as a
confirmable response for detection that the client is still responding.
*NOTE:* Furthermore, the server must send at least one "observe" response as
confirmable, when generally sending non-confirmable, at least every 24 hours
as per https://tools.ietf.org/html/rfc7641#section-4.5.
Libcoap automatically handles this by sending every fifth (COAP_OBS_MAX_NON)
response as a confirmable response for detection that the client is still
responding unless if COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS is set, which is a
RFC7641 violation, where non-confirmable "observe" responses are always sent
as required by some higher layer protocols.
The *coap_resource_notify_observers*() function needs to be called whenever the
server application determines that there has been a change to the state of
+9 -2
View File
@@ -84,7 +84,13 @@ _flags_ can be one of the following definitions or'ed together.
[horizontal]
*COAP_RESOURCE_FLAGS_NOTIFY_NON*::
Set the notification message type to non-confirmable for any trigggered
"observe" responses.
"observe" responses with type set to confirmable every 5 packets as required by
https://tools.ietf.org/html/rfc7641#section-4.5.
//-
*COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS*::
Set the notification message type to always non-confirmable for any trigggered
"observe" responses. This should only be used if a upper layer protocol
requires it.
//-
*COAP_RESOURCE_FLAGS_NOTIFY_CON*::
Set the notification message type to confirmable for any trigggered
@@ -120,7 +126,8 @@ _context_ and frees their storage.
The *coap_resource_set_mode*() changes the notification message type of
_resource_ to the given _mode_ which must be one of
COAP_RESOURCE_FLAGS_NOTIFY_NON or COAP_RESOURCE_FLAGS_NOTIFY_CON.
COAP_RESOURCE_FLAGS_NOTIFY_NON, COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS or
COAP_RESOURCE_FLAGS_NOTIFY_CON.
The *coap_resource_set_userdata*() function allows a pointer to user _data_
to be associated with a _resource_ that can accessed in any callback that
+5 -3
View File
@@ -793,8 +793,9 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r) {
token.s = obs->token;
obs->tid = response->tid = coap_new_message_id(obs->session);
if ((r->flags & COAP_RESOURCE_FLAGS_NOTIFY_CON) == 0
&& obs->non_cnt < COAP_OBS_MAX_NON) {
if ((r->flags & COAP_RESOURCE_FLAGS_NOTIFY_CON) == 0 &&
((r->flags & COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS) ||
obs->non_cnt < COAP_OBS_MAX_NON)) {
response->type = COAP_MESSAGE_NON;
} else {
response->type = COAP_MESSAGE_CON;
@@ -805,7 +806,8 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r) {
/* TODO: do not send response and remove observer when
* COAP_RESPONSE_CLASS(response->hdr->code) > 2
*/
if (response->type == COAP_MESSAGE_CON) {
if (response->type == COAP_MESSAGE_CON ||
(r->flags & COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS)) {
obs->non_cnt = 0;
} else {
obs->non_cnt++;