New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC8768: Add in support for CoAP Option Hop Limit loop detection #476
Conversation
include/coap2/uri.h
Outdated
@@ -79,17 +82,36 @@ coap_uri_t *coap_clone_uri(const coap_uri_t *uri); | |||
* Parses a given string into URI components. The identified syntactic | |||
* components are stored in the result parameter @p uri. Optional URI | |||
* components that are not specified will be set to { 0, 0 }, except for the | |||
* port which is set to @c COAP_DEFAULT_PORT. This function returns @p 0 if | |||
* parsing succeeded, a value less than zero otherwise. | |||
* port which is set to default port for the protocol. This function returns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"to default port for the protocol" → "to the default port for the protocol"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected
f9507bb
to
d90b9ae
Compare
Pushed code with proxy specific code abstracted to #511 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the commit message, 2nd para: "Incoming requests are check" → "Incoming requests are checked".
I was wondering if the new function coap_insert_option()
should at least be part of the internal API to enable unit tests against this function. I tested a little this way but would like to see more test coverage.
examples/client.c
Outdated
default: | ||
; | ||
default: | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this makes no difference in the generated code: Why would you have a break
statement here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I adjusted the indentation spacing and out of habit put in the break. Updated
examples/client.c
Outdated
value = atoi(arg); | ||
|
||
value = strtol(optarg, NULL, 10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should have been a mix of these two statements:
value = strtol(arg, NULL, 10);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct - well spotted.
include/coap2/pdu.h
Outdated
#define COAP_OPTION_CONTENT_FORMAT 12 /* E, uint, 0-2 B, (none) */ | ||
/* | ||
* The C, U, and N flags indicate the properties | ||
* Critical, UnSafe, and NoCacheKey, respectively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"UnSafe" → "Unsafe"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected
include/coap2/pdu.h
Outdated
#define COAP_OPTION_LOCATION_QUERY 20 /* ___RE__, String, 0-255 B, (none) */ | ||
#define COAP_OPTION_PROXY_URI 35 /* CU-___U, String, 1-1034 B, (none) */ | ||
#define COAP_OPTION_PROXY_SCHEME 39 /* CU-___U, String, 1-255 B, (none) */ | ||
#define COAP_OPTION_SIZE1 60 /* __N_E_U, uint, 0-4 B, (none) */ | ||
|
||
/* option types from RFC 7641 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thinking aloud: When doing the re-ordering anyway, do we want to move the option numbers from extensions to the previous "Core CoAP list" and just note the extension RFC in the comment of each option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had done this in man/coap_pdu_setup.txt.in. Moved the code from there into pdu.h
src/net.c
Outdated
coap_log(LOG_WARNING, "cannot send response for transaction %u\n", | ||
pdu->tid); | ||
} | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This statement is superfluous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return;
deleted
tests/test_pdu.c
Outdated
static void | ||
t_encode_pdu15(void) { | ||
coap_optlist_t *optlist = NULL; | ||
int n; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you make n
of data type size_t
you wont need casting to int
all the time in the following.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated as suggested
tests/test_pdu.c
Outdated
@@ -790,6 +789,40 @@ t_encode_pdu14(void) { | |||
coap_delete_optlist(optlist); | |||
} | |||
|
|||
static void | |||
t_encode_pdu15(void) { | |||
coap_optlist_t *optlist = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since optlist
is not used in this function it can be deleted here as can the call to coap_delete_optlist()
at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected
Corrected
It now is - as well as a new internal helper function coap_update_option(). Test have been added for this. Code changes pushed. |
Builds failed if tests/testdriver was not built against the static libraries. Now fixed by allowing coap_insert_option() and coap_update_option() to be exposed in the .so file. Perhaps in the future the test suite is built against the library files that expose all the internal functions so that the internal API functions can be properly tested. The external API can then be a suitably restricted subset of functions that the applications should be using. |
By making the following change (.la -> .a), the tests can make use of options that are not exposed to general applications (it requires that --enable-static is set)
Is it worth doing this as a separate option? |
Regarding static builds for unit tests: I think it is reasonable to enforce |
99c3b0a
to
6fd45b2
Compare
examples/client.c
Outdated
value = strtol(arg, NULL, 10); | ||
if (value < 1 || value > 255) { | ||
fprintf(stderr, "Hop Limit has to be > 0 and < 256\n"); | ||
exit(-1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I advise against functions that have a hard program termination as side-effect. If you really need the program to terminate (instead of, say, give a warning that the default value is used due to a wrong parameter), I suggest to indicate via return value that the function arguments were not processed. And then, in the main switch statement, exit
may be called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code updated (and pushed) along the suggested lines
All this is handled by libcoap with coap-client having the ability to define an initial Hop Count value for testing. No other application support is required. Incoming requests are checked for the Hop Limit option - if found, the value is decremented in the PDU before passing it up to the application. If it decrements to 0, a 5.08 response is generated. coap_add_option() checks if this is a Proxy option for a request. If so, and Hop Limit option does not exist, then the Hop Limit option is inserted into the PDU with the default value (16). coap_send() checks if it is a 5.08 response and if so, prepends the diagnostic data with the IP address of the transmitting interface. If the IP address already exists, then the PDU is dropped as the return path for the 5.08 response is looping. An alternative method for return path looping check is also used by initially setting, then testing and then decrementing the Hop Limit value as response packets pass back through the proxies. If a proxy does not copy the Hop Limit options when returning the 5.08 response, then the IP address duplication is used. Makefile.am: Hide the coap_insert_option(), coap_update_option and coap_pdu_check_resize() function from applications. README.md: Add in RFC8768 is supported by libcoap. examples/client.c: Add in the -H hoplimit option. include/coap2/pdu.h: Add in the default Hop-Limit: option COAP_OPTION_HOP_LIMIT. Re-organize the COAP_OPTION_ descriptions to include the C, U, N, R, E, I and U flags. Expose the internal coap_pdu_check_resize() function so src/net.c can use it. Define the two new internal functions coap_insert_option() and coap_update_option() and expose them so that the test suites can use them. man/coap-client.txt.in: Document the new -H hoplimit option. man/coap.txt.in: Include the new RFC8768. man/coap_pdu_setup.txt.in: Update documentation for the CoAP options. src/coap_debug.c: Add in support for printing out COAP_OPTION_HOP_LIMIT. src/net.c: Make sure that COAP_OPTION_HOP_LIMIT is not returned in an error response. Decrement received Hop-limit in handle_request() and generate 5.08 response if appropriate. Update coap_send() to prepend IP in 5.08 response. Support COAP_OPTION_HOP_LIMIT being used in the 5.08 response message. src/pdu.c: Report on CoAP options that are repeated, but not defined as repeatable. Define new (5.08) Hop Limit Reached error response. Add in new internal coap_insert_option() function. This now means that callers of coap_add_option() no longer have to have the options in the correct order. Add in new internal coap_update_option() function that updates the value of an option. Make coap_pdu_check_resize() non-static. tests/test_pdu.c: Check that options are getting inserted in the correct order when using coap_insert_option(), even though they are provided in a random order. Test the coap_update_option() function.
PR obgm#476 added in coap_insert_option() which could be called by coap_add_option() with with a coap_log() message set to LOG_DEBUG. When PR obgm#539 was merged in, this upped the logging level to LOG_WARNING which now causes test/testdriver to report unecessary messages. Logging level reverted to LOG_DEBUG.
All this is handled by libcoap with coap-client having the ability to define
an initial Hop Count value for testing. No other application support is
required.
Incoming requests are checked for the Hop Limit option - if found, the value
is decremented in the PDU before passing it up to the application. If it
decrements to 0, a 5.08 response is generated.
coap_add_option() checks if this is a Proxy option for a request. If so, and
Hop Limit option does not exist, then the Hop Limit option is inserted into
the PDU with the default value (16).
coap_send() checks if it is a 5.08 response and if so, prepends the diagnostic
data with the IP address of the transmitting interface. If the IP address
already exists, then the PDU is dropped as the return path for the 5.08 response
is looping. An alternative method for return path looping check is also
used by initially setting, then testing and then decrementing the Hop Limit
value as response packets pass back through the proxies. If a proxy does not
copy the Hop Limit options when returning the 5.08 response, then the IP address
duplication is used.
Makefile.am:
Hide the coap_insert_option(), coap_update_option and coap_pdu_check_resize()
function from applications.
README.md:
Add in RFC8768 is supported by libcoap.
examples/client.c:
Add in the -H hoplimit option.
include/coap2/pdu.h:
Add in the default Hop-Limit: option COAP_OPTION_HOP_LIMIT.
Re-organize the COAP_OPTION_ descriptions to include
the C, U, N, R, E, I and U flags.
Expose the internal coap_pdu_check_resize() function so src/net.c can use it.
Define the two new internal functions coap_insert_option() and
coap_update_option() and expose them so that the test suites can use them.
man/coap-client.txt.in:
Document the new -H hoplimit option.
man/coap.txt.in:
Include the new RFC8768.
man/coap_pdu_setup.txt.in:
Update documentation for the CoAP options.
src/coap_debug.c:
Add in support for printing out COAP_OPTION_HOP_LIMIT.
src/net.c:
Make sure that COAP_OPTION_HOP_LIMIT is not returned in an error response.
Decrement received Hop-limit in handle_request() and generate 5.08 response
if appropriate.
Update coap_send() to prepend IP in 5.08 response.
Support COAP_OPTION_HOP_LIMIT being used in the 5.08 response message.
src/pdu.c:
Report on CoAP options that are repeated, but not defined as repeatable.
Define new (5.08) Hop Limit Reached error response.
Add in new internal coap_insert_option() function. This now means that
callers of coap_add_option() no longer have to have the options in the
correct order.
Add in new internal coap_update_option() function that updates the value of
an option.
Make coap_pdu_check_resize() non-static.
tests/test_pdu.c:
Check that options are getting inserted in the correct order when using
coap_insert_option(), even though they are provided in a random order.
Test the coap_update_option() function.