Code works as expected for confirmable observes as the sent pdu is
retained for potential re-transmission.
For non-confirmable observes, the RST is seen in the response packet but
previously had no way of finding the observe/subscription to cancel.
Keep the last sent message id in coap_subscription_t (as tid) and when the
RST comes in, search for the subscription that has the same message id as
the pdu and remove that subscription.
include/coap2/subscribe.h:
Add in tid to coap_subscription_t (as per coap_pdu_t).
src/net.c:
Match tid in incoming RST pdu with a subscription. If found, delete the
subscription.
src/resource.c:
Save tid in both pdu and subscription when sending off an observe response.
To test code, make the following temporary change to coap-client
diff --git a/examples/client.c b/examples/client.c
index 4d3e4c7..0020b68 100644
--- a/examples/client.c
+++ b/examples/client.c
@@ -348,7 +348,8 @@ message_handler(struct coap_context_t *ctx,
#endif
/* check if this is a response to our original request */
- if (!check_token(received)) {
+static int count = 0;
+ if (!check_token(received) || ++count == 5) {
/* drop if this was just some message, or send RST in case of notification */
if (!sent && (received->type == COAP_MESSAGE_CON ||
received->type == COAP_MESSAGE_NON))
and run (coap-server running on the same host)
coap-client -N -s 10 coap://127.0.0.1/time
Adding in new structures to .h files that are typedef'd to not include
"struct" which are then referenced by other .h files can easily set up
recursive requirements that cannot be fulfilled.
In particular, adding in a new typedef'd struct to coap_dtls.h cannot
easily be used by coap_session.h
include/coap2/coap_dtls.h:
In coap_dtls.h, forward reference the (outside of the file) structures
and then prefix the coap_*_t entries with "struct", so making the
entries "struct coap_*_t" entries as appropriate
As coap-server now sets up 2 (or 4) endpoints, UDP and TCP based, all
subsequent endpoints are pre-pended to the ctx->endpoint list. Thus
ctx->endpoint will always be TCP based. Setting IPV6_JOIN_GROUP on a TCP
socket is a no-no.
As join() is complex function, it should be within libcoap so as to not require
detailed knowledge of how internal structures work (which really should be
opaque to the application writer).
include/coap2/net.h:
src/net.c:
libcoap-2.map:
libcoap-2.sym:
Create coap_join_mcast_group() in src/net.c (as it is a network layer
function using the (fixed) join() code. (Iterate through the ctx->endpoint list
looking for UDP based endpoints and only do the IPV6_JOIN_GROUP on them.)
There is no support for WITH_CONTIKI or WITH_LWIP at this point (returns -1).
examples/coap-server.c:
Remove join() code and replace call to join() with coap_join_mcast_group()
examples/coap-rd.c:
Remove join() code and replace call to join() with coap_join_mcast_group()
man/coap-rd.txt.in:
Correct a typo in the coap-ed man page
When there is a limited stack size, having large data items on the stack
can easily cause stack overflows.
This makes integration with any constrained stack O/S a lot easier.
include/coap2/coap_mutex.h:
Create coap_ mutex functions which are platform independent to protect
the (now) static variables if compiled with "-DCOAP_CONSTRAINED_STACK=1"
Makefile.am:
Include include/coap2/coap_mutex.h for distribution
coap_config.h.contiki:
coap_config.h.lwip:
As CONTIKI and LWIP have constrained stacks, set
"#define COAP_CONSTRAINED_STACK 1"
src/coap_debug.c:
src/coap_io.c:
src/net.c:
coap_show_pdu()
coap_log_impl()
coap_run_once()
coap_read_session()
coap_read_endpoint()
Move large data items out of the functions' stack and make them static
variables (defined within the function) if COAP_CONSTRAINED_STACK is defined.
Protect the usage of these static variables by mutexes.
Note: if "-DCOAP_CONSTRAINED_STACK=0" is used, then the stack will not
be constrained.
To reproduce the issue:
Server session
$ coap-server -v9 -n -k secretPSK -c server.pem -C ca.pem -R /etc/ssl/certs
Client session
$ examples/coap-client -v9 coaps://127.0.0.1/
include/coap2/coap_dtls.h:
src/coap_gnutls.c:
If neither coap_new_client_session_pki() or coap_new_client_session_psk()
is called, but coap_new_client_session() is (as done by coap-client if
no PKI or PSK options set), then set up a default PKI session to be
able to talk to a coap server.
By defining the CA file or Root CAs in the client, the server's certificate
can be validated by the options in coap_dtls_pki_t parameter even if the client
does not define a certificate.
[The server must be configured not to require a Client Cert]
examples/client.c:
Add in the support to the coap-client to allow any of Root CA, CA and Cert
to be defined to set up PKI checking.
src/coap_gnutls.c:
src/coap_openssl.c:
Remove the checks in the OpenSSL and GnuTLS underlying support that previously
used to enforce that both CA and Cert had to be set in the client.
Correct some of the PKI setup error messages to relect whether the failure is
on the client or the server.
include/coap2/coap_dtls.h:
src/coap_gnutls.c:
src/coap_notls.c:
src/coap_openssl.c:
src/coap_tinydtls.c:
Convert COAP_DTLS_ROLE_SERVER and COAP_DTLS_ROLE_CLIENT to enum
coap_dtls_role_t and use as appropriate to differentiate between the roles
in the different DTLS libraries
include/coap2/libcoap.h
_LIBCOAP_H_ to COAP_LIBCOAP_H_
src/coap_session.c
_COAP_SESSION_H_ to COAP_SESSION_C_
include/coap2/coap_session.h
_SESSION_H_ to COAP_SESSION_H_
otherwise, all #define _COAP_xxxxx wrappers are now COAP_xxxxx
Fixes#291
As str structure has been replaced by coap_string_t, remove it from the code
as it is no longer required, has been deprecated for some time and can cause
clashes with other str definitions.
Tidy up comment referring to str.
For any TLS implementation, it is possible to crash the coap-server by
initiating (D)TLS handshakes but never completing them, thus continuing to use
more RAM. Each partially completed handshake is left in the endpoint->sessions
chain in a state of COAP_SESSION_STATE_HANDSHAKE and unless
endpoint->max_idle_sessions is deliberately configured, these sessions will
never get deleted.
A cause of partially completed handshakes is when there is a PSK mismatch.
Furthermore, unnecessary CPU usage is used to search down long lists held in
endpoint->sessions.
This fix limits the number of these sessions in a handshake state to the
number defined by endpoint->max_handshake_sessions if non zero or 100 to prevent
memory exhaustion. By default, endpoint->max_handshake_sessions is 0.
Sessions in state COAP_SESSION_STATE_HANDSHAKE will get timed out after 30
seconds of inactivity.
This does not prevent a DOS attack by creating max_handshake_sessions as a
genuine new session will fail to get responded to until the number of current
COAP_SESSION_STATE_HANDSHAKE sessions drop. However, the use of Cookie
exchanges by the underlying TLS library prior to a new session being created
and added into endpoint->sessions will filter out a lot of the DOS attacks.
include/coap2/coap_session.h
New default definition for COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS
New default definition for COAP_PARTIAL_SESSION_TIMEOUT_TICKS
include/coap2/net.h
Include max_handshake_sessions in coap_context_t
src/coap_session.c
In coap_endpoint_get_session() check the number of sessions in
COAP_SESSION_STATE_HANDSHAKE and handle accordingly when limits are hit, or
they need to be timed out.
Information set up in the pseudo session held in endpoint->hello is not freed
off when coap_free_endpoint() is called.
A solution is to split coap_session_free() into two parts with
coap_session_free() calling a new function coap_session_mfree().
Then coap_mfree_endpoint() can call coap_session_mfree() to free off the
endpoint specific hello information.
Makefile.am
Add coap_mfree_endpoint and coap_session_mfree to the CTAGS_IGNORE list.
libcoap-2.{map|sym}
Remove coap_mfree_endpoint as it is not a public function
include/coap2/coap_session.h
Add in new coap_session_mfree() function definition
src/coap_io.c
Call coap_session_mfree() from within coap_mfree_endpoint()
src/coap_session.c
Move some of the functionality out of coap_session_free() into a new
function coap_session_mfree() and call coap_session_mfree().
These new functions can be used to either update a buffer with, or coap_log()
out the current runtime TLS library along with the version of the library
that libcoap was built against.
include/coap2/debug.h
src/debug.c
libcoap-2.map
libcoap-2.sym
Support for the new functions coap_show_tls_version() and coap_string_tls_version().
This allows an application to determine what the built version is
as well as what the runtime version of a TLS library is.
include/coap2/coap_dtls.h
Add built_version to coap_tls_version_t
src/coap_openssl.c
src/coap_tinydtls.c
Additionally populate coap_tls_version_t with build_version when
coap_get_tls_library_version() is called.
src/coap_tinydtls.c
Correct the version returned as actual TinyDTLS version instead the
binary value of a DTLS packet type.
This then removes the need for name polution/confict of debug(), info() and
warn() when building other projects that use libcoap and need to #include the
libcoap header files
Updated:
examples/client.c
examples/contiki/coap-observer.c
examples/etsi_iot_01.c
include/coap2/debug.h
src/async.c
src/block.c
src/coap_io.c
src/coap_openssl.c
src/coap_session.c
src/coap_tinydtls.c
src/debug.c
src/mem.c
src/net.c
src/option.c
src/pdu.c
src/resource.c
src/uri.c
If the debug() etc. macros are still required, then the change to
include/coap2/debug.h just needs to be reverted.
There are also a couple of space changes - to cause log output to be columnar
e.g "ERR" was padded to "ERR ", so that "EMRG" or "ERR " log output output was
aligned in the same way.
This is a replacement for PR#51, and partially deals with name polution issues
raised in Issue #50.
Parameter re-aligned some long strings, splitting strings across multiple lines
Automake is using the variable 'libcoap_include_HEADERS' as the list to
install the header files and is this list installing to $(prefix)
basically.
This commit is changing the primary installation folder for the header
files in addition to the previous commit.
hashkey.[ch] files restored (now prefixed with coap_)
LWIP and Contiki builds now include these files
block.[ch]:
New function coap_add_data_blocked_response() to simplify GET
responses and handle adding in BLOCK2 options as appropriate.
Needs coap_hash() to generate ETag option.
net.c:
Determine if Block2 is in use, and add to coap_add_observer().
resource.[ch]:
Include Block2 request in coap_add_observer().
subscribe.h:
Include Block2 definition in coap_subscriber_t for using during
observe responses.
pdu.h:
Update comment.
coap-client.c:
No longer causes duplicate calls to coap_show_pdu()
(one in library, one in coap-client for the same PDU).
If a block'ed response received and observing, now observing continues.
(Fixes#166).
Send Observe Cancel with Block2 option if -b defined
coap-server.c:
Replaced all option setting, data addition etc. with new
coap_add_data_blocked_response() function in the GET handlers.
(Fixes#246 Issue 2).
Support PUT with BLOCK1.
(Fixes#246 Issue 1).
Add in -N option to send observe responses as non-confirmable.
Handle small wait_ms values correctly (after being decremented) for testing
whether observe should be triggered or not.
Refresh time every second by making COAP_RESOURCE_CHECK_TIME 1
Manuals:
Add in new function coap_add_data_blocked_response()
Update coap_observe with coap_delete_observer(s) functions
Correct example typo and use new function in hnd_get_time().
Add in -N option to coap-server(5)
Be more specific about COAP_RESOURCE_FLAGS_NOTIFY_NON and
COAP_RESOURCE_FLAGS_NOTIFY_CON usage for observe.
Files:
Makefile.am
Makefile.libcoap
examples/client.c
examples/coap-server.c
examples/lwip/Makefile
include/coap/block.h
include/coap/coap_hashkey.h
include/coap/pdu.h
include/coap/resource.h
include/coap/subscribe.h
libcoap-2.map
libcoap-2.sym
man/Makefile.am
man/coap-server.txt.in
man/coap_handler.txt.in
man/coap_observe.txt.in
man/coap_pdu_setup.txt.in
man/coap_resource.txt.in
src/block.c
src/coap_hashkey.c
src/net.c
src/resource.c
Added in a new landing page for Main Page
doc/main.md (new)
Enabled Tree View of whats available
Disable Related Pages TAB as it fills up with the man pages
- updated doc/Doxyfile.in
Get a2x to also generate html man pages which are then included. These
html files are updated to correct the lowercasing of NAME and SYNOPSIS.
The SEE ALSO references to other man pages are made hyper links.
- done by doc/build_man_files.sh (new)
Created a new TAB Manual Pages
Created a new TAB Depricated Items
- done by modifing DoxygenLayout.xml file using doc/build_man_files.sh
Updated .gitignore to ignore additional files and autogen.sh to clean them up
man/coap*txt.in updated to display as expected in Doxygen.
This only updates documentation
.gitignore
Makefile.am
autogen.sh
doc/Doxyfile.in
doc/Makefile.am
doc/build_man_files.sh (New)
doc/main.md (New)
include/coap/debug.h
include/coap/encode.h
include/coap/option.h
include/coap/pdu.h
include/coap/prng.h
man/Makefile.am
man/coap.txt.in
man/coap_attribute.txt.in
man/coap_context.txt.in
man/coap_encryption.txt.in
man/coap_handler.txt.in
man/coap_logging.txt.in
man/coap_observe.txt.in
man/coap_pdu_setup.txt.in
man/coap_recovery.txt.in
man/coap_resource.txt.in
man/coap_session.txt.in
man/coap_tls_library.txt.in
Because of time accuracy of COAP_TICKS_PER_SECOND (usually 1000
ticks per second on platform POSIX), the pong response may have
the same timestamp as the ping request. To be reliable, the pong
timestamp must be tracked separately from the general last RX/TX
timestamp.
Add new event types to report the TCP connection status and CSM exchange
status to the application. Add optional auto send of ping messages for
reliable client sessions. Add default timeout of 30s for receiving a CSM
message from the remote host after connect.
dtls_event is a static variable, declared outside of all the functions which
tracks (D)TLS errors for generating events etc.
If there are multiple SSL sessions being set up to the same server (as per
Happy Eyeballs for the DOTS protocol) it is possible to asynchronously get
dtls_event updated and the wrong SSL session then acts on it.
Make dtls_event a part of coap_session_t to maintain seperation.
Preset dtls_event to -1 in coap_make_session().
Update coap_event_handler() to have the 3rd parameter as
coap_session_t *session instead of void *arg as the parameter is always session.
Updated coap_event_handler_t to have session as the 3rd parameter.
Add in new registration handler coap_register_event_handler() to be consistent
with all the other coap_register_XXX_handler()s.
Consequently, coap_set_event_handler() and coap_clear_enent_handler() are
deprecated.
Update coap_handler(3) to include new coap_register_event_handler().
(PR #183 event definitions are included presumptive on #183 getting merged)
OpenSSL 1.1.0 has support for making decisions during receipt of
the Client Hello - the call back function is set up using
SSL_CTX_set_tlsext_servername_callback() which is called later in the
Client Hello processing - but called every Client Hello.
Certificates and Preshared Keys have to be set up in the SSL CTX before
SSL_Accept() is called, making the code messy to decide whether this is a
PKI or PSK incoming request to handle things accordingly if both are
defined. SNI has to create a new SSL CTX to handle different server names
with different crtificates.
OpenSSL 1.1.1 introduces a new function SSL_CTX_set_client_hello_cb().
The call back is invoked early on in the Client Hello processing giving
the ability to easily use different Preshared Keys, Certificates etc.
Certificates do not have to be set up in the SSL CTX before SSL_Accept is
called.
Later in the Client Hello code, the callback for
SSL_CTX_set_tlsext_servername_callback() is still called, but only if SNI
is being used by the client, so cannot be used for doing things the
OpenSSL 1.1.0 way.
OpenSSL 1.1.1 supports TLS1.3.
Consequently, this code has to have compile time options to include /
exclude code based on whether compiled against 1.1.0 or 1.1.1, as well as
have additional run time checks.
Updated:
examples/client.c
examples/coap-server.c
include/coap/coap_dtls.h
man/coap_context.txt.in
man/coap_encryption.txt.in
man/coap_session.txt.in
src/coap_openssl.c
In addition, the callback app_override_tls_setup_call_back has been removed
from coap_dtls_pki_t and replaced with additional_tls_setup_call_back
as app_override_tls_setup_call_back became very messy with 2 versions
of OpenSSL. If the application now wants to make additional checks/
changes etc., app_override_tls_setup_call_back will get invoked after
the defined configuration checks are done.
SNI has been added into coap-client for testing / demonstration
Update code to use new APIs
[Some code changes modelled on PR #202, some code being moved between files]
Remove #ifdef WITH_LWIP from coap_io.c as file is not used
Add in resource time to lwip
Update for Travis build
Report on Contiki memory allocate failures to ease debugging
Make the different memory type counts configurable by using the -D option
included in a CFLAGS definition to the ./configure command line
.travis.yml
BUILDING
Makefile.libcoap
examples/contiki/Makefile
examples/contiki/README new
examples/contiki/server.c
examples/contiki/.gitignore (new)
examples/lwip/Makefile
examples/lwip/README
examples/lwip/lwipopts.h
examples/lwip/server-coap.c
examples/lwip/server.c
include/coap/address.h
include/coap/coap_io.h
include/coap/lwippools.h
include/coap/pdu.h
scripts/build.sh
src/address.c
src/coap_io.c
src/coap_io_lwip.c
src/coap_session.c
src/mem.c
src/net.c
src/pdu.c
As C++ forbides returning a pointer to a temporary object, the
creation of a coap_str_const_t to wrap the character-array and
size done in coap_make_str_const() does not work.
This change therefore creates a C++ class CoAPStrConst in namespace
libcoap in a way that allows the default constructor to be used with
aggregate initialization.
This commit closes issue #233 [2].
[1] https://en.cppreference.com/w/cpp/language/aggregate_initialization
[2] https://github.com/obgm/libcoap/issues/233
New struct coap_binary_t - same as coap_string_t, used for tokens
Deprecate struct str with the intent of removing it downstream as it
polutes namespace.
Make end of coap_string_t data a NUL.
Updated coap_make_str_const(), removing .length= and .s= to keep upstream
compilers happy.
Update Doxygen for str.h
Files:
examples/client.c
examples/coap-rd.c
examples/coap-server.c
examples/contiki/server.c
examples/etsi_iot_01.c
include/coap/resource.h
include/coap/str.h
include/coap/subscribe.h
man/coap_observe.txt.in
src/net.c
src/resource.c
src/str.c
src/uri.c
tests/test_options.c
Update
This better describes what is going on here (as they are created by
coap_session_delay_pdu() and are only released off this queue when
either the session becomes established, or the outstanding CON requests
falls below COAP_DEFAULT_NSTART (a value of 1).
This is to remove confusion with the use of coap_context_t sendqueue
which is used for retransmitting data after no response detected for a
CON request.
include/coap/coap_session.h
src/coap_io.c
src/coap_session.c
src/net.c