1// -*- mode:doc; -*- 2// vim: set syntax=asciidoc,tw=0: 3 4coap_endpoint_client(3) 5======================= 6:doctype: manpage 7:man source: coap_endpoint_client 8:man version: @PACKAGE_VERSION@ 9:man manual: libcoap Manual 10 11NAME 12---- 13coap_endpoint_client, 14coap_new_client_session, 15coap_new_client_session_psk2, 16coap_new_client_session_pki, 17coap_session_set_mtu, 18coap_session_max_pdu_size 19- Work with CoAP client endpoints 20 21SYNOPSIS 22-------- 23*#include <coap@LIBCOAP_API_VERSION@/coap.h>* 24 25*coap_session_t *coap_new_client_session(coap_context_t *_context_, 26const coap_address_t *_local_if_, const coap_address_t *_server_, 27coap_proto_t _proto_);* 28 29*coap_session_t *coap_new_client_session_psk2(coap_context_t *_context_, 30const coap_address_t *_local_if_, const coap_address_t *_server_, coap_proto_t 31_proto_, coap_dtls_cpsk_t *_setup_data_);* 32 33*coap_session_t *coap_new_client_session_pki(coap_context_t *_context_, 34const coap_address_t *_local_if_, const coap_address_t *_server_, coap_proto_t 35_proto_, coap_dtls_pki_t *_setup_data_);* 36 37*void coap_session_set_mtu(coap_session_t *_session_, unsigned _mtu_);* 38 39*size_t coap_session_max_pdu_size(const coap_session_t *_session_);* 40 41For specific (D)TLS library support, link with 42*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*, 43*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls* 44or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*. Otherwise, link with 45*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support. 46 47DESCRIPTION 48----------- 49This man page focuses on the setting up of a CoAP client endpoint and hence 50creation of a CoAP Session used to connect to a server. For a CoAP server 51endpoint, see *coap_endpoint_server*(3). 52 53The CoAP stack's global state is stored in a coap_context_t Context object. 54Resources, Endpoints and Sessions are associated with this context object. 55There can be more than one coap_context_t object per application, it is up to 56the application to manage each one accordingly. 57 58A CoAP Ssssion maintains the state of an ongoing connection between a Client 59and Server which is stored in a coap_session_t Session object. A CoAP session 60is tracked by local port, CoAP protocol, remote IP address and remote port. 61 62The Session network traffic can be encrypted or un-encrypted if there is an 63underlying TLS library. 64 65If TLS is going to be used for encrypting the network traffic, then the TLS 66information for Pre-Shared Keys (PSK) or Public Key Infrastructure (PKI) needs 67to be configured before any network traffic starts to flow. For Servers, this 68has to be done before the Endpoint is created, for Clients, this is done 69during the Client Endpoint/Session set up. 70 71For Clients, all the encryption information can be held at the TLS Context and 72CoAP Context levels, or at the TLS Session and CoAP Session levels. If 73defined at the Context level, then when Sessions are created, they will 74inherit the Context definitions, unless they have separately been defined for 75the Session level, in which case the Session version will get used. 76Typically the information will be configured at the Session level for Clients. 77 78In principle the set-up sequence for CoAP client endpoints looks like 79---- 80coap_new_context() 81coap_context_set_pki_root_cas() if the root CAs need to be updated and PKI 82coap_new_client_session(), coap_new_client_session_pki() or coap_new_client_session_psk2() 83---- 84 85Multiple client endpoints and hence sessions are supported per Context. 86 87Different CoAP protocols can be defined for _proto_ - the current supported 88list is: 89 90[source, c] 91---- 92COAP_PROTO_UDP 93COAP_PROTO_DTLS 94COAP_PROTO_TCP 95COAP_PROTO_TLS 96---- 97 98*coap_tcp_is_supported*(), *coap_dtls_is_supported*() and 99*coap_tls_is_supported*() can be used for checking whether the underlying 100TCP or (D)TLS protocol support is available. See *coap_tls_library(3)* for 101further information. 102 103The *coap_new_client_session*() function creates a client endpoint for a 104specific _context_ and initiates a new client session to the specified _server_ 105using the CoAP protocol 106_proto_. If the port is set to 0 in _server_, then the default CoAP 107port is used. Normally _local_if_ would be set to NULL, but by specifying 108_local_if_ the source of the network session can be bound to a specific IP 109address or port. The session will initially have a reference count of 1. 110 111The *coap_new_client_session_pki*() function, for a specific _context_, is 112used to configure the TLS context using the _setup_data_ variables as defined 113in the coap_dtls_pki_t structure in the newly created endpoint session - 114see *coap_encryption*(3). The connection is to the specified _server_ using 115the CoAP protocol _proto_. If the port is set to 0 in _server_, then the 116default CoAP port is used. Normally _local_if_ would be set to NULL, but by 117specifying _local_if_ the source of the network session can be bound to a 118specific IP address or port. The session will initially have a reference count 119of 1. 120 121The *coap_new_client_session_psk2*() function, for a specific _context_, is 122used to configure the TLS context using the _setup_data_ variables as defined 123in the coap_dtls_cpsk_t structure in the newly created endpoint session - 124see *coap_encryption*(3). The connection is to the specified _server_ using 125the CoAP protocol _proto_. If the port is set to 0 in _server_, then the 126default CoAP port is used. Normally _local_if_ would be set to NULL, but by 127specifying _local_if_ the source of the network session can be bound to a 128specific IP address or port. The session will initially have a reference count 129of 1. 130 131To stop using a client session, the reference count must be decremented to 0 132by calling *coap_session_release*(). See *coap_session*(3). This will remove 133the client endpoint. 134 135The *coap_sesson_set_default_mtu*() function is used to set the MTU size 136(the maximum message size) of the data in a packet, excluding any IP or 137TCP/UDP overhead to _mtu_ for the client endpoint's _session_. The default 138MTU is 1152. 139 140The *coap_session_max_pdu_size*() function is used to get the maximum MTU 141size of the data for the client endpoint's _session_. 142 143RETURN VALUES 144------------- 145*coap_new_client_session*(), *coap_new_client_session_psk2*(), 146*coap_new_client_session_pki*() functions returns a newly created client 147session or NULL if there is a creation failure. 148 149*coap_session_max_pdu_size*() function returns the MTU size. 150 151EXAMPLES 152-------- 153*CoAP Client Non-Encrypted Setup* 154[source, c] 155---- 156#include <coap@LIBCOAP_API_VERSION@/coap.h> 157 158#include <netinet/in.h> 159 160static coap_session_t * 161setup_client_session (struct in_addr ip_address) { 162 coap_session_t *session; 163 coap_address_t server; 164 /* See coap_context(3) */ 165 coap_context_t *context = coap_new_context(NULL); 166 167 if (!context) 168 return NULL; 169 /* See coap_block(3) */ 170 coap_context_set_block_mode(context, 171 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 172 173 174 coap_address_init(&server); 175 server.addr.sa.sa_family = AF_INET; 176 server.addr.sin.sin_addr = ip_address; 177 server.addr.sin.sin_port = htons (5683); 178 179 session = coap_new_client_session(context, NULL, &server, COAP_PROTO_UDP); 180 if (!session) { 181 coap_free_context(context); 182 return NULL; 183 } 184 /* The context is in session->context */ 185 return session; 186} 187---- 188 189*CoAP Client PKI Setup* 190[source, c] 191---- 192#include <coap@LIBCOAP_API_VERSION@/coap.h> 193 194#include <netinet/in.h> 195 196static int 197verify_cn_callback(const char *cn, 198 const uint8_t *asn1_public_cert, 199 size_t asn1_length, 200 coap_session_t *c_session, 201 unsigned int depth, 202 int validated, 203 void *arg 204) { 205 /* Remove (void) definition if variable is used */ 206 (void)cn; 207 (void)asn1_public_cert; 208 (void)asn1_length; 209 (void)c_session; 210 (void)depth; 211 (void)validated; 212 (void)arg; 213 214 /* Check that the CN is valid */ 215 216 /* ... */ 217 218 return 1; 219} 220 221static coap_session_t * 222setup_client_session_pki (struct in_addr ip_address, 223 const char *public_cert_file, 224 const char *private_key_file, 225 const char *ca_file 226) { 227 coap_session_t *session; 228 coap_address_t server; 229 coap_dtls_pki_t dtls_pki; 230 /* See coap_context(3) */ 231 coap_context_t *context = coap_new_context(NULL); 232 233 if (!context) 234 return NULL; 235 /* See coap_block(3) */ 236 coap_context_set_block_mode(context, 237 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 238 239 240 coap_address_init(&server); 241 server.addr.sa.sa_family = AF_INET; 242 server.addr.sin.sin_addr = ip_address; 243 server.addr.sin.sin_port = htons (5684); 244 245 memset (&dtls_pki, 0, sizeof (dtls_pki)); 246 247 /* See coap_encryption(3) */ 248 dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION; 249 dtls_pki.verify_peer_cert = 1; 250 dtls_pki.check_common_ca = 1; 251 dtls_pki.allow_self_signed = 1; 252 dtls_pki.allow_expired_certs = 1; 253 dtls_pki.cert_chain_validation = 1; 254 dtls_pki.cert_chain_verify_depth = 1; 255 dtls_pki.check_cert_revocation = 1; 256 dtls_pki.allow_no_crl = 1; 257 dtls_pki.allow_expired_crl = 1; 258 dtls_pki.allow_bad_md_hash = 0; 259 dtls_pki.allow_short_rsa_length = 0; 260 dtls_pki.is_rpk_not_cert = 0; /* Set to 1 if RPK */ 261 dtls_pki.validate_cn_call_back = verify_cn_callback; 262 dtls_pki.cn_call_back_arg = NULL; 263 dtls_pki.validate_sni_call_back = NULL; 264 dtls_pki.sni_call_back_arg = NULL; 265 dtls_pki.additional_tls_setup_call_back = NULL; 266 dtls_pki.client_sni = NULL; 267 dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM; 268 dtls_pki.pki_key.key.pem.ca_file = ca_file; 269 dtls_pki.pki_key.key.pem.public_cert = public_cert_file; 270 dtls_pki.pki_key.key.pem.private_key = private_key_file; 271 272 session = coap_new_client_session_pki(context, NULL, &server, 273 COAP_PROTO_DTLS, &dtls_pki); 274 if (!session) { 275 coap_free_context(context); 276 return NULL; 277 } 278 /* The context is in session->context */ 279 return session; 280} 281---- 282 283*CoAP Client PSK Setup* 284[source, c] 285---- 286#include <coap@LIBCOAP_API_VERSION@/coap.h> 287 288#include <stdio.h> 289#include <netinet/in.h> 290 291#ifndef min 292#define min(a,b) ((a) < (b) ? (a) : (b)) 293#endif 294 295static const coap_dtls_cpsk_info_t * 296verify_ih_callback(coap_str_const_t *hint, 297 coap_session_t *c_session, 298 void *arg 299) { 300 coap_dtls_cpsk_info_t *psk_info = (coap_dtls_cpsk_info_t *)arg; 301 /* Remove (void) definition if variable is used */ 302 (void)c_session; 303 304 coap_log(LOG_INFO, "Identity Hint '%.*s' provided\n", (int)hint->length, hint->s); 305 306 /* Just use the defined information for now as passed in by arg */ 307 return psk_info; 308} 309 310static coap_dtls_cpsk_t dtls_psk; 311static char client_sni[256]; 312 313static coap_session_t * 314setup_client_session_psk (const char *uri, 315 struct in_addr ip_address, 316 const uint8_t *identity, 317 unsigned int identity_len, 318 const uint8_t *key, 319 unsigned int key_len 320) { 321 coap_session_t *session; 322 coap_address_t server; 323 /* See coap_context(3) */ 324 coap_context_t *context = coap_new_context(NULL); 325 326 if (!context) 327 return NULL; 328 /* See coap_block(3) */ 329 coap_context_set_block_mode(context, 330 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 331 332 333 coap_address_init(&server); 334 server.addr.sa.sa_family = AF_INET; 335 server.addr.sin.sin_addr = ip_address; 336 server.addr.sin.sin_port = htons (5684); 337 338 /* See coap_encryption(3) */ 339 memset (&dtls_psk, 0, sizeof(dtls_psk)); 340 dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION; 341 dtls_psk.validate_ih_call_back = verify_ih_callback; 342 dtls_psk.ih_call_back_arg = &dtls_psk.psk_info; 343 if (uri) 344 memcpy(client_sni, uri, min(strlen(uri), sizeof(client_sni)-1)); 345 else 346 memcpy(client_sni, "localhost", 9); 347 dtls_psk.client_sni = client_sni; 348 dtls_psk.psk_info.identity.s = identity; 349 dtls_psk.psk_info.identity.length = identity_len; 350 dtls_psk.psk_info.key.s = key; 351 dtls_psk.psk_info.key.length = key_len; 352 session = coap_new_client_session_psk2(context, NULL, &server, 353 COAP_PROTO_DTLS, &dtls_psk); 354 if (!session) { 355 coap_free_context(context); 356 return NULL; 357 } 358 /* The context is in session->context */ 359 return session; 360} 361---- 362 363*CoAP Client Anonymous PKI Setup* 364[source, c] 365---- 366#include <coap@LIBCOAP_API_VERSION@/coap.h> 367 368#include <netinet/in.h> 369 370static coap_session_t * 371setup_client_session_dtls (struct in_addr ip_address) { 372 coap_session_t *session; 373 coap_address_t server; 374 /* See coap_context(3) */ 375 coap_context_t *context = coap_new_context(NULL); 376 377 if (!context) 378 return NULL; 379 /* See coap_block(3) */ 380 coap_context_set_block_mode(context, 381 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 382 383 384 coap_address_init(&server); 385 server.addr.sa.sa_family = AF_INET; 386 server.addr.sin.sin_addr = ip_address; 387 server.addr.sin.sin_port = htons (5683); 388 389 session = coap_new_client_session(context, NULL, &server, 390 COAP_PROTO_DTLS); 391 if (!session) { 392 coap_free_context(context); 393 return NULL; 394 } 395 /* The context is in session->context */ 396 return session; 397} 398---- 399 400SEE ALSO 401-------- 402*coap_block*(3), *coap_context*(3), *coap_encryption*(3), 403*coap_endpoint_server*()3), *coap_resource*(3), *coap_session*(3) and 404*coap_tls_library*(3) 405 406FURTHER INFORMATION 407------------------- 408See "RFC7252: The Constrained Application Protocol (CoAP)" for further 409information. 410 411BUGS 412---- 413Please report bugs on the mailing list for libcoap: 414libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at 415https://github.com/obgm/libcoap/issues 416 417AUTHORS 418------- 419The libcoap project <libcoap-developers@lists.sourceforge.net> 420