Fix final data size in last BLOCK2 response for .well-known/core

src/net.c:

Corect the length for the final block size.

Add in an ETAG and SIZE2 option into the response as suggested by RFC7959.

examples/client.c:

Warn if URI path is too long for internal buffer (found when testing that
a large WellKnown response triggered sending BLOCK2 correctly).

Increase internal buffersize to allow longer URIs.

To reproduce issue

coap-client -b 256 coap://127.0.0.1/.well-known/core

As reported by Zafi Ramarosandratana.  See #360 which this fixes.
This commit is contained in:
Jon Shallow committed 2019-06-20 12:35:57 +01:00
1 parent a5ffdf323d
commit d84ac69b67
2 files changed
+30 -12

No files matched your search

+3 -1
View File
@@ -744,7 +744,7 @@ get_default_port(const coap_uri_t *u) {
static int
cmdline_uri(char *arg, int create_uri_opts) {
unsigned char portbuf[2];
#define BUFSIZE 40
#define BUFSIZE 100
unsigned char _buf[BUFSIZE];
unsigned char *buf = _buf;
size_t buflen;
@@ -795,6 +795,8 @@ cmdline_uri(char *arg, int create_uri_opts) {
if (uri.path.length) {
buflen = BUFSIZE;
if (uri.path.length > BUFSIZE)
coap_log(LOG_WARNING, "URI path will be truncated (max buffer %d)\n", BUFSIZE);
res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
while (res--) {
+27 -11
View File
@@ -1637,7 +1637,7 @@ coap_wellknown_response(coap_context_t *context, coap_session_t *session,
coap_pdu_t *resp;
coap_opt_iterator_t opt_iter;
size_t len, wkc_len;
uint8_t buf[2];
uint8_t buf[4];
int result = 0;
int need_block2 = 0; /* set to 1 if Block2 option is required */
coap_block_t block;
@@ -1691,19 +1691,11 @@ coap_wellknown_response(coap_context_t *context, coap_session_t *session,
* and data. We do this before adding the Content-Format option to
* avoid sending error responses with that option but no actual
* content. */
if (resp->max_size && resp->max_size <= resp->used_size + 3) {
if (resp->max_size && resp->max_size <= resp->used_size + 8) {
coap_log(LOG_DEBUG, "coap_wellknown_response: insufficient storage space\n");
goto error;
}
/* Add Content-Format. As we have checked for available storage,
* nothing should go wrong here. */
assert(coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_APPLICATION_LINK_FORMAT) == 1);
coap_add_option(resp, COAP_OPTION_CONTENT_FORMAT,
coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_APPLICATION_LINK_FORMAT), buf);
/* check if Block2 option is required even if not requested */
if (!need_block2 && resp->max_size && resp->max_size - resp->used_size < wkc_len + 1) {
assert(resp->used_size <= resp->max_size);
@@ -1725,6 +1717,24 @@ coap_wellknown_response(coap_context_t *context, coap_session_t *session,
need_block2 = 1;
}
if (need_block2) {
/* Add in a pseudo etag (use wkc_len) in case .well-known/core
changes over time */
coap_add_option(resp,
COAP_OPTION_ETAG,
coap_encode_var_safe(buf, sizeof(buf), wkc_len),
buf);
}
/* Add Content-Format. As we have checked for available storage,
* nothing should go wrong here. */
assert(coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_APPLICATION_LINK_FORMAT) == 1);
coap_add_option(resp, COAP_OPTION_CONTENT_FORMAT,
coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_APPLICATION_LINK_FORMAT), buf);
/* write Block2 option if necessary */
if (need_block2) {
if (coap_write_block_opt(&block, COAP_OPTION_BLOCK2, resp, wkc_len) < 0) {
@@ -1734,7 +1744,13 @@ coap_wellknown_response(coap_context_t *context, coap_session_t *session,
}
}
len = need_block2 ? SZX_TO_BYTES( block.szx ) :
coap_add_option(resp,
COAP_OPTION_SIZE2,
coap_encode_var_safe(buf, sizeof(buf), wkc_len),
buf);
len = need_block2 ?
min(SZX_TO_BYTES(block.szx), wkc_len - (block.num << (block.szx + 4))) :
resp->max_size && resp->used_size + wkc_len + 1 > resp->max_size ?
resp->max_size - resp->used_size - 1 : wkc_len;
data = coap_add_data_after(resp, len);