1COAP_ENDPOINT_CLIENT(3) libcoap Manual COAP_ENDPOINT_CLIENT(3)
2
3
4
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
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
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
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
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
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
382 See "RFC7252: The Constrained Application Protocol (CoAP)" for further
383 information.
384
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
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)