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). There is no need to call 52*coap_new_endpoint*(3) for a client as well as one of the 53*coap_new_client_server**() functions. 54 55The CoAP stack's global state is stored in a coap_context_t _context_ object. 56Resources, Endpoints and Sessions are associated with this _context_ object. 57There can be more than one coap_context_t object per application, it is up to 58the application to manage each one accordingly. 59 60A CoAP _session_ maintains the state of an ongoing connection between a Client 61and Server which is stored in a coap_session_t _session_ object. A CoAP 62_session_ is tracked by local port, CoAP protocol, remote IP address and 63remote port, or in the case of Unix Domain sockets, the local path and the 64remote path. 65 66The _session_ network traffic can be encrypted or un-encrypted if there is an 67underlying TLS library. 68 69If (D)TLS is going to be used for encrypting the network traffic, then the 70(D)TLS 71information for Pre-Shared Keys (PSK) or Public Key Infrastructure (PKI) needs 72to be configured before any network traffic starts to flow. For Clients, this 73is done during the Client _session_ set up. 74 75For Clients, all the encryption information can be held at the (D)TLS 76context and CoAP _context_ levels, or at the (D)TLS session and CoAP 77_session_ levels. If defined at the _context_ level, then when a _session_ is 78created, it will inherit the _context_ definitions, unless they have separately 79been defined for the _session_ level, in which case the _session_ version will 80get used. Typically the information will be configured at the _session_ level 81for Clients. 82 83In principle the set-up sequence for CoAP client endpoints looks like 84---- 85coap_new_context() 86coap_context_set_pki_root_cas() - if the root CAs need to be updated and using PKI 87coap_new_client_session(), coap_new_client_session_pki() or coap_new_client_session_psk2() 88---- 89 90Multiple client endpoints and hence sessions are supported per _context_. 91 92Different CoAP protocols can be defined for _proto_ - the current supported 93list is: 94 95[source, c] 96---- 97COAP_PROTO_UDP 98COAP_PROTO_DTLS 99COAP_PROTO_TCP 100COAP_PROTO_TLS 101COAP_PROTO_WS 102COAP_PROTO_WSS 103---- 104 105*coap_tcp_is_supported*(3), *coap_dtls_is_supported*(3), 106*coap_tls_is_supported*(3), *coap_ws_is_supported*(3) and 107*coap_wss_is_supported*(3) can be used for checking whether the underlying 108TCP, (D)TLS or WebSocket protocol support is available. 109See *coap_tls_library(3)* for further information on the types of (D)TLS 110sessions supported. 111 112Libcoap supports 3 different socket types: 113 114[source, c] 115---- 116AF_INET IPv4 IP addresses and ports 117AF_INET6 IPv6 IP addresses and ports and can be dual IPv4/IPv6 stacked 118AF_UNIX Unix Domain using file path names 119---- 120 121For AF_INET and AF_INET6, the client does not need to specify a local IP 122address and/or port as default values will get filled in. However for AF_UNIX, 123the local pathname must be provided and must be unique per client session. This 124unique local pathname will get deleted on the session being properly closed at 125application exit. 126 127The client must specify IP and port when defining the *coap_address_t* (see 128*coap_address_t*(3)) for the remote end of the session if AF_INET or AF_INET6. 129If port is 0, then the default CoAP port is used instead. If AF_UNIX, the 130unix domain path to connect to must be specified. 131 132FUNCTIONS 133--------- 134 135*Function: coap_new_client_session()* 136 137The *coap_new_client_session*() function creates a client endpoint for a 138specific _context_ and initiates a new client session to the specified 139_server_ using the CoAP protocol _proto_ as defined above. If the port is set 140to 0 in _server_ (for AF_INET or AF_INET6), then the default CoAP port is used. 141 142Normally _local_if_ would be set to NULL, but by specifying 143_local_if_ the source of the network session can be bound to a specific IP 144address or port. For AF_UNIX, _local_if_ must be specified pointing to an 145appropriate *coap_address_t*. If _local_if_ is defined, the address families 146for _local_if_ and _server_ must be identical. The session will initially have 147a reference count of 1. 148 149To stop using a client session, the reference count must be decremented to 0 150by calling *coap_session_release*(3). See *coap_session*(3). This will remove 151the client endpoint's _session_ and all its associated information. 152 153*Function: coap_new_client_session_pki()* 154 155The *coap_new_client_session_pki*() function, for a specific _context_, is 156used to configure the (D)TLS context using the _setup_data_ variables as defined 157in the coap_dtls_pki_t structure in the newly created endpoint session - 158see *coap_encryption*(3). The connection is to the specified _server_ using 159the CoAP protocol _proto_ as defined above. If the port is set to 0 in 160_server_ (for AF_INET or AF_INET6), then the default CoAP port is used. 161 162Normally _local_if_ would be set to NULL, but by specifying 163_local_if_ the source of the network session can be bound to a specific IP 164address or port. For AF_UNIX, _local_if_ must be specified pointing to an 165appropriate *coap_address_t*. If _local_if_ is defined, the address families 166for _local_if_ and _server_ must be identical. The session will initially have 167a reference count of 1. 168 169To stop using a client session, the reference count must be decremented to 0 170by calling *coap_session_release*(3). See *coap_session*(3). This will remove 171the client endpoint's _session_ and all its associated information. 172 173*Function: coap_new_client_session_psk2()* 174 175The *coap_new_client_session_psk2*() function, for a specific _context_, is 176used to configure the (D)TLS context using the _setup_data_ variables as defined 177in the coap_dtls_cpsk_t structure in the newly created endpoint session - 178see *coap_encryption*(3). The connection is to the specified _server_ using 179the CoAP protocol _proto_ as defined above. If the port is set to 0 in 180_server_ (for AF_INET or AF_INET6), then the default CoAP port is used. 181 182Normally _local_if_ would be set to NULL, but by specifying 183_local_if_ the source of the network session can be bound to a specific IP 184address or port. For AF_UNIX, _local_if_ must be specified pointing to an 185appropriate *coap_address_t*. If _local_if_ is defined, the address families 186for _local_if_ and _server_ must be identical. The session will initially have 187a reference count of 1. 188 189To stop using a client session, the reference count must be decremented to 0 190by calling *coap_session_release*(3). See *coap_session*(3). This will remove 191the client endpoint's _session_ and all its associated information. 192 193*Function: coap_session_set_mtu()* 194 195The *coap_session_set_mtu*() function is used to set the MTU size 196(the maximum message size) of the data in a packet, excluding any IP or 197TCP/UDP overhead to _mtu_ for the client endpoint's _session_. The default 198MTU is 1152. 199 200*Function: coap_session_max_pdu_size()* 201 202The *coap_session_max_pdu_size*() function is used to get the maximum MTU 203size of the data for the client endpoint's _session_. 204 205RETURN VALUES 206------------- 207*coap_new_client_session*(), *coap_new_client_session_psk2*(), 208*coap_new_client_session_pki*() return a newly created client. 209session or NULL if there is a creation failure. 210 211*coap_session_max_pdu_size*() returns the MTU size. 212 213EXAMPLES 214-------- 215*CoAP Client Non-Encrypted Setup* 216[source, c] 217---- 218#include <coap@LIBCOAP_API_VERSION@/coap.h> 219 220#include <netinet/in.h> 221 222static coap_session_t * 223setup_client_session (struct in_addr ip_address) { 224 coap_session_t *session; 225 coap_address_t server; 226 /* See coap_context(3) */ 227 coap_context_t *context = coap_new_context(NULL); 228 229 if (!context) 230 return NULL; 231 /* See coap_block(3) */ 232 coap_context_set_block_mode(context, 233 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 234 235 236 /* See coap_address(3) */ 237 coap_address_init(&server); 238 server.addr.sa.sa_family = AF_INET; 239 server.addr.sin.sin_addr = ip_address; 240 server.addr.sin.sin_port = htons (5683); 241 242 session = coap_new_client_session(context, NULL, &server, COAP_PROTO_UDP); 243 if (!session) { 244 coap_free_context(context); 245 return NULL; 246 } 247 /* The context is in session->context */ 248 return session; 249} 250---- 251 252*CoAP Client Non-Encrypted Unix Domain Setup* 253[source, c] 254---- 255#include <coap@LIBCOAP_API_VERSION@/coap.h> 256 257#include <stdio.h> 258#include <sys/types.h> 259#include <unistd.h> 260 261static coap_session_t * 262setup_client_session (const char *server_ud) { 263 coap_session_t *session; 264 coap_address_t server; 265 coap_address_t local; 266 /* See coap_context(3) */ 267 coap_context_t *context = coap_new_context(NULL); 268 269 if (!context) 270 return NULL; 271 /* See coap_block(3) */ 272 coap_context_set_block_mode(context, 273 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 274 275 276 /* See coap_address(3) */ 277 coap_address_init(&server); 278 server.addr.sa.sa_family = AF_UNIX; 279 snprintf(server.addr.cun.sun_path, sizeof(server.addr.cun.sun_path), 280 "%s", server_ud); 281 282 /* Need to have a uniquely named local address */ 283 coap_address_init(&local); 284 local.addr.sa.sa_family = AF_UNIX; 285 snprintf(local.addr.cun.sun_path, sizeof(server.addr.cun.sun_path), 286 "/tmp/client.%d", getpid()); 287 /* Only do this if you know it is safe to do so */ 288 unlink(local.addr.cun.sun_path); 289 290 session = coap_new_client_session(context, &local, &server, COAP_PROTO_UDP); 291 if (!session) { 292 coap_free_context(context); 293 return NULL; 294 } 295 /* The context is in session->context */ 296 return session; 297} 298---- 299 300*CoAP Client PKI Setup* 301[source, c] 302---- 303#include <coap@LIBCOAP_API_VERSION@/coap.h> 304 305#include <netinet/in.h> 306 307static int 308verify_cn_callback(const char *cn, 309 const uint8_t *asn1_public_cert, 310 size_t asn1_length, 311 coap_session_t *c_session, 312 unsigned int depth, 313 int validated, 314 void *arg 315) { 316 /* Remove (void) definition if variable is used */ 317 (void)cn; 318 (void)asn1_public_cert; 319 (void)asn1_length; 320 (void)c_session; 321 (void)depth; 322 (void)validated; 323 (void)arg; 324 325 /* Check that the CN is valid */ 326 327 /* ... */ 328 329 return 1; 330} 331 332static coap_session_t * 333setup_client_session_pki (struct in_addr ip_address, 334 const char *public_cert_file, 335 const char *private_key_file, 336 const char *ca_file 337) { 338 coap_session_t *session; 339 coap_address_t server; 340 coap_dtls_pki_t dtls_pki; 341 /* See coap_context(3) */ 342 coap_context_t *context = coap_new_context(NULL); 343 344 if (!context) 345 return NULL; 346 /* See coap_block(3) */ 347 coap_context_set_block_mode(context, 348 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 349 350 351 /* See coap_address(3) */ 352 coap_address_init(&server); 353 server.addr.sa.sa_family = AF_INET; 354 server.addr.sin.sin_addr = ip_address; 355 server.addr.sin.sin_port = htons (5684); 356 357 memset (&dtls_pki, 0, sizeof (dtls_pki)); 358 359 /* See coap_encryption(3) */ 360 dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION; 361 dtls_pki.verify_peer_cert = 1; 362 dtls_pki.check_common_ca = 1; 363 dtls_pki.allow_self_signed = 1; 364 dtls_pki.allow_expired_certs = 1; 365 dtls_pki.cert_chain_validation = 1; 366 dtls_pki.cert_chain_verify_depth = 1; 367 dtls_pki.check_cert_revocation = 1; 368 dtls_pki.allow_no_crl = 1; 369 dtls_pki.allow_expired_crl = 1; 370 dtls_pki.allow_bad_md_hash = 0; 371 dtls_pki.allow_short_rsa_length = 0; 372 dtls_pki.is_rpk_not_cert = 0; /* Set to 1 if RPK */ 373 dtls_pki.validate_cn_call_back = verify_cn_callback; 374 dtls_pki.cn_call_back_arg = NULL; 375 dtls_pki.validate_sni_call_back = NULL; 376 dtls_pki.sni_call_back_arg = NULL; 377 dtls_pki.additional_tls_setup_call_back = NULL; 378 dtls_pki.client_sni = NULL; 379 dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM; 380 dtls_pki.pki_key.key.pem.ca_file = ca_file; 381 dtls_pki.pki_key.key.pem.public_cert = public_cert_file; 382 dtls_pki.pki_key.key.pem.private_key = private_key_file; 383 384 session = coap_new_client_session_pki(context, NULL, &server, 385 COAP_PROTO_DTLS, &dtls_pki); 386 if (!session) { 387 coap_free_context(context); 388 return NULL; 389 } 390 /* The context is in session->context */ 391 return session; 392} 393---- 394 395*CoAP Client PSK Setup* 396[source, c] 397---- 398#include <coap@LIBCOAP_API_VERSION@/coap.h> 399 400#include <stdio.h> 401#include <netinet/in.h> 402 403#ifndef min 404#define min(a,b) ((a) < (b) ? (a) : (b)) 405#endif 406 407static const coap_dtls_cpsk_info_t * 408verify_ih_callback(coap_str_const_t *hint, 409 coap_session_t *c_session, 410 void *arg 411) { 412 coap_dtls_cpsk_info_t *psk_info = (coap_dtls_cpsk_info_t *)arg; 413 /* Remove (void) definition if variable is used */ 414 (void)c_session; 415 416 coap_log_info("Identity Hint '%.*s' provided\n", (int)hint->length, hint->s); 417 418 /* Just use the defined information for now as passed in by arg */ 419 return psk_info; 420} 421 422static coap_dtls_cpsk_t dtls_psk; 423static char client_sni[256]; 424 425static coap_session_t * 426setup_client_session_psk (const char *uri, 427 struct in_addr ip_address, 428 const uint8_t *identity, 429 unsigned int identity_len, 430 const uint8_t *key, 431 unsigned int key_len 432) { 433 coap_session_t *session; 434 coap_address_t server; 435 /* See coap_context(3) */ 436 coap_context_t *context = coap_new_context(NULL); 437 438 if (!context) 439 return NULL; 440 /* See coap_block(3) */ 441 coap_context_set_block_mode(context, 442 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 443 444 445 /* See coap_address(3) */ 446 coap_address_init(&server); 447 server.addr.sa.sa_family = AF_INET; 448 server.addr.sin.sin_addr = ip_address; 449 server.addr.sin.sin_port = htons (5684); 450 451 /* See coap_encryption(3) */ 452 memset (&dtls_psk, 0, sizeof(dtls_psk)); 453 dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION; 454 dtls_psk.validate_ih_call_back = verify_ih_callback; 455 dtls_psk.ih_call_back_arg = &dtls_psk.psk_info; 456 if (uri) 457 memcpy(client_sni, uri, min(strlen(uri), sizeof(client_sni)-1)); 458 else 459 memcpy(client_sni, "localhost", 9); 460 dtls_psk.client_sni = client_sni; 461 dtls_psk.psk_info.identity.s = identity; 462 dtls_psk.psk_info.identity.length = identity_len; 463 dtls_psk.psk_info.key.s = key; 464 dtls_psk.psk_info.key.length = key_len; 465 session = coap_new_client_session_psk2(context, NULL, &server, 466 COAP_PROTO_DTLS, &dtls_psk); 467 if (!session) { 468 coap_free_context(context); 469 return NULL; 470 } 471 /* The context is in session->context */ 472 return session; 473} 474---- 475 476*CoAP Client Anonymous PKI Setup* 477[source, c] 478---- 479#include <coap@LIBCOAP_API_VERSION@/coap.h> 480 481#include <netinet/in.h> 482 483static coap_session_t * 484setup_client_session_dtls (struct in_addr ip_address) { 485 coap_session_t *session; 486 coap_address_t server; 487 /* See coap_context(3) */ 488 coap_context_t *context = coap_new_context(NULL); 489 490 if (!context) 491 return NULL; 492 /* See coap_block(3) */ 493 coap_context_set_block_mode(context, 494 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 495 496 497 /* See coap_address(3) */ 498 coap_address_init(&server); 499 server.addr.sa.sa_family = AF_INET; 500 server.addr.sin.sin_addr = ip_address; 501 server.addr.sin.sin_port = htons (5683); 502 503 session = coap_new_client_session(context, NULL, &server, 504 COAP_PROTO_DTLS); 505 if (!session) { 506 coap_free_context(context); 507 return NULL; 508 } 509 /* The context is in session->context */ 510 return session; 511} 512---- 513 514SEE ALSO 515-------- 516*coap_address*(3), *coap_block*(3), *coap_context*(3), *coap_encryption*(3), 517*coap_endpoint_server*(3), *coap_resource*(3), *coap_session*(3) and 518*coap_tls_library*(3) 519 520FURTHER INFORMATION 521------------------- 522See 523 524"https://rfc-editor.org/rfc/rfc7252[RFC7252: The Constrained Application Protocol (CoAP)]" 525 526"https://rfc-editor.org/rfc/rfc8323[RFC8323: CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets]" 527 528for further information. 529 530BUGS 531---- 532Please report bugs on the mailing list for libcoap: 533libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at 534https://github.com/obgm/libcoap/issues 535 536AUTHORS 537------- 538The libcoap project <libcoap-developers@lists.sourceforge.net> 539