Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ The following RFCs are supported

* [RFC9177: Constrained Application Protocol (CoAP) Block-Wise Transfer Options Supporting Robust Transmission](https://rfc-editor.org/rfc/rfc9177)

The following Internet Draft is supported

* [I-D URI-Path abbreviation in CoAP](https://datatracker.ietf.org/doc/html/draft-ietf-core-uri-path-abbrev-02)

There is (D)TLS support for the following libraries

* [OpenSSL](https://www.openssl.org) (Minimum version 1.1.0) [PKI, PSK and PKCS11]
Expand Down
5 changes: 3 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ WARNING_CFLAGS="\
# check whether or not the compiler supports -Wlogical-op (clang does not...)
AX_CHECK_COMPILE_FLAG([-Wlogical-op], [WARNING_CFLAGS="$WARNING_CFLAGS -Wlogical-op"],,[-Werror])
AX_CHECK_COMPILE_FLAG([-fdiagnostics-color], [CFLAGS="$CFLAGS -fdiagnostics-color"],,[-Werror])
AX_CHECK_COMPILE_FLAG([-Wunused-result], [WARNING_CFLAGS="$WARNING_CFLAGS -Wunused-result"])
AX_CHECK_COMPILE_FLAG([-Wunused-result], [WARNING_CFLAGS="$WARNING_CFLAGS -Wunused-result"],,[-Werror])

# clang 14+ generates dwarf-5, which is not currently supported by valgrind
if test "x$CC" = "xclang"; then
Expand Down Expand Up @@ -1409,7 +1409,8 @@ libcoap Configuration Summary:
libcoap ABI version : "$LIBCOAP_ABI_VERSION"
libcoap libtool SO version : "$LIBCOAP_SO_VERSION"
libcoap DTLS lib extn : "$LIBCOAP_DTLS_LIB_EXTENSION_NAME"
host system : "$host"]);
host system : "$host"
compiler : "$CC"]);
if test "x$enable_server_mode" = "xyes"; then
AC_MSG_RESULT([ build with server support : "yes"])
else
Expand Down
4 changes: 4 additions & 0 deletions doc/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ The following RFCs are supported

* [RFC9177: Constrained Application Protocol (CoAP) Block-Wise Transfer Options Supporting Robust Transmission](https://rfc-editor.org/rfc/rfc9177)

The following Internet Draft is supported

* [I-D URI-Path abbreviation in CoAP](https://datatracker.ietf.org/doc/html/draft-ietf-core-uri-path-abbrev-02)

There is (D)TLS support for the following libraries

* [OpenSSL](https://www.openssl.org) (Minimum version 1.1.0) [PKI, PSK and PKCS11]
Expand Down
38 changes: 29 additions & 9 deletions examples/coap-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ int flags = 0;
static coap_session_t *global_session;
static unsigned char _token_data[24]; /* With support for RFC8974 */
static coap_binary_t the_token = { 0, _token_data };
static coap_upa_abbrev_t abbrev_mappings[] = {
{ 0, ".well-known/core" },
{ 1, ".well-known/rd" }
};


typedef struct {
coap_binary_t *token;
Expand Down Expand Up @@ -587,7 +592,7 @@ usage(const char *program, const char *version) {
coap_string_tls_version(buffer, sizeof(buffer)));
fprintf(stderr, "%s\n", coap_string_tls_support(buffer, sizeof(buffer)));
fprintf(stderr, "\n"
"Usage: %s [-a addr] [-b [num,]size] [-e text] [-f file] [-g file]\n"
"Usage: %s [-a addr] [-b [num,]size] [-e text] [-f file] [-g file] [-i]\n"
"\t\t[-l loss] [-m method] [-o file] [-p port] [-q tls_engine_conf_file]\n"
"\t\t[-r] [-s duration] [-t type] [-v num] [-w] [-x] [-y rec_secs]\n"
"\t\t[-z] [-A type] [-B seconds]\n"
Expand All @@ -610,6 +615,7 @@ usage(const char *program, const char *version) {
"\t-f file\t\tFile to send with PUT/POST (use '-' for STDIN)\n"
"\t-g file\t\tFile to send with PUT/POST using individual block\n"
"\t \t\trequest call-back\n"
"\t-i \t\tTest using Uri-Path-Abbrev path mapping\n"
"\t-l list\t\tFail to send some datagrams specified by a comma\n"
"\t \t\tseparated list of numbers or number ranges\n"
"\t \t\t(for debugging only)\n"
Expand Down Expand Up @@ -665,9 +671,9 @@ usage(const char *program, const char *version) {
"\t \t\tcoap+ws, and coaps+ws\n"
"\t-S \t\tUse Proxy-Scheme instead of Proxy-Uri option if -P\n"
"\t \t\toption used\n"
"\t-T token\tDefine the initial starting token (up to 24 characters)\n"
,program, wait_seconds);
fprintf(stderr,
"\t-T token\tDefine the initial starting token (up to 24 characters)\n"
"\t-U \t\tNever include Uri-Host or Uri-Port options\n"
"\t-V num \t\tVerbosity level (default 3, maximum is 7) for (D)TLS\n"
"\t \t\tlibrary logging\n"
Expand Down Expand Up @@ -1935,6 +1941,7 @@ main(int argc, char **argv) {
uint8_t cid_every = 0;
int report_ind_blocks = 0;
coap_pdu_t *resp_pdu;
int use_abbrev = 0;
#ifndef _WIN32
struct sigaction sa;
#endif
Expand All @@ -1950,7 +1957,7 @@ main(int argc, char **argv) {
coap_startup();

while ((opt = getopt(argc, argv,
"a:b:c:d:e:f:g:h:j:k:l:m:no:p:q:rs:t:u:v:wxy:zA:B:C:E:G:H:J:K:L:M:NO:P:R:ST:UV:X:Y23")) != -1) {
"a:b:c:d:e:f:g:h:ij:k:l:m:no:p:q:rs:t:u:v:wxy:zA:B:C:E:G:H:J:K:L:M:NO:P:R:ST:UV:X:Y23")) != -1) {
switch (opt) {
case 'a':
strncpy(node_str, optarg, NI_MAXHOST - 1);
Expand Down Expand Up @@ -1991,6 +1998,9 @@ main(int argc, char **argv) {
if (!cmdline_input_from_file_f(optarg))
payload.length = 0;
break;
case 'i' :
use_abbrev = 1;
break;
case 'j' :
key_file = optarg;
break;
Expand Down Expand Up @@ -2259,12 +2269,22 @@ main(int argc, char **argv) {
coap_session_init_token(session, the_token.length, the_token.s);

/* Convert provided uri into CoAP options */
if (!coap_uri_into_optlist((proxy.host.length && !use_proxy_scheme) ?
&proxy : &uri, !uri_host_option ?
&dst : NULL,
&optlist, create_uri_opts)) {
coap_log_err("Failed to create options for URI\n");
goto failed;
if (use_abbrev) {
if (!coap_uri_into_optlist_abbrev((proxy.host.length && !use_proxy_scheme) ?
&proxy : &uri, !uri_host_option ?
&dst : NULL,
&optlist, create_uri_opts, abbrev_mappings, sizeof(abbrev_mappings)/sizeof(abbrev_mappings[0]))) {
coap_log_err("Failed to create options for URI\n");
goto failed;
}
} else {
if (!coap_uri_into_optlist((proxy.host.length && !use_proxy_scheme) ?
&proxy : &uri, !uri_host_option ?
&dst : NULL,
&optlist, create_uri_opts)) {
coap_log_err("Failed to create options for URI\n");
goto failed;
}
}

/* set block option if requested at commandline */
Expand Down
8 changes: 8 additions & 0 deletions examples/coap-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ static int call_home = 0;
static const char *proxy_add_resource = NULL;
static const char *proxy_add_check = NULL;

static coap_upa_abbrev_t abbrev_mappings[] = {
{ 0, ".well-known/core" },
{ 1000, "example_data" },
{ 1001, "time" }
};

static coap_dtls_pki_t *setup_pki(coap_context_t *ctx, coap_dtls_role_t role, char *sni);

typedef struct psk_sni_def_t {
Expand Down Expand Up @@ -2883,6 +2889,8 @@ main(int argc, char **argv) {
coap_context_set_max_block_size(ctx, max_block_size);
coap_context_set_session_reconnect_time2(ctx, reconnect_secs, 10);
coap_context_set_keepalive(ctx, reconnect_secs ? reconnect_secs : 30);
coap_upa_server_mapping(abbrev_mappings, sizeof(abbrev_mappings)/sizeof(abbrev_mappings[0]));

if (report_each_block)
coap_register_block_data_handler(ctx, individual_blocks);
if (csm_max_message_size)
Expand Down
4 changes: 2 additions & 2 deletions include/coap3/coap_net_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ struct coap_context_t {
#endif /* COAP_CLIENT_SUPPORT */
uint32_t block_mode; /**< Zero or more COAP_BLOCK_ or'd options */
coap_resource_dynamic_create_t dyn_create_handler; /**< Dynamc resource create handler */
uint32_t dynamic_cur; /* Current number of dynamic resources */
uint32_t dynamic_max; /* Max number of dynamic resources or 0 is unlimited */
uint32_t dynamic_cur; /**< Current number of dynamic resources */
uint32_t dynamic_max; /**< Max number of dynamic resources or 0 is unlimited */
};

/**
Expand Down
6 changes: 6 additions & 0 deletions include/coap3/coap_pdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ typedef enum coap_request_t {
#define COAP_OPTION_OSCORE 9 /* C_____U, *, 0-255 B, RFC8613 */
#define COAP_OPTION_URI_PATH 11 /* CU-RE__, String, 0-255 B, RFC7252 */
#define COAP_OPTION_CONTENT_FORMAT 12 /* ____E__, uint, 0-2 B, RFC7252 */
#define COAP_OPTION_URI_PATH_ABB 13 /* C___E__, uint, 0-4 B, RFC TBD */
#define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT
/* COAP_OPTION_MAXAGE default 60 seconds if not set */
#define COAP_OPTION_MAXAGE 14 /* _U-_E_U, uint, 0-4 B, RFC7252 */
Expand Down Expand Up @@ -375,6 +376,11 @@ typedef enum coap_pdu_code_t {
COAP_SIGNALING_CODE_ABORT = COAP_SIGNALING_ABORT
} coap_pdu_code_t;

typedef enum {
COAP_BOOL_FALSE,
COAP_BOOL_TRUE
} coap_bool_t;

/**
* Creates a new CoAP PDU with at least enough storage space for the given
* @p size maximum message size. The function returns a pointer to the
Expand Down
4 changes: 3 additions & 1 deletion include/coap3/coap_pdu_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,14 +440,16 @@ coap_pdu_release_lkd(coap_pdu_t *pdu) {
* @param token The token to use in this duplicated PDU.
* @param drop_options A list of options not to copy into the duplicated PDU.
* If @c NULL, then all options are copied across.
* @param expand_opt_abb If COAP_BOOL_TRUE, try to expand out Uri-Path-Abbrev.
*
* @return The duplicated PDU or @c NULL if failure.
*/
coap_pdu_t *coap_pdu_duplicate_lkd(const coap_pdu_t *old_pdu,
coap_session_t *session,
size_t token_length,
const uint8_t *token,
coap_opt_filter_t *drop_options);
coap_opt_filter_t *drop_options,
coap_bool_t expand_opt_abb);

/**
* Increment reference counter on a pdu to stop it prematurely getting freed off
Expand Down
10 changes: 10 additions & 0 deletions include/coap3/coap_proxy_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,16 @@ void coap_proxy_del_req(coap_proxy_entry_t *proxy_entry, coap_proxy_req_t *prox
void coap_delete_proxy_subscriber(coap_session_t *session, coap_bin_const_t *token,
coap_mid_t mid, coap_proxy_subs_delete_t type);

/**
* coap_proxy_log_entry() is used to log a proxy status
*
* @param incoming The incoming proxy session.
* @param pdu The request PDU.
* @param upstream_token The token used for the ongoing session.
* @param type The change update type.
*/
void coap_proxy_log_entry(coap_session_t *incoming, const coap_pdu_t *pdu,
coap_bin_const_t *upstream_token, const char *type);
/** @} */

#define PROXY_CACHE_ADD(e, obj) \
Expand Down
1 change: 1 addition & 0 deletions include/coap3/coap_session_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ struct coap_session_t {
coap_tick_t doing_first_timeout; /**< If doing_first, when to timeout */
coap_pdu_t *doing_first_pdu; /**< If doing fist, PDU to retry sending */
#endif /* COAP_CLIENT_SUPPORT */
uint8_t no_path_abbrev; /**< Set is remote does not support Uri-Path-Abbrev */
coap_mid_t remote_test_mid; /**< mid used for checking remote
support */
uint32_t max_token_size; /**< Largest token size supported RFC8974 */
Expand Down
75 changes: 75 additions & 0 deletions include/coap3/coap_uri.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ typedef struct {
enum coap_uri_scheme_t scheme;
} coap_uri_t;

typedef struct {
uint32_t upa_value; /**< The Uri-Path-Abbrev option value */
const char *upa_path; /**< The Uri-Path-Abbrev option path representation
(withouot the leading '/') */
} coap_upa_abbrev_t;

static inline int
coap_uri_scheme_is_secure(const coap_uri_t *uri) {
return uri && ((uri->scheme & COAP_URI_SCHEME_SECURE_MASK) != 0);
Expand Down Expand Up @@ -222,6 +228,32 @@ int coap_uri_into_options(const coap_uri_t *uri, const coap_address_t *dst,
int coap_uri_into_optlist(const coap_uri_t *uri, const coap_address_t *dst,
coap_optlist_t **optlist_chain,
int create_port_host_opt);
/**
* Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain.
* If the port is not the default port and create_port_host_opt is not 0, then
* the Uri-Port option is added to the @p optlist_chain.
* If the dst defines an address that does not match the host in uri->host and
* is not 0, then the Uri-Host option is added to the @p optlist_chain.
* Any path or query are broken down into the individual segment Uri-Path
* or Uri-Path-Abbrev (if mapping match) or Uri-Query options and added to
* the @p optlist_chain.
*
* @param uri The coap_uri_t object.
* @param dst The destination, or NULL if URI_HOST not to be added.
* @param optlist_chain Where to store the chain of options.
* @param create_port_host_opt @c 1 if port/host option to be added
* (if non-default) else @c 0.
* @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL.
* (path does not have the leading '/').
* @param count Number of Uri-Path-Abbrev table entries.
*
* @return @c 1 on success, @c 0 if error.
*
*/
int coap_uri_into_optlist_abbrev(const coap_uri_t *uri, const coap_address_t *dst,
coap_optlist_t **optlist_chain,
int create_port_host_opt,
coap_upa_abbrev_t *mapping, uint32_t count);

/**
* Splits the given URI path into segments. Each segment is preceded
Expand Down Expand Up @@ -261,6 +293,28 @@ int coap_split_path(const uint8_t *path,
int coap_path_into_optlist(const uint8_t *path, size_t length,
coap_option_num_t optnum,
coap_optlist_t **optlist_chain);
/**
* Splits the given URI path into '/' separate segments, and then adds
* the Uri-Path / Location-Path option for each segment to the @p optlist_chain.
*
* Note: any segments that are just '.' or '..' are stripped out.
*
* @param path The path string to split.
* @param length The actual length of @p path.
* @param optnum The CoAP option (COAP_OPTION_URI_PATH or
* COAP_OPTION_LOCATION_PATH)
* @param optlist_chain The chain of optlists to add to. optlist_chain
* parent is to be NULL or a previous set of optlists.
* @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL.
* (path does not have the leading '/').
* @param count Number of Uri-Path-Abbrev table entries.
*
* @return @c 1 on success else @c 0 if error.
*/
int coap_path_into_optlist_abbrev(const uint8_t *path, size_t length,
coap_option_num_t optnum,
coap_optlist_t **optlist_chain,
coap_upa_abbrev_t *mapping, uint32_t count);

/**
* Splits the given URI query into segments. Each segment is preceded
Expand Down Expand Up @@ -319,6 +373,27 @@ coap_string_t *coap_get_query(const coap_pdu_t *request);
*/
coap_string_t *coap_get_uri_path(const coap_pdu_t *request);

/**
* Define a Path to use if an Uri-Path-Abbrev option fails and the client
* is to retry the request using Uri-Path instread of Uri-Path-Abbrev.
*
* @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL
if the previous mapping is to be cleared.
* (path does not have the leading '/').
* @param count Number of Uri-Path-Abbrev table entries.
*/
void coap_upa_client_fallback(coap_upa_abbrev_t *mapping, uint32_t count);

/**
* Define a Path to use on receipt of an Uri-Path-Abbrev option value.
*
* @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL
if the previous mapping is to be cleared.
* (path does not have the leading '/').
* @param count Number of Uri-Path-Abbrev table entries.
*/
void coap_upa_server_mapping(coap_upa_abbrev_t *mapping, uint32_t count);

/** @} */

#ifdef __cplusplus
Expand Down
24 changes: 24 additions & 0 deletions include/coap3/coap_uri_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,16 @@ typedef struct {
coap_uri_scheme_t scheme; /**< scheme */
} coap_uri_info_t;

typedef struct coap_upa_chain_t {
struct coap_upa_chain_t *next; /**< Next entry in the chain */
uint32_t upa_value; /**< The Uri-Path-Abbrev option value */
char *upa_path; /**< The Uri-Path-Abbrev option path representation
(withouot the leading '/') */
} coap_upa_chain_t;

extern coap_uri_info_t coap_uri_scheme[COAP_URI_SCHEME_LAST];
extern coap_upa_chain_t *coap_upa_client_fallback_chain;
extern coap_upa_chain_t *coap_upa_server_mapping_chain;

/**
* replace any % hex definitions with the actual character.
Expand All @@ -47,6 +56,21 @@ extern coap_uri_info_t coap_uri_scheme[COAP_URI_SCHEME_LAST];
*/
void coap_replace_percents(coap_optlist_t *optlist);

/**
* Determine the expanded Uri-Path-Abbrev option value.
*
* @param chain Chain holding the information.
* @param value The Uri-Path-Abbrev numeric value
*
* @return The expanded textual path or @c NULL if not found.
*/
const char *coap_map_abbrev_uri_path(coap_upa_chain_t *chain, u_int value);

int coap_map_uri_path_abbrev(coap_upa_chain_t *chain, const char *path, size_t length,
u_int *value);

void coap_delete_upa_chain(coap_upa_chain_t *chain);

/** @} */

#ifdef __cplusplus
Expand Down
4 changes: 4 additions & 0 deletions libcoap-3.map
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ global:
coap_package_name;
coap_package_version;
coap_path_into_optlist;
coap_path_into_optlist_abbrev;
coap_pdu_duplicate;
coap_pdu_get_code;
coap_pdu_get_mid;
Expand Down Expand Up @@ -348,8 +349,11 @@ global:
coap_tls_engine_configure;
coap_tls_engine_remove;
coap_tls_is_supported;
coap_upa_client_fallback;
coap_upa_server_mapping;
coap_uri_into_options;
coap_uri_into_optlist;
coap_uri_into_optlist_abbrev;
coap_verify_proxy_scheme_supported;
coap_write_block_b_opt;
coap_write_block_opt;
Expand Down
Loading