1COAP_ENDPOINT_CLIENT(3)         libcoap Manual         COAP_ENDPOINT_CLIENT(3)
2
3
4

NAME

6       coap_endpoint_client, coap_new_client_session,
7       coap_new_client_session_psk2, coap_new_client_session_pki,
8       coap_session_set_mtu, coap_session_max_pdu_size - Work with CoAP client
9       endpoints
10

SYNOPSIS

12       #include <coap3/coap.h>
13
14       coap_session_t *coap_new_client_session(coap_context_t *context, const
15       coap_address_t *local_if, const coap_address_t *server, coap_proto_t
16       proto);
17
18       coap_session_t *coap_new_client_session_psk2(coap_context_t *context,
19       const coap_address_t *local_if, const coap_address_t *server,
20       coap_proto_t proto, coap_dtls_cpsk_t *setup_data);
21
22       coap_session_t *coap_new_client_session_pki(coap_context_t *context,
23       const coap_address_t *local_if, const coap_address_t *server,
24       coap_proto_t proto, coap_dtls_pki_t *setup_data);
25
26       void coap_session_set_mtu(coap_session_t *session, unsigned mtu);
27
28       size_t coap_session_max_pdu_size(const coap_session_t *session);
29
30       For specific (D)TLS library support, link with -lcoap-3-notls,
31       -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls or
32       -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default
33       (D)TLS library support.
34

DESCRIPTION

36       This man page focuses on the setting up of a CoAP client endpoint and
37       hence creation of a CoAP session used to connect to a server. For a
38       CoAP server endpoint, see coap_endpoint_server(3). There is no need to
39       call coap_new_endpoint(3) for a client as well as one of the
40       coap_new_client_server*() functions.
41
42       The CoAP stack’s global state is stored in a coap_context_t context
43       object. Resources, Endpoints and Sessions are associated with this
44       context object. There can be more than one coap_context_t object per
45       application, it is up to the application to manage each one
46       accordingly.
47
48       A CoAP session maintains the state of an ongoing connection between a
49       Client and Server which is stored in a coap_session_t session object. A
50       CoAP session is tracked by local port, CoAP protocol, remote IP address
51       and remote port, or in the case of Unix Domain sockets, the local path
52       and the remote path.
53
54       The session network traffic can be encrypted or un-encrypted if there
55       is an underlying TLS library.
56
57       If (D)TLS is going to be used for encrypting the network traffic, then
58       the (D)TLS information for Pre-Shared Keys (PSK) or Public Key
59       Infrastructure (PKI) needs to be configured before any network traffic
60       starts to flow. For Clients, this is done during the Client session set
61       up.
62
63       For Clients, all the encryption information can be held at the (D)TLS
64       context and CoAP context levels, or at the (D)TLS session and CoAP
65       session levels. If defined at the context level, then when a session is
66       created, it will inherit the context definitions, unless they have
67       separately been defined for the session level, in which case the
68       session version will get used. Typically the information will be
69       configured at the session level for Clients.
70
71       In principle the set-up sequence for CoAP client endpoints looks like
72
73           coap_new_context()
74           coap_context_set_pki_root_cas() - if the root CAs need to be updated and using PKI
75           coap_new_client_session(), coap_new_client_session_pki() or coap_new_client_session_psk2()
76
77       Multiple client endpoints and hence sessions are supported per context.
78
79       Different CoAP protocols can be defined for proto - the current
80       supported list is:
81
82           COAP_PROTO_UDP
83           COAP_PROTO_DTLS
84           COAP_PROTO_TCP
85           COAP_PROTO_TLS
86           COAP_PROTO_WS
87           COAP_PROTO_WSS
88
89       coap_tcp_is_supported(3), coap_dtls_is_supported(3),
90       coap_tls_is_supported(3), coap_ws_is_supported(3) and
91       coap_wss_is_supported(3) can be used for checking whether the
92       underlying TCP, (D)TLS or WebSocket protocol support is available. See
93       coap_tls_library(3) for further information on the types of (D)TLS
94       sessions supported.
95
96       Libcoap supports 3 different socket types:
97
98           AF_INET  IPv4 IP addresses and ports
99           AF_INET6 IPv6 IP addresses and ports and can be dual IPv4/IPv6 stacked
100           AF_UNIX  Unix Domain using file path names
101
102       For AF_INET and AF_INET6, the client does not need to specify a local
103       IP address and/or port as default values will get filled in. However
104       for AF_UNIX, the local pathname must be provided and must be unique per
105       client session. This unique local pathname will get deleted on the
106       session being properly closed at application exit.
107
108       The client must specify IP and port when defining the coap_address_t
109       (see coap_address_t(3)) for the remote end of the session if AF_INET or
110       AF_INET6. If port is 0, then the default CoAP port is used instead. If
111       AF_UNIX, the unix domain path to connect to must be specified.
112

FUNCTIONS

114       Function: coap_new_client_session()
115
116       The coap_new_client_session() function creates a client endpoint for a
117       specific context and initiates a new client session to the specified
118       server using the CoAP protocol proto as defined above. If the port is
119       set to 0 in server (for AF_INET or AF_INET6), then the default CoAP
120       port is used.
121
122       Normally local_if would be set to NULL, but by specifying local_if the
123       source of the network session can be bound to a specific IP address or
124       port. For AF_UNIX, local_if must be specified pointing to an
125       appropriate coap_address_t. If local_if is defined, the address
126       families for local_if and server must be identical. The session will
127       initially have a reference count of 1.
128
129       To stop using a client session, the reference count must be decremented
130       to 0 by calling coap_session_release(3). See coap_session(3). This will
131       remove the client endpoint’s session and all its associated
132       information.
133
134       Function: coap_new_client_session_pki()
135
136       The coap_new_client_session_pki() function, for a specific context, is
137       used to configure the (D)TLS context using the setup_data variables as
138       defined in the coap_dtls_pki_t structure in the newly created endpoint
139       session - see coap_encryption(3). The connection is to the specified
140       server using the CoAP protocol proto as defined above. If the port is
141       set to 0 in server (for AF_INET or AF_INET6), then the default CoAP
142       port is used.
143
144       Normally local_if would be set to NULL, but by specifying local_if the
145       source of the network session can be bound to a specific IP address or
146       port. For AF_UNIX, local_if must be specified pointing to an
147       appropriate coap_address_t. If local_if is defined, the address
148       families for local_if and server must be identical. The session will
149       initially have a reference count of 1.
150
151       To stop using a client session, the reference count must be decremented
152       to 0 by calling coap_session_release(3). See coap_session(3). This will
153       remove the client endpoint’s session and all its associated
154       information.
155
156       Function: coap_new_client_session_psk2()
157
158       The coap_new_client_session_psk2() function, for a specific context, is
159       used to configure the (D)TLS context using the setup_data variables as
160       defined in the coap_dtls_cpsk_t structure in the newly created endpoint
161       session - see coap_encryption(3). The connection is to the specified
162       server using the CoAP protocol proto as defined above. If the port is
163       set to 0 in server (for AF_INET or AF_INET6), then the default CoAP
164       port is used.
165
166       Normally local_if would be set to NULL, but by specifying local_if the
167       source of the network session can be bound to a specific IP address or
168       port. For AF_UNIX, local_if must be specified pointing to an
169       appropriate coap_address_t. If local_if is defined, the address
170       families for local_if and server must be identical. The session will
171       initially have a reference count of 1.
172
173       To stop using a client session, the reference count must be decremented
174       to 0 by calling coap_session_release(3). See coap_session(3). This will
175       remove the client endpoint’s session and all its associated
176       information.
177
178       Function: coap_session_set_mtu()
179
180       The coap_session_set_mtu() function is used to set the MTU size (the
181       maximum message size) of the data in a packet, excluding any IP or
182       TCP/UDP overhead to mtu for the client endpoint’s session. The default
183       MTU is 1152.
184
185       Function: coap_session_max_pdu_size()
186
187       The coap_session_max_pdu_size() function is used to get the maximum MTU
188       size of the data for the client endpoint’s session.
189

RETURN VALUES

191       coap_new_client_session(), coap_new_client_session_psk2(),
192       coap_new_client_session_pki() return a newly created client. session or
193       NULL if there is a creation failure.
194
195       coap_session_max_pdu_size() returns the MTU size.
196

EXAMPLES

198       CoAP Client Non-Encrypted Setup
199
200           #include <coap3/coap.h>
201
202           #include <netinet/in.h>
203
204           static coap_session_t *
205           setup_client_session (struct in_addr ip_address) {
206             coap_session_t *session;
207             coap_address_t server;
208             /* See coap_context(3) */
209             coap_context_t *context = coap_new_context(NULL);
210
211             if (!context)
212               return NULL;
213             /* See coap_block(3) */
214             coap_context_set_block_mode(context,
215                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
216
217
218             /* See coap_address(3) */
219             coap_address_init(&server);
220             server.addr.sa.sa_family = AF_INET;
221             server.addr.sin.sin_addr = ip_address;
222             server.addr.sin.sin_port = htons (5683);
223
224             session = coap_new_client_session(context, NULL, &server, COAP_PROTO_UDP);
225             if (!session) {
226               coap_free_context(context);
227               return NULL;
228             }
229             /* The context is in session->context */
230             return session;
231           }
232
233       CoAP Client Non-Encrypted Unix Domain Setup
234
235           #include <coap3/coap.h>
236
237           #include <stdio.h>
238           #include <sys/types.h>
239           #include <unistd.h>
240
241           static coap_session_t *
242           setup_client_session (const char *server_ud) {
243             coap_session_t *session;
244             coap_address_t server;
245             coap_address_t local;
246             /* See coap_context(3) */
247             coap_context_t *context = coap_new_context(NULL);
248
249             if (!context)
250               return NULL;
251             /* See coap_block(3) */
252             coap_context_set_block_mode(context,
253                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
254
255
256             /* See coap_address(3) */
257             coap_address_init(&server);
258             server.addr.sa.sa_family = AF_UNIX;
259             snprintf(server.addr.cun.sun_path, sizeof(server.addr.cun.sun_path),
260                      "%s", server_ud);
261
262             /* Need to have a uniquely named local address */
263             coap_address_init(&local);
264             local.addr.sa.sa_family = AF_UNIX;
265             snprintf(local.addr.cun.sun_path, sizeof(server.addr.cun.sun_path),
266                      "/tmp/client.%d", getpid());
267             /* Only do this if you know it is safe to do so */
268             unlink(local.addr.cun.sun_path);
269
270             session = coap_new_client_session(context, &local, &server, COAP_PROTO_UDP);
271             if (!session) {
272               coap_free_context(context);
273               return NULL;
274             }
275             /* The context is in session->context */
276             return session;
277           }
278
279       CoAP Client PKI Setup
280
281           #include <coap3/coap.h>
282
283           #include <netinet/in.h>
284
285           static int
286           verify_cn_callback(const char *cn,
287                              const uint8_t *asn1_public_cert,
288                              size_t asn1_length,
289                              coap_session_t *c_session,
290                              unsigned int depth,
291                              int validated,
292                              void *arg
293           ) {
294             /* Remove (void) definition if variable is used */
295             (void)cn;
296             (void)asn1_public_cert;
297             (void)asn1_length;
298             (void)c_session;
299             (void)depth;
300             (void)validated;
301             (void)arg;
302
303             /* Check that the CN is valid */
304
305             /* ... */
306
307             return 1;
308           }
309
310           static coap_session_t *
311           setup_client_session_pki (struct in_addr ip_address,
312                                     const char *public_cert_file,
313                                     const char *private_key_file,
314                                     const char *ca_file
315           ) {
316             coap_session_t *session;
317             coap_address_t server;
318             coap_dtls_pki_t dtls_pki;
319             /* See coap_context(3) */
320             coap_context_t *context = coap_new_context(NULL);
321
322             if (!context)
323               return NULL;
324             /* See coap_block(3) */
325             coap_context_set_block_mode(context,
326                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
327
328
329             /* See coap_address(3) */
330             coap_address_init(&server);
331             server.addr.sa.sa_family = AF_INET;
332             server.addr.sin.sin_addr = ip_address;
333             server.addr.sin.sin_port = htons (5684);
334
335             memset (&dtls_pki, 0, sizeof (dtls_pki));
336
337             /* See coap_encryption(3) */
338             dtls_pki.version                 = COAP_DTLS_PKI_SETUP_VERSION;
339             dtls_pki.verify_peer_cert        = 1;
340             dtls_pki.check_common_ca         = 1;
341             dtls_pki.allow_self_signed       = 1;
342             dtls_pki.allow_expired_certs     = 1;
343             dtls_pki.cert_chain_validation   = 1;
344             dtls_pki.cert_chain_verify_depth = 1;
345             dtls_pki.check_cert_revocation   = 1;
346             dtls_pki.allow_no_crl            = 1;
347             dtls_pki.allow_expired_crl       = 1;
348             dtls_pki.allow_bad_md_hash       = 0;
349             dtls_pki.allow_short_rsa_length  = 0;
350             dtls_pki.is_rpk_not_cert         = 0; /* Set to 1 if RPK */
351             dtls_pki.validate_cn_call_back   = verify_cn_callback;
352             dtls_pki.cn_call_back_arg        = NULL;
353             dtls_pki.validate_sni_call_back  = NULL;
354             dtls_pki.sni_call_back_arg       = NULL;
355             dtls_pki.additional_tls_setup_call_back = NULL;
356             dtls_pki.client_sni              = NULL;
357             dtls_pki.pki_key.key_type        = COAP_PKI_KEY_PEM;
358             dtls_pki.pki_key.key.pem.ca_file = ca_file;
359             dtls_pki.pki_key.key.pem.public_cert = public_cert_file;
360             dtls_pki.pki_key.key.pem.private_key = private_key_file;
361
362             session = coap_new_client_session_pki(context, NULL, &server,
363                                                   COAP_PROTO_DTLS, &dtls_pki);
364             if (!session) {
365               coap_free_context(context);
366               return NULL;
367             }
368             /* The context is in session->context */
369             return session;
370           }
371
372       CoAP Client PSK Setup
373
374           #include <coap3/coap.h>
375
376           #include <stdio.h>
377           #include <netinet/in.h>
378
379           #ifndef min
380           #define min(a,b) ((a) < (b) ? (a) : (b))
381           #endif
382
383           static const coap_dtls_cpsk_info_t *
384           verify_ih_callback(coap_str_const_t *hint,
385                              coap_session_t *c_session,
386                              void *arg
387           ) {
388             coap_dtls_cpsk_info_t *psk_info = (coap_dtls_cpsk_info_t *)arg;
389             /* Remove (void) definition if variable is used */
390             (void)c_session;
391
392             coap_log_info("Identity Hint '%.*s' provided\n", (int)hint->length, hint->s);
393
394             /* Just use the defined information for now as passed in by arg */
395             return psk_info;
396           }
397
398           static coap_dtls_cpsk_t dtls_psk;
399           static char client_sni[256];
400
401           static coap_session_t *
402           setup_client_session_psk (const char *uri,
403                                     struct in_addr ip_address,
404                                     const uint8_t *identity,
405                                     unsigned int identity_len,
406                                     const uint8_t *key,
407                                     unsigned int key_len
408           ) {
409             coap_session_t *session;
410             coap_address_t server;
411             /* See coap_context(3) */
412             coap_context_t *context = coap_new_context(NULL);
413
414             if (!context)
415               return NULL;
416             /* See coap_block(3) */
417             coap_context_set_block_mode(context,
418                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
419
420
421             /* See coap_address(3) */
422             coap_address_init(&server);
423             server.addr.sa.sa_family = AF_INET;
424             server.addr.sin.sin_addr = ip_address;
425             server.addr.sin.sin_port = htons (5684);
426
427             /* See coap_encryption(3) */
428             memset (&dtls_psk, 0, sizeof(dtls_psk));
429             dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION;
430             dtls_psk.validate_ih_call_back = verify_ih_callback;
431             dtls_psk.ih_call_back_arg = &dtls_psk.psk_info;
432             if (uri)
433               memcpy(client_sni, uri, min(strlen(uri), sizeof(client_sni)-1));
434             else
435               memcpy(client_sni, "localhost", 9);
436             dtls_psk.client_sni = client_sni;
437             dtls_psk.psk_info.identity.s = identity;
438             dtls_psk.psk_info.identity.length = identity_len;
439             dtls_psk.psk_info.key.s = key;
440             dtls_psk.psk_info.key.length = key_len;
441             session = coap_new_client_session_psk2(context, NULL, &server,
442                                                   COAP_PROTO_DTLS, &dtls_psk);
443             if (!session) {
444               coap_free_context(context);
445               return NULL;
446             }
447             /* The context is in session->context */
448             return session;
449           }
450
451       CoAP Client Anonymous PKI Setup
452
453           #include <coap3/coap.h>
454
455           #include <netinet/in.h>
456
457           static coap_session_t *
458           setup_client_session_dtls (struct in_addr ip_address) {
459             coap_session_t *session;
460             coap_address_t server;
461             /* See coap_context(3) */
462             coap_context_t *context = coap_new_context(NULL);
463
464             if (!context)
465               return NULL;
466             /* See coap_block(3) */
467             coap_context_set_block_mode(context,
468                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
469
470
471             /* See coap_address(3) */
472             coap_address_init(&server);
473             server.addr.sa.sa_family = AF_INET;
474             server.addr.sin.sin_addr = ip_address;
475             server.addr.sin.sin_port = htons (5683);
476
477             session = coap_new_client_session(context, NULL, &server,
478                                                   COAP_PROTO_DTLS);
479             if (!session) {
480               coap_free_context(context);
481               return NULL;
482             }
483             /* The context is in session->context */
484             return session;
485           }
486

SEE ALSO

488       coap_address(3), coap_block(3), coap_context(3), coap_encryption(3),
489       coap_endpoint_server(3), coap_resource(3), coap_session(3) and
490       coap_tls_library(3)
491

FURTHER INFORMATION

493       See
494
495       "RFC7252: The Constrained Application Protocol (CoAP)"
496
497       "RFC8323: CoAP (Constrained Application Protocol) over TCP, TLS, and
498       WebSockets"
499
500       for further information.
501

BUGS

503       Please report bugs on the mailing list for libcoap:
504       libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
505       https://github.com/obgm/libcoap/issues
506

AUTHORS

508       The libcoap project <libcoap-developers@lists.sourceforge.net>
509
510
511
512coap_endpoint_client 4.3.4        10/09/2023           COAP_ENDPOINT_CLIENT(3)
Impressum