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).
39
40       The CoAP stack’s global state is stored in a coap_context_t Context
41       object. Resources, Endpoints and Sessions are associated with this
42       context object. There can be more than one coap_context_t object per
43       application, it is up to the application to manage each one
44       accordingly.
45
46       A CoAP Ssssion maintains the state of an ongoing connection between a
47       Client and Server which is stored in a coap_session_t Session object. A
48       CoAP session is tracked by local port, CoAP protocol, remote IP address
49       and remote port.
50
51       The Session network traffic can be encrypted or un-encrypted if there
52       is an underlying TLS library.
53
54       If TLS is going to be used for encrypting the network traffic, then the
55       TLS information for Pre-Shared Keys (PSK) or Public Key Infrastructure
56       (PKI) needs to be configured before any network traffic starts to flow.
57       For Servers, this has to be done before the Endpoint is created, for
58       Clients, this is done during the Client Endpoint/Session set up.
59
60       For Clients, all the encryption information can be held at the TLS
61       Context and CoAP Context levels, or at the TLS Session and CoAP Session
62       levels. If defined at the Context level, then when Sessions are
63       created, they will inherit the Context definitions, unless they have
64       separately been defined for the Session level, in which case the
65       Session version will get used. Typically the information will be
66       configured at the Session level for Clients.
67
68       In principle the set-up sequence for CoAP client endpoints looks like
69
70           coap_new_context()
71           coap_context_set_pki_root_cas() if the root CAs need to be updated and PKI
72           coap_new_client_session(), coap_new_client_session_pki() or coap_new_client_session_psk2()
73
74       Multiple client endpoints and hence sessions are supported per Context.
75
76       Different CoAP protocols can be defined for proto - the current
77       supported list is:
78
79           COAP_PROTO_UDP
80           COAP_PROTO_DTLS
81           COAP_PROTO_TCP
82           COAP_PROTO_TLS
83
84       coap_tcp_is_supported(), coap_dtls_is_supported() and
85       coap_tls_is_supported() can be used for checking whether the underlying
86       TCP or (D)TLS protocol support is available. See coap_tls_library(3)
87       for further information.
88
89       The coap_new_client_session() function creates a client endpoint for a
90       specific context and initiates a new client session to the specified
91       server using the CoAP protocol proto. If the port is set to 0 in
92       server, then the default CoAP port is used. Normally local_if would be
93       set to NULL, but by specifying local_if the source of the network
94       session can be bound to a specific IP address or port. The session will
95       initially have a reference count of 1.
96
97       The coap_new_client_session_pki() function, for a specific context, is
98       used to configure the TLS context using the setup_data variables as
99       defined in the coap_dtls_pki_t structure in the newly created endpoint
100       session - see coap_encryption(3). The connection is to the specified
101       server using the CoAP protocol proto. If the port is set to 0 in
102       server, then the default CoAP port is used. Normally local_if would be
103       set to NULL, but by specifying local_if the source of the network
104       session can be bound to a specific IP address or port. The session will
105       initially have a reference count of 1.
106
107       The coap_new_client_session_psk2() function, for a specific context, is
108       used to configure the TLS context using the setup_data variables as
109       defined in the coap_dtls_cpsk_t structure in the newly created endpoint
110       session - see coap_encryption(3). The connection is to the specified
111       server using the CoAP protocol proto. If the port is set to 0 in
112       server, then the default CoAP port is used. Normally local_if would be
113       set to NULL, but by specifying local_if the source of the network
114       session can be bound to a specific IP address or port. The session will
115       initially have a reference count of 1.
116
117       To stop using a client session, the reference count must be decremented
118       to 0 by calling coap_session_release(). See coap_session(3). This will
119       remove the client endpoint.
120
121       The coap_sesson_set_default_mtu() function is used to set the MTU size
122       (the maximum message size) of the data in a packet, excluding any IP or
123       TCP/UDP overhead to mtu for the client endpoint’s session. The default
124       MTU is 1152.
125
126       The coap_session_max_pdu_size() function is used to get the maximum MTU
127       size of the data for the client endpoint’s session.
128

RETURN VALUES

130       coap_new_client_session(), coap_new_client_session_psk2(),
131       coap_new_client_session_pki() functions returns a newly created client
132       session or NULL if there is a creation failure.
133
134       coap_session_max_pdu_size() function returns the MTU size.
135

EXAMPLES

137       CoAP Client Non-Encrypted Setup
138
139           #include <coap3/coap.h>
140
141           #include <netinet/in.h>
142
143           static coap_session_t *
144           setup_client_session (struct in_addr ip_address) {
145             coap_session_t *session;
146             coap_address_t server;
147             /* See coap_context(3) */
148             coap_context_t *context = coap_new_context(NULL);
149
150             if (!context)
151               return NULL;
152             /* See coap_block(3) */
153             coap_context_set_block_mode(context,
154                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
155
156
157             coap_address_init(&server);
158             server.addr.sa.sa_family = AF_INET;
159             server.addr.sin.sin_addr = ip_address;
160             server.addr.sin.sin_port = htons (5683);
161
162             session = coap_new_client_session(context, NULL, &server, COAP_PROTO_UDP);
163             if (!session) {
164               coap_free_context(context);
165               return NULL;
166             }
167             /* The context is in session->context */
168             return session;
169           }
170
171       CoAP Client PKI Setup
172
173           #include <coap3/coap.h>
174
175           #include <netinet/in.h>
176
177           static int
178           verify_cn_callback(const char *cn,
179                              const uint8_t *asn1_public_cert,
180                              size_t asn1_length,
181                              coap_session_t *c_session,
182                              unsigned int depth,
183                              int validated,
184                              void *arg
185           ) {
186             /* Remove (void) definition if variable is used */
187             (void)cn;
188             (void)asn1_public_cert;
189             (void)asn1_length;
190             (void)c_session;
191             (void)depth;
192             (void)validated;
193             (void)arg;
194
195             /* Check that the CN is valid */
196
197             /* ... */
198
199             return 1;
200           }
201
202           static coap_session_t *
203           setup_client_session_pki (struct in_addr ip_address,
204                                     const char *public_cert_file,
205                                     const char *private_key_file,
206                                     const char *ca_file
207           ) {
208             coap_session_t *session;
209             coap_address_t server;
210             coap_dtls_pki_t dtls_pki;
211             /* See coap_context(3) */
212             coap_context_t *context = coap_new_context(NULL);
213
214             if (!context)
215               return NULL;
216             /* See coap_block(3) */
217             coap_context_set_block_mode(context,
218                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
219
220
221             coap_address_init(&server);
222             server.addr.sa.sa_family = AF_INET;
223             server.addr.sin.sin_addr = ip_address;
224             server.addr.sin.sin_port = htons (5684);
225
226             memset (&dtls_pki, 0, sizeof (dtls_pki));
227
228             /* See coap_encryption(3) */
229             dtls_pki.version                 = COAP_DTLS_PKI_SETUP_VERSION;
230             dtls_pki.verify_peer_cert        = 1;
231             dtls_pki.check_common_ca         = 1;
232             dtls_pki.allow_self_signed       = 1;
233             dtls_pki.allow_expired_certs     = 1;
234             dtls_pki.cert_chain_validation   = 1;
235             dtls_pki.cert_chain_verify_depth = 1;
236             dtls_pki.check_cert_revocation   = 1;
237             dtls_pki.allow_no_crl            = 1;
238             dtls_pki.allow_expired_crl       = 1;
239             dtls_pki.allow_bad_md_hash       = 0;
240             dtls_pki.allow_short_rsa_length  = 0;
241             dtls_pki.is_rpk_not_cert         = 0; /* Set to 1 if RPK */
242             dtls_pki.validate_cn_call_back   = verify_cn_callback;
243             dtls_pki.cn_call_back_arg        = NULL;
244             dtls_pki.validate_sni_call_back  = NULL;
245             dtls_pki.sni_call_back_arg       = NULL;
246             dtls_pki.additional_tls_setup_call_back = NULL;
247             dtls_pki.client_sni              = NULL;
248             dtls_pki.pki_key.key_type        = COAP_PKI_KEY_PEM;
249             dtls_pki.pki_key.key.pem.ca_file = ca_file;
250             dtls_pki.pki_key.key.pem.public_cert = public_cert_file;
251             dtls_pki.pki_key.key.pem.private_key = private_key_file;
252
253             session = coap_new_client_session_pki(context, NULL, &server,
254                                                   COAP_PROTO_DTLS, &dtls_pki);
255             if (!session) {
256               coap_free_context(context);
257               return NULL;
258             }
259             /* The context is in session->context */
260             return session;
261           }
262
263       CoAP Client PSK Setup
264
265           #include <coap3/coap.h>
266
267           #include <stdio.h>
268           #include <netinet/in.h>
269
270           #ifndef min
271           #define min(a,b) ((a) < (b) ? (a) : (b))
272           #endif
273
274           static const coap_dtls_cpsk_info_t *
275           verify_ih_callback(coap_str_const_t *hint,
276                              coap_session_t *c_session,
277                              void *arg
278           ) {
279             coap_dtls_cpsk_info_t *psk_info = (coap_dtls_cpsk_info_t *)arg;
280             /* Remove (void) definition if variable is used */
281             (void)c_session;
282
283             coap_log(LOG_INFO, "Identity Hint '%.*s' provided\n", (int)hint->length, hint->s);
284
285             /* Just use the defined information for now as passed in by arg */
286             return psk_info;
287           }
288
289           static coap_dtls_cpsk_t dtls_psk;
290           static char client_sni[256];
291
292           static coap_session_t *
293           setup_client_session_psk (const char *uri,
294                                     struct in_addr ip_address,
295                                     const uint8_t *identity,
296                                     unsigned int identity_len,
297                                     const uint8_t *key,
298                                     unsigned int key_len
299           ) {
300             coap_session_t *session;
301             coap_address_t server;
302             /* See coap_context(3) */
303             coap_context_t *context = coap_new_context(NULL);
304
305             if (!context)
306               return NULL;
307             /* See coap_block(3) */
308             coap_context_set_block_mode(context,
309                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
310
311
312             coap_address_init(&server);
313             server.addr.sa.sa_family = AF_INET;
314             server.addr.sin.sin_addr = ip_address;
315             server.addr.sin.sin_port = htons (5684);
316
317             /* See coap_encryption(3) */
318             memset (&dtls_psk, 0, sizeof(dtls_psk));
319             dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION;
320             dtls_psk.validate_ih_call_back = verify_ih_callback;
321             dtls_psk.ih_call_back_arg = &dtls_psk.psk_info;
322             if (uri)
323               memcpy(client_sni, uri, min(strlen(uri), sizeof(client_sni)-1));
324             else
325               memcpy(client_sni, "localhost", 9);
326             dtls_psk.client_sni = client_sni;
327             dtls_psk.psk_info.identity.s = identity;
328             dtls_psk.psk_info.identity.length = identity_len;
329             dtls_psk.psk_info.key.s = key;
330             dtls_psk.psk_info.key.length = key_len;
331             session = coap_new_client_session_psk2(context, NULL, &server,
332                                                   COAP_PROTO_DTLS, &dtls_psk);
333             if (!session) {
334               coap_free_context(context);
335               return NULL;
336             }
337             /* The context is in session->context */
338             return session;
339           }
340
341       CoAP Client Anonymous PKI Setup
342
343           #include <coap3/coap.h>
344
345           #include <netinet/in.h>
346
347           static coap_session_t *
348           setup_client_session_dtls (struct in_addr ip_address) {
349             coap_session_t *session;
350             coap_address_t server;
351             /* See coap_context(3) */
352             coap_context_t *context = coap_new_context(NULL);
353
354             if (!context)
355               return NULL;
356             /* See coap_block(3) */
357             coap_context_set_block_mode(context,
358                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
359
360
361             coap_address_init(&server);
362             server.addr.sa.sa_family = AF_INET;
363             server.addr.sin.sin_addr = ip_address;
364             server.addr.sin.sin_port = htons (5683);
365
366             session = coap_new_client_session(context, NULL, &server,
367                                                   COAP_PROTO_DTLS);
368             if (!session) {
369               coap_free_context(context);
370               return NULL;
371             }
372             /* The context is in session->context */
373             return session;
374           }
375

SEE ALSO

377       coap_block(3), coap_context(3), coap_encryption(3),
378       coap_endpoint_server()3), coap_resource(3), coap_session(3) and
379       coap_tls_library(3)
380

FURTHER INFORMATION

382       See "RFC7252: The Constrained Application Protocol (CoAP)" for further
383       information.
384

BUGS

386       Please report bugs on the mailing list for libcoap:
387       libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
388       https://github.com/obgm/libcoap/issues
389

AUTHORS

391       The libcoap project <libcoap-developers@lists.sourceforge.net>
392
393
394
395coap_endpoint_client 4.3.0        01/20/2022           COAP_ENDPOINT_CLIENT(3)
Impressum