COAP_PROXY(3)

NAME
coap_proxy, coap_proxy_forward_request, coap_proxy_forward_response, coap_verify_proxy_scheme_supported - Work with CoAP proxies

SYNOPSIS

#include <coap3/coap.h>

int coap_proxy_forward_request(coap_session_t *session, const coap_pdu_t *request, coap_pdu_t *response, coap_resource_t *resource, coap_cache_key_t *cache_key, coap_proxy_server_list_t *server_list);

coap_response_t coap_proxy_forward_response(coap_session_t *session, const coap_pdu_t *received_, coap_cache_key_t **cache_key);

int coap_verify_proxy_scheme_supported(coap_uri_scheme_t scheme);

For specific (D)TLS library support, link with -lcoap-3-notls, -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls, -lcoap-3-wolfssl or -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default (D)TLS library support.

DESCRIPTION

To simplify some of the CoAP proxy requirements, some of the proxy forwarding functionality is provided by libcoap.

The resourse handlers to handle forward or reverse proxy requests are defined using coap_resource_proxy_uri_init2(3) or coap_resource_reverse_proxy_init*(3).

FUNCTIONS

Function: coap_proxy_forward_request()

The coap_proxy_forward_request() function is called from a request handler when the request needs to be forwarded to an upstream server with a possible change in protocol.

Function: coap_proxy_forward_response()

The coap_proxy_forward_response() function is used to cleanup / free any information set up by the coap_startup() function and should be the last coap_*() function called. The only safe function that can be called after coap_cleanup() is coap_startup() to re-initialize the libcoap logic.

NOTE: Calling coap_cleanup() in one thread while continuing to use other coap_*() function calls in a different thread is not supported - even if they are using a different coap_context_t.

NOTE: All other libcoap cleanups should called prior to coap_cleanup(), e.g. coap_free_context(3).

Function: coap_verify_proxy_scheme_supported()

The coap_proxy_forward_request() function is called from a request handler when the request needs to be forwarded to an upstream server with a possible change in protocol.

RETURN VALUES

coap_proxy_forward_request() and coap_verify_proxy_scheme_supported() return 1 on success and 0 on failure.

coap_proxy_forward_response() returns one of COAP_RESPONSE_OK or COAP_RESPONSE_FAIL.

EXAMPLES

Forward Proxy Set Up

    #include <coap3/coap.h>
    static size_t proxy_host_name_count = 0;
    static const char **proxy_host_name_list = NULL;
    static coap_proxy_server_list_t forward_proxy = { NULL, 0, 0, COAP_PROXY_FORWARD, 0, 300};
    static void
    hnd_forward_proxy_uri(coap_resource_t *resource,
                          coap_session_t *session,
                          const coap_pdu_t *request,
                          const coap_string_t *query COAP_UNUSED,
                          coap_pdu_t *response) {
      if (!coap_proxy_forward_request(session, request, response, resource,
                                      NULL, &forward_proxy)) {
        coap_log_debug("hnd_forward_proxy_uri: Failed to forward PDU\n");
        /* Non ACK response code set on error detection */
      }
      /* Leave response code as is */
    }
    static coap_response_t
    proxy_response_handler(coap_session_t *session,
                           const coap_pdu_t *sent COAP_UNUSED,
                           const coap_pdu_t *received,
                           const coap_mid_t id COAP_UNUSED) {
      return coap_proxy_forward_response(session, received, NULL);
    }
    static void
    init_resources(coap_context_t *ctx) {
      coap_resource_t *r;
      /* See coap_resource_proxy_uri_init2(3) */
      r = coap_resource_proxy_uri_init2(hnd_forward_proxy_uri, proxy_host_name_count,
                                        proxy_host_name_list, 0);
      coap_add_resource(ctx, r);
      coap_register_response_handler(ctx, proxy_response_handler);
      /* Add in event or nack handlers if required */
    }
    static void
    init_proxy_info(coap_uri_t *proxy_uri, const char *proxy_host_name) {
      coap_proxy_server_t *new_entry;
      new_entry = realloc(forward_proxy.entry,
                          (forward_proxy.entry_count + 1)*sizeof(forward_proxy.entry[0]));
      if (!new_entry) {
        coap_log_err("CoAP Proxy realloc() error\n");
        return;
      }
      /* Can have multiple of these upstream proxy hosts for doing round robin etc. */
      forward_proxy.entry = new_entry;
      memset(&forward_proxy.entry[forward_proxy.entry_count], 0, sizeof(forward_proxy.entry[0]));
      forward_proxy.entry[forward_proxy.entry_count].uri = *proxy_uri;
      forward_proxy.entry_count++;
      /* The proxy host could be known by multile names - add them all in */
      proxy_host_name_count = 0;
      proxy_host_name_list = coap_malloc(proxy_host_name_count * sizeof(char *));
      proxy_host_name_list[0] = proxy_host_name;
    }

Reverse Proxy Set Up

    #include <coap3/coap.h>
    static coap_proxy_server_list_t reverse_proxy = { NULL, 0, 0, COAP_PROXY_REVERSE_STRIP, 0, 10};
    static void
    hnd_reverse_proxy_uri(coap_resource_t *resource,
                          coap_session_t *session,
                          const coap_pdu_t *request,
                          const coap_string_t *query COAP_UNUSED,
                          coap_pdu_t *response) {
      if (!coap_proxy_forward_request(session, request, response, resource,
                                      NULL, &reverse_proxy)) {
        coap_log_debug("hnd_reverse_proxy: Failed to forward PDU\n");
        /* Non ACK response code set on error detection */
      }
      /* Leave response code as is */
    }
    static coap_response_t
    proxy_response_handler(coap_session_t *session,
                           const coap_pdu_t *sent COAP_UNUSED,
                           const coap_pdu_t *received,
                           const coap_mid_t id COAP_UNUSED) {
      return coap_proxy_forward_response(session, received, NULL);
    }
    static void
    init_resources(coap_context_t *ctx) {
      coap_resource_t *r;
      /* See coap_resource_reverse_proxy_init(3) */
      r = coap_resource_reverse_proxy_init(hnd_reverse_proxy_uri, 0);
      coap_add_resource(ctx, r);
      coap_register_response_handler(ctx, proxy_response_handler);
      /* Add in event or nack handlers if required */
    }

FURTHER INFORMATION

See

"RFC7252: The Constrained Application Protocol (CoAP)"

for further information.

BUGS

Please raise an issue on GitHub at https://github.com/obgm/libcoap/issues to report any bugs.

Please raise a Pull Request at https://github.com/obgm/libcoap/pulls for any fixes.

AUTHORS

The libcoap project <libcoap-developers@lists.sourceforge.net>