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

RETURN VALUES

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

EXAMPLES

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

SEE ALSO

379       coap_block(3), coap_context(3), coap_encryption(3),
380       coap_endpoint_server(3), coap_resource(3), coap_session(3) and
381       coap_tls_library(3)
382

FURTHER INFORMATION

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

BUGS

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

AUTHORS

393       The libcoap project <libcoap-developers@lists.sourceforge.net>
394
395
396
397coap_endpoint_client 4.3.1        11/24/2022           COAP_ENDPOINT_CLIENT(3)
Impressum