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). 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
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
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
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
384 See "RFC7252: The Constrained Application Protocol (CoAP)" for further
385 information.
386
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
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)