obgm/libcoap

Provide defines for supported features and more feature availability check functions

pulsastrix opened this issue · 7 comments

Is your feature request related to a problem? Please describe.

Currently, libcoap provides functions that return whether specific features are supported during runtime (e.g. coap_dtls_is_supported()).
While this allows for feature detection during runtime, it does not allow for checking feature support during compile time, which would be nice in order to solve namib-project/libcoap-rs#20.

Describe the solution you would like

It would be nice if there were also #defines in the public headers that indicate whether the compiled version of libcoap supports certain features.

Additionally, as there is no guarantee that the generated headers match the compiled library files that are linked against, some additional runtime feature checking functions would be nice (e.g. coap_is_threadsafe(), coap_epoll_is_supported())

Describe alternatives you have considered

Some of those defines are already generated in coap_config.h. However, this header is typically not available in regular installations of libcoap.

Programs using autoconf or similar tools may work around this issue by compiling a test program that calls the feature support function during configuration.
Unfortunately, there is no easy way to do something like this in Rust, and even if there were, this would not work in cross-compilation environments (libcoap itself has an example of this here).

Alternatively, applications could check for required features during library initialization, but at least for namib-project/libcoap-rs, it would be nicer if we could prevent compilation of programs that would immediately fail using compile-time checks.

Additional context

For libcoap-rs of particular interest would be defines for:

  • Each optional feature that can be enabled or disabled using the configure-script (client, server, DTLS, async, websockets, ...), as these are provided as optional features in libcoap-rs as well and we'd ideally prevent compilation of libcoap-rs with features that aren't supported in the linked version of libcoap.
    • a define indicating the used DTLS library would also be nice, but not strictly required
  • Whether thread-safe support is enabled, as thread-safety in libcoap is a prerequisite for enabling multithreading in libcoap-rs, and we'd have to enable different code during compile-time based on whether multithreading is enabled or not.
  • Whether libcoap uses epoll or not (might become relevant later on for libcoap-rs, as epoll-support would allow integration into Rust async runtimes such as tokio (using coap_context_get_coap_fd())

Of course, these defines could only serve as an indicator for feature support that would have to be validated during library initialization, as there is no guarantee that the headers refer to the same build of libcoap as the compiled library files.
However, it would still be nice to catch missing feature support during compile-time in most cases.

I was not involved in decisions about whether coap_config.h should be available or not to application code.

libcoap for instance, with wolfSSL as the TLS library relies on wolfssl/options.h which is available if wolfSSL is built with --enable-all, but not with --enable-distro.

I don't see why coap_config.h in principle should not be installed as there is no architecture specific stuff in it (but will have system build specifics such as HAVE_STDINT_H which may confuse the application build). So, it makes sense to have a coap_options.h file which is an appropriate subset of coap_config.h.

checking functions would be nice (e.g. coap_is_threadsafe(), coap_epoll_is_supported()

Yes, these should be available.

I will look and see what I can do, but may take a few weeks.

Does #1488 work for you?

I'm not that happy with the creation solution for coap_defines.h when running ./configure (no #define wrapper check) (but CMakelists.txt is fine), so open to suggestions.

Thanks for adding this in so quickly.

I'll make the appropriate changes to utilize those defines in libcoap-rs and get back to you as soon as I can tell if something is missing (shouldn't take more than a day or so).

The COAP_* #defines are abstracted out of coap_config.h, so I would not expect any of them to be missing, but....

The coap_*_is_supported() list potentially has missing functionality.

Regarding the runtime check functions, coap_ipv4_is_supported(), coap_ipv6_is_supported(), coap_af_unix_is_supported() and coap_observe_persist_is_supported() seem to be missing.1

Client-side and server-side support probably don't need a check because (as far as I understand it) disabling those will actually remove the corresponding functions, right?

Regarding the defines, I assume that adding defines for DTLS PKI/PSK/RPK/PKCS11 support would be more trouble than it is worth, as those depend on DTLS library specifics.
Those would be nice to have, but I can make do with runtime checks there.

Just for reference, this is my (still very WIP) branch in libcoap-rs that utilizes the defines and runtime check functions to ensure that the features enabled in libcoap-sys are actually present in the linked version of libcoap: namib-project/libcoap-rs#26

Footnotes

  1. thread-recursive-lock-detection and small-stack probably don't need a runtime check, as they don't influence the application-facing API (I assume).

Added in additional coap_*_is_supported() functions.

thread-recursive-lock-detection and small-stack probably don't need a runtime check

Agreed.

Regarding the defines, I assume that adding defines for DTLS PKI/PSK/RPK/PKCS11 support would be more trouble

Yes, as they are very TLS library dependent as well as TLS library version dependent.

Support for this in now in the develop branch. Closing this request.