libcoap  4.2.0
coap_session.c
Go to the documentation of this file.
1 /* session.c -- Session management for libcoap
2 *
3 * Copyright (C) 2017 Jean-Claue Michelou <jcm@spinetix.com>
4 *
5 * This file is part of the CoAP library libcoap. Please see
6 * README for terms of use.
7 */
8 
9 #ifndef COAP_SESSION_C_
10 #define COAP_SESSION_C_
11 
12 
13 #include "coap_config.h"
14 #include "coap_io.h"
15 #include "coap_session.h"
16 #include "net.h"
17 #include "coap_debug.h"
18 #include "mem.h"
19 #include "resource.h"
20 #include "utlist.h"
21 #include "encode.h"
22 #include <stdio.h>
23 
24 
25 void
26 coap_session_set_max_retransmit (coap_session_t *session, unsigned int value) {
27  if (value > 0)
28  session->max_retransmit = value;
29  coap_log(LOG_DEBUG, "***%s: session max_retransmit set to %d\n",
30  coap_session_str(session), session->max_retransmit);
31  return;
32 }
33 
34 void
36  if (value.integer_part > 0 && value.fractional_part < 1000)
37  session->ack_timeout = value;
38  coap_log(LOG_DEBUG, "***%s: session ack_timeout set to %d.%03d\n",
39  coap_session_str(session), session->ack_timeout.integer_part,
40  session->ack_timeout.fractional_part);
41  return;
42 }
43 
44 void
46  coap_fixed_point_t value) {
47  if (value.integer_part > 0 && value.fractional_part < 1000)
48  session->ack_random_factor = value;
49  coap_log(LOG_DEBUG, "***%s: session ack_random_factor set to %d.%03d\n",
52  return;
53 }
54 
55 unsigned int
57  return session->max_retransmit;
58 }
59 
62  return session->ack_timeout;
63 }
64 
67  return session->ack_random_factor;
68 }
69 
72  ++session->ref;
73  return session;
74 }
75 
76 void
78  if (session) {
79  assert(session->ref > 0);
80  if (session->ref > 0)
81  --session->ref;
82  if (session->ref == 0 && session->type == COAP_SESSION_TYPE_CLIENT)
83  coap_session_free(session);
84  }
85 }
86 
87 void
88 coap_session_set_app_data(coap_session_t *session, void *app_data) {
89  assert(session);
90  session->app = app_data;
91 }
92 
93 void *
95  assert(session);
96  return session->app;
97 }
98 
99 static coap_session_t *
101  const coap_address_t *local_if, const coap_address_t *local_addr,
102  const coap_address_t *remote_addr, int ifindex, coap_context_t *context,
103  coap_endpoint_t *endpoint) {
105  if (!session)
106  return NULL;
107  memset(session, 0, sizeof(*session));
108  session->proto = proto;
109  session->type = type;
110  if (local_if)
111  coap_address_copy(&session->local_if, local_if);
112  else
113  coap_address_init(&session->local_if);
114  if (local_addr)
115  coap_address_copy(&session->local_addr, local_addr);
116  else
117  coap_address_init(&session->local_addr);
118  if (remote_addr)
119  coap_address_copy(&session->remote_addr, remote_addr);
120  else
121  coap_address_init(&session->remote_addr);
122  session->ifindex = ifindex;
123  session->context = context;
124  session->endpoint = endpoint;
125  if (endpoint)
126  session->mtu = endpoint->default_mtu;
127  else
128  session->mtu = COAP_DEFAULT_MTU;
129  if (proto == COAP_PROTO_DTLS) {
130  session->tls_overhead = 29;
131  if (session->tls_overhead >= session->mtu) {
132  session->tls_overhead = session->mtu;
133  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
134  }
135  }
139  session->dtls_event = -1;
140 
141  /* initialize message id */
142  prng((unsigned char *)&session->tx_mid, sizeof(session->tx_mid));
143 
144  return session;
145 }
146 
148  coap_queue_t *q, *tmp;
149 
150  if (session->partial_pdu)
151  coap_delete_pdu(session->partial_pdu);
152  if (session->proto == COAP_PROTO_DTLS)
153  coap_dtls_free_session(session);
154  else if (session->proto == COAP_PROTO_TLS)
155  coap_tls_free_session(session);
156  if (session->sock.flags != COAP_SOCKET_EMPTY)
157  coap_socket_close(&session->sock);
158  if (session->psk_identity)
159  coap_free(session->psk_identity);
160  if (session->psk_key)
161  coap_free(session->psk_key);
162 
163  LL_FOREACH_SAFE(session->delayqueue, q, tmp) {
164  if (q->pdu->type==COAP_MESSAGE_CON && session->context && session->context->nack_handler)
165  session->context->nack_handler(session->context, session, q->pdu, session->proto == COAP_PROTO_DTLS ? COAP_NACK_TLS_FAILED : COAP_NACK_NOT_DELIVERABLE, q->id);
166  coap_delete_node(q);
167  }
168 }
169 
171  if (!session)
172  return;
173  assert(session->ref == 0);
174  if (session->ref)
175  return;
176  if (session->endpoint) {
177  if (session->endpoint->sessions)
178  LL_DELETE(session->endpoint->sessions, session);
179  } else if (session->context) {
180  if (session->context->sessions)
181  LL_DELETE(session->context->sessions, session);
182  }
183  coap_session_mfree(session);
184  coap_log(LOG_DEBUG, "***%s: session closed\n", coap_session_str(session));
185 
186  coap_free_type(COAP_SESSION, session);
187 }
188 
190  size_t max_with_header = (size_t)(session->mtu - session->tls_overhead);
191  if (COAP_PROTO_NOT_RELIABLE(session->proto))
192  return max_with_header > 4 ? max_with_header - 4 : 0;
193  /* we must assume there is no token to be on the safe side */
194  if (max_with_header <= 2)
195  return 0;
196  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP0 + 2)
197  return max_with_header - 2;
198  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP8 + 3)
199  return max_with_header - 3;
200  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP16 + 4)
201  return max_with_header - 4;
202  else
203  return max_with_header - 6;
204 }
205 
206 void coap_session_set_mtu(coap_session_t *session, unsigned mtu) {
207 #if defined(WITH_CONTIKI) || defined(WITH_LWIP)
208  if (mtu > COAP_MAX_MESSAGE_SIZE_TCP16 + 4)
209  mtu = COAP_MAX_MESSAGE_SIZE_TCP16 + 4;
210 #endif
211  session->mtu = mtu;
212  if (session->tls_overhead >= session->mtu) {
213  session->tls_overhead = session->mtu;
214  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
215  }
216 }
217 
218 ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen) {
219  ssize_t bytes_written;
220 
221  coap_socket_t *sock = &session->sock;
222  if (sock->flags == COAP_SOCKET_EMPTY) {
223  assert(session->endpoint != NULL);
224  sock = &session->endpoint->sock;
225  }
226 
227  bytes_written = coap_socket_send(sock, session, data, datalen);
228  if (bytes_written == (ssize_t)datalen) {
229  coap_ticks(&session->last_rx_tx);
230  coap_log(LOG_DEBUG, "* %s: sent %zd bytes\n",
231  coap_session_str(session), datalen);
232  } else {
233  coap_log(LOG_DEBUG, "* %s: failed to send %zd bytes\n",
234  coap_session_str(session), datalen);
235  }
236  return bytes_written;
237 }
238 
239 ssize_t coap_session_write(coap_session_t *session, const uint8_t *data, size_t datalen) {
240  ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
241  if (bytes_written > 0) {
242  coap_ticks(&session->last_rx_tx);
243  coap_log(LOG_DEBUG, "* %s: sent %zd bytes\n",
244  coap_session_str(session), datalen);
245  } else if (bytes_written < 0) {
246  coap_log(LOG_DEBUG, "* %s: failed to send %zd bytes\n",
247  coap_session_str(session), datalen );
248  }
249  return bytes_written;
250 }
251 
252 ssize_t
254  coap_queue_t *node)
255 {
256  if ( node ) {
257  coap_queue_t *removed = NULL;
258  coap_remove_from_queue(&session->context->sendqueue, session, node->id, &removed);
259  assert(removed == node);
261  node->session = NULL;
262  node->t = 0;
263  } else {
264  coap_queue_t *q = NULL;
265  /* Check that the same tid is not getting re-used in violation of RFC7252 */
266  LL_FOREACH(session->delayqueue, q) {
267  if (q->id == pdu->tid) {
268  coap_log(LOG_ERR, "** %s: tid=%d: already in-use - dropped\n", coap_session_str(session), pdu->tid);
269  return COAP_INVALID_TID;
270  }
271  }
272  node = coap_new_node();
273  if (node == NULL)
274  return COAP_INVALID_TID;
275  node->id = pdu->tid;
276  node->pdu = pdu;
277  if (pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
278  uint8_t r;
279  prng(&r, sizeof(r));
280  /* add timeout in range [ACK_TIMEOUT...ACK_TIMEOUT * ACK_RANDOM_FACTOR] */
281  node->timeout = coap_calc_timeout(session, r);
282  }
283  }
284  LL_APPEND(session->delayqueue, node);
285  coap_log(LOG_DEBUG, "** %s: tid=%d: delayed\n",
286  coap_session_str(session), node->id);
287  return COAP_PDU_DELAYED;
288 }
289 
291  coap_pdu_t *pdu;
292  uint8_t buf[4];
293  assert(COAP_PROTO_RELIABLE(session->proto));
294  coap_log(LOG_DEBUG, "***%s: sending CSM\n", coap_session_str(session));
295  session->state = COAP_SESSION_STATE_CSM;
296  session->partial_write = 0;
297  if (session->mtu == 0)
298  session->mtu = COAP_DEFAULT_MTU; /* base value */
300  if ( pdu == NULL
302  coap_encode_var_safe(buf, sizeof(buf),
303  COAP_DEFAULT_MAX_PDU_RX_SIZE), buf) == 0
304  || coap_pdu_encode_header(pdu, session->proto) == 0
305  ) {
307  } else {
308  ssize_t bytes_written = coap_session_send_pdu(session, pdu);
309  if (bytes_written != (ssize_t)pdu->used_size + pdu->hdr_size)
311  }
312  if (pdu)
313  coap_delete_pdu(pdu);
314 }
315 
317  coap_pdu_t *ping;
318  if (session->state != COAP_SESSION_STATE_ESTABLISHED)
319  return 0;
321  if (!ping)
322  return COAP_INVALID_TID;
323  return coap_send(session, ping);
324 }
325 
327  if (session->state != COAP_SESSION_STATE_ESTABLISHED) {
328  coap_log(LOG_DEBUG, "***%s: session connected\n",
329  coap_session_str(session));
330  if (session->state == COAP_SESSION_STATE_CSM)
332  }
333 
335  session->partial_write = 0;
336 
337  if ( session->proto==COAP_PROTO_DTLS) {
338  session->tls_overhead = coap_dtls_get_overhead(session);
339  if (session->tls_overhead >= session->mtu) {
340  session->tls_overhead = session->mtu;
341  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
342  }
343  }
344 
345  while (session->delayqueue && session->state == COAP_SESSION_STATE_ESTABLISHED) {
346  ssize_t bytes_written;
347  coap_queue_t *q = session->delayqueue;
348  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
349  if (session->con_active >= COAP_DEFAULT_NSTART)
350  break;
351  session->con_active++;
352  }
353  /* Take entry off the queue */
354  session->delayqueue = q->next;
355  q->next = NULL;
356 
357  coap_log(LOG_DEBUG, "** %s: tid=%d: transmitted after delay\n",
358  coap_session_str(session), (int)q->pdu->tid);
359  bytes_written = coap_session_send_pdu(session, q->pdu);
360  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
361  if (coap_wait_ack(session->context, session, q) >= 0)
362  q = NULL;
363  }
364  if (COAP_PROTO_NOT_RELIABLE(session->proto)) {
365  if (q)
366  coap_delete_node(q);
367  if (bytes_written < 0)
368  break;
369  } else {
370  if (bytes_written <= 0 || (size_t)bytes_written < q->pdu->used_size + q->pdu->hdr_size) {
371  q->next = session->delayqueue;
372  session->delayqueue = q;
373  if (bytes_written > 0)
374  session->partial_write = (size_t)bytes_written;
375  break;
376  } else {
377  coap_delete_node(q);
378  }
379  }
380  }
381 }
382 
384  (void)reason;
385  coap_session_state_t state = session->state;
386 
387  coap_log(LOG_DEBUG, "***%s: session disconnected (reason %d)\n",
388  coap_session_str(session), reason);
389 #ifndef WITHOUT_OBSERVE
390  coap_delete_observers( session->context, session );
391 #endif
392 
393  if ( session->tls) {
394  if (session->proto == COAP_PROTO_DTLS)
395  coap_dtls_free_session(session);
396  else if (session->proto == COAP_PROTO_TLS)
397  coap_tls_free_session(session);
398  session->tls = NULL;
399  }
400 
401  session->state = COAP_SESSION_STATE_NONE;
402 
403  if (session->partial_pdu) {
404  coap_delete_pdu(session->partial_pdu);
405  session->partial_pdu = NULL;
406  }
407  session->partial_read = 0;
408 
409  while (session->delayqueue) {
410  coap_queue_t *q = session->delayqueue;
411  session->delayqueue = q->next;
412  q->next = NULL;
413  coap_log(LOG_DEBUG, "** %s: tid=%d: not transmitted after delay\n",
414  coap_session_str(session), q->id);
415  if (q->pdu->type==COAP_MESSAGE_CON
416  && COAP_PROTO_NOT_RELIABLE(session->proto)
417  && reason != COAP_NACK_RST)
418  {
419  if (coap_wait_ack(session->context, session, q) >= 0)
420  q = NULL;
421  }
422  if (q && q->pdu->type == COAP_MESSAGE_CON
423  && session->context->nack_handler)
424  {
425  session->context->nack_handler(session->context, session, q->pdu,
426  reason, q->id);
427  }
428  if (q)
429  coap_delete_node(q);
430  }
431  if ( COAP_PROTO_RELIABLE(session->proto) ) {
432  if (session->sock.flags != COAP_SOCKET_EMPTY) {
433  coap_socket_close(&session->sock);
434  coap_handle_event(session->context,
437  }
438  if (state != COAP_SESSION_STATE_NONE) {
439  coap_handle_event(session->context,
442  }
443  }
444 }
445 
448  const coap_packet_t *packet, coap_tick_t now) {
449  coap_session_t *session = NULL;
450  unsigned int num_idle = 0;
451  unsigned int num_hs = 0;
452  coap_session_t *oldest = NULL;
453  coap_session_t *oldest_hs = NULL;
454 
455  endpoint->hello.ifindex = -1;
456 
457  LL_FOREACH(endpoint->sessions, session) {
458  if (session->ifindex == packet->ifindex &&
459  coap_address_equals(&session->local_addr, &packet->dst) &&
460  coap_address_equals(&session->remote_addr, &packet->src))
461  {
462  session->last_rx_tx = now;
463  return session;
464  }
465  if (session->ref == 0 && session->delayqueue == NULL &&
466  session->type == COAP_SESSION_TYPE_SERVER) {
467  ++num_idle;
468  if (oldest==NULL || session->last_rx_tx < oldest->last_rx_tx)
469  oldest = session;
470 
471  if (session->state == COAP_SESSION_STATE_HANDSHAKE) {
472  ++num_hs;
473  /* See if this is a partial SSL session set up
474  which needs to be cleared down to prevent DOS */
475  if ((session->last_rx_tx + COAP_PARTIAL_SESSION_TIMEOUT_TICKS) < now) {
476  if (oldest_hs == NULL ||
477  session->last_rx_tx < oldest_hs->last_rx_tx)
478  oldest_hs = session;
479  }
480  }
481  }
482  }
483 
484  if (endpoint->context->max_idle_sessions > 0 &&
485  num_idle >= endpoint->context->max_idle_sessions) {
486  coap_session_free(oldest);
487  }
488  else if (oldest_hs) {
489  coap_log(LOG_WARNING, "***%s: Incomplete session timed out\n",
490  coap_session_str(oldest_hs));
491  coap_session_free(oldest_hs);
492  }
493 
494  if (num_hs > (endpoint->context->max_handshake_sessions ?
495  endpoint->context->max_handshake_sessions :
497  /* Maxed out on number of session in SSL negotiation state */
499  "Oustanding sessions in COAP_SESSION_STATE_HANDSHAKE too "
500  "large. New request ignored\n");
501  return NULL;
502  }
503 
504  if (endpoint->proto == COAP_PROTO_DTLS) {
505  session = &endpoint->hello;
506  coap_address_copy(&session->local_addr, &packet->dst);
507  coap_address_copy(&session->remote_addr, &packet->src);
508  session->ifindex = packet->ifindex;
509  } else {
510  session = coap_make_session(endpoint->proto, COAP_SESSION_TYPE_SERVER,
511  NULL, &packet->dst, &packet->src, packet->ifindex, endpoint->context,
512  endpoint);
513  if (session) {
514  session->last_rx_tx = now;
515  if (endpoint->proto == COAP_PROTO_UDP)
517  LL_PREPEND(endpoint->sessions, session);
518  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
519  coap_session_str(session));
520  }
521  }
522 
523  return session;
524 }
525 
528  const coap_packet_t *packet, coap_tick_t now) {
530  COAP_SESSION_TYPE_SERVER, NULL, &packet->dst, &packet->src,
531  packet->ifindex, endpoint->context, endpoint);
532  if (session) {
533  session->last_rx_tx = now;
535  session->tls = coap_dtls_new_server_session(session);
536  if (session->tls) {
538  LL_PREPEND(endpoint->sessions, session);
539  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
540  coap_session_str(session));
541  } else {
542  coap_session_free(session);
543  session = NULL;
544  }
545  }
546  return session;
547 }
548 
549 static coap_session_t *
551  coap_context_t *ctx,
552  const coap_address_t *local_if,
553  const coap_address_t *server,
554  coap_proto_t proto
555 ) {
556  coap_session_t *session = NULL;
557 
558  assert(server);
559  assert(proto != COAP_PROTO_NONE);
560 
561  session = coap_make_session(proto, COAP_SESSION_TYPE_CLIENT, local_if,
562  local_if, server, 0, ctx, NULL);
563  if (!session)
564  goto error;
565 
566  coap_session_reference(session);
567 
568  if (proto == COAP_PROTO_UDP || proto == COAP_PROTO_DTLS) {
569  if (!coap_socket_connect_udp(&session->sock, &session->local_if, server,
571  &session->local_addr, &session->remote_addr)) {
572  goto error;
573  }
574  } else if (proto == COAP_PROTO_TCP || proto == COAP_PROTO_TLS) {
575  if (!coap_socket_connect_tcp1(&session->sock, &session->local_if, server,
577  &session->local_addr, &session->remote_addr)) {
578  goto error;
579  }
580  }
581 
583  if (local_if)
584  session->sock.flags |= COAP_SOCKET_BOUND;
585  LL_PREPEND(ctx->sessions, session);
586  return session;
587 
588 error:
589  coap_session_release(session);
590  return NULL;
591 }
592 
593 static coap_session_t *
595  if (session->proto == COAP_PROTO_UDP) {
597  } else if (session->proto == COAP_PROTO_DTLS) {
598  session->tls = coap_dtls_new_client_session(session);
599  if (session->tls) {
601  } else {
602  /* Need to free session object. As a new session may not yet
603  * have been referenced, we call coap_session_reference() first
604  * before trying to release the object.
605  */
606  coap_session_reference(session);
607  coap_session_release(session);
608  return NULL;
609  }
610  } else if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS) {
611  if (session->sock.flags & COAP_SOCKET_WANT_CONNECT) {
613  } else if (session->proto == COAP_PROTO_TLS) {
614  int connected = 0;
615  session->tls = coap_tls_new_client_session(session, &connected);
616  if (session->tls) {
618  if (connected)
619  coap_session_send_csm(session);
620  } else {
621  /* Need to free session object. As a new session may not yet
622  * have been referenced, we call coap_session_reference()
623  * first before trying to release the object.
624  */
625  coap_session_reference(session);
626  coap_session_release(session);
627  return NULL;
628  }
629  } else {
630  coap_session_send_csm(session);
631  }
632  }
633  coap_ticks(&session->last_rx_tx);
634  return session;
635 }
636 
637 static coap_session_t *
639  if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS)
641  if (session->proto == COAP_PROTO_TCP) {
642  coap_session_send_csm(session);
643  } else if (session->proto == COAP_PROTO_TLS) {
644  int connected = 0;
645  session->tls = coap_tls_new_server_session(session, &connected);
646  if (session->tls) {
648  if (connected) {
650  coap_session_send_csm(session);
651  }
652  } else {
653  /* Need to free session object. As a new session may not yet
654  * have been referenced, we call coap_session_reference() first
655  * before trying to release the object.
656  */
657  coap_session_reference(session);
658  coap_session_release(session);
659  session = NULL;
660  }
661  }
662  return session;
663 }
664 
666  struct coap_context_t *ctx,
667  const coap_address_t *local_if,
668  const coap_address_t *server,
669  coap_proto_t proto
670 ) {
671  coap_session_t *session = coap_session_create_client(ctx, local_if, server, proto);
672  if (session) {
673  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
674  coap_session_str(session));
675  session = coap_session_connect(session);
676  }
677  return session;
678 }
679 
681  struct coap_context_t *ctx,
682  const coap_address_t *local_if,
683  const coap_address_t *server,
684  coap_proto_t proto,
685  const char *identity,
686  const uint8_t *key,
687  unsigned key_len
688 ) {
689  coap_session_t *session = coap_session_create_client(ctx, local_if, server, proto);
690 
691  if (!session)
692  return NULL;
693 
694  if (identity && (strlen(identity) > 0)) {
695  size_t identity_len = strlen(identity);
696  session->psk_identity = (uint8_t*)coap_malloc(identity_len);
697  if (session->psk_identity) {
698  memcpy(session->psk_identity, identity, identity_len);
699  session->psk_identity_len = identity_len;
700  } else {
701  coap_log(LOG_WARNING, "Cannot store session PSK identity\n");
702  coap_session_release(session);
703  return NULL;
704  }
705  }
706  else if (coap_dtls_is_supported()) {
707  coap_log(LOG_WARNING, "PSK identity not defined\n");
708  coap_session_release(session);
709  return NULL;
710  }
711 
712  if (key && key_len > 0) {
713  session->psk_key = (uint8_t*)coap_malloc(key_len);
714  if (session->psk_key) {
715  memcpy(session->psk_key, key, key_len);
716  session->psk_key_len = key_len;
717  } else {
718  coap_log(LOG_WARNING, "Cannot store session PSK key\n");
719  coap_session_release(session);
720  return NULL;
721  }
722  }
723  else if (coap_dtls_is_supported()) {
724  coap_log(LOG_WARNING, "PSK key not defined\n");
725  coap_session_release(session);
726  return NULL;
727  }
728 
729  if (coap_dtls_is_supported()) {
731  coap_session_release(session);
732  return NULL;
733  }
734  }
735  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
736  coap_session_str(session));
737  return coap_session_connect(session);
738 }
739 
741  struct coap_context_t *ctx,
742  const coap_address_t *local_if,
743  const coap_address_t *server,
744  coap_proto_t proto,
745  coap_dtls_pki_t* setup_data
746 ) {
747  coap_session_t *session;
748 
749  if (coap_dtls_is_supported()) {
750  if (!setup_data) {
751  return NULL;
752  } else {
753  if (setup_data->version != COAP_DTLS_PKI_SETUP_VERSION) {
755  "coap_new_client_session_pki: Wrong version of setup_data\n");
756  return NULL;
757  }
758  }
759 
760  }
761  session = coap_session_create_client(ctx, local_if, server, proto);
762 
763  if (!session) {
764  return NULL;
765  }
766 
767  if (coap_dtls_is_supported()) {
768  /* we know that setup_data is not NULL */
769  if (!coap_dtls_context_set_pki(ctx, setup_data, COAP_DTLS_ROLE_CLIENT)) {
770  coap_session_release(session);
771  return NULL;
772  }
773  }
774  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
775  coap_session_str(session));
776  return coap_session_connect(session);
777 }
778 
779 
781  struct coap_context_t *ctx,
782  coap_endpoint_t *ep
783 ) {
784  coap_session_t *session;
786  &ep->bind_addr, NULL, NULL, 0, ctx, ep );
787  if (!session)
788  goto error;
789 
790  if (!coap_socket_accept_tcp(&ep->sock, &session->sock,
791  &session->local_addr, &session->remote_addr))
792  goto error;
795  LL_PREPEND(ep->sessions, session);
796  if (session) {
797  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
798  coap_session_str(session));
799  session = coap_session_accept(session);
800  }
801  return session;
802 
803 error:
804  coap_session_free(session);
805  return NULL;
806 }
807 
808 #ifndef WITH_LWIP
810 coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto) {
811  struct coap_endpoint_t *ep = NULL;
812 
813  assert(context);
814  assert(listen_addr);
815  assert(proto != COAP_PROTO_NONE);
816 
817  if (proto == COAP_PROTO_DTLS && !coap_dtls_is_supported()) {
818  coap_log(LOG_CRIT, "coap_new_endpoint: DTLS not supported\n");
819  goto error;
820  }
821 
822  if (proto == COAP_PROTO_TLS && !coap_tls_is_supported()) {
823  coap_log(LOG_CRIT, "coap_new_endpoint: TLS not supported\n");
824  goto error;
825  }
826 
827  if (proto == COAP_PROTO_DTLS || proto == COAP_PROTO_TLS) {
828  if (!coap_dtls_context_check_keys_enabled(context)) {
830  "coap_new_endpoint: one of coap_context_set_psk() or "
831  "coap_context_set_pki() not called\n");
832  goto error;
833  }
834  }
835 
836  ep = coap_malloc_endpoint();
837  if (!ep) {
838  coap_log(LOG_WARNING, "coap_new_endpoint: malloc");
839  goto error;
840  }
841 
842  memset(ep, 0, sizeof(struct coap_endpoint_t));
843  ep->context = context;
844  ep->proto = proto;
845 
846  if (proto==COAP_PROTO_TCP || proto==COAP_PROTO_TLS) {
847  if (!coap_socket_bind_tcp(&ep->sock, listen_addr, &ep->bind_addr))
848  goto error;
850  } else if (proto==COAP_PROTO_UDP || proto==COAP_PROTO_DTLS) {
851  if (!coap_socket_bind_udp(&ep->sock, listen_addr, &ep->bind_addr))
852  goto error;
854  } else {
855  coap_log(LOG_CRIT, "coap_new_endpoint: protocol not supported\n");
856  goto error;
857  }
858 
859 #ifndef NDEBUG
860  if (LOG_DEBUG <= coap_get_log_level()) {
861 #ifndef INET6_ADDRSTRLEN
862 #define INET6_ADDRSTRLEN 40
863 #endif
864  unsigned char addr_str[INET6_ADDRSTRLEN + 8];
865 
866  if (coap_print_addr(&ep->bind_addr, addr_str, INET6_ADDRSTRLEN + 8)) {
867  coap_log(LOG_DEBUG, "created %s endpoint %s\n",
868  ep->proto == COAP_PROTO_TLS ? "TLS "
869  : ep->proto == COAP_PROTO_TCP ? "TCP "
870  : ep->proto == COAP_PROTO_DTLS ? "DTLS" : "UDP ",
871  addr_str);
872  }
873  }
874 #endif /* NDEBUG */
875 
877 
878  if (proto == COAP_PROTO_DTLS) {
879  ep->hello.proto = proto;
881  ep->hello.mtu = ep->default_mtu;
882  ep->hello.context = context;
883  ep->hello.endpoint = ep;
884  }
885 
887 
888  LL_PREPEND(context->endpoint, ep);
889  return ep;
890 
891 error:
892  coap_free_endpoint(ep);
893  return NULL;
894 }
895 
897  ep->default_mtu = (uint16_t)mtu;
898 }
899 
900 void
902  if (ep) {
903  coap_session_t *session, *tmp;
904 
905  if (ep->sock.flags != COAP_SOCKET_EMPTY)
906  coap_socket_close(&ep->sock);
907 
908  LL_FOREACH_SAFE(ep->sessions, session, tmp) {
909  assert(session->ref == 0);
910  if (session->ref == 0) {
911  session->endpoint = NULL;
912  session->context = NULL;
913  coap_session_free(session);
914  }
915  }
916 
918  }
919 }
920 #endif /* WITH_LWIP */
921 
924  const coap_address_t *remote_addr,
925  int ifindex) {
926  coap_session_t *s;
927  coap_endpoint_t *ep;
928  LL_FOREACH(ctx->sessions, s) {
929  if (s->ifindex == ifindex && coap_address_equals(&s->remote_addr, remote_addr))
930  return s;
931  }
932  LL_FOREACH(ctx->endpoint, ep) {
933  if (ep->hello.ifindex == ifindex && coap_address_equals(&ep->hello.remote_addr, remote_addr))
934  return &ep->hello;
935  LL_FOREACH(ep->sessions, s) {
936  if (s->ifindex == ifindex && coap_address_equals(&s->remote_addr, remote_addr))
937  return s;
938  }
939  }
940  return NULL;
941 }
942 
943 const char *coap_session_str(const coap_session_t *session) {
944  static char szSession[256];
945  char *p = szSession, *end = szSession + sizeof(szSession);
946  if (coap_print_addr(&session->local_addr, (unsigned char*)p, end - p) > 0)
947  p += strlen(p);
948  if (p + 6 < end) {
949  strcpy(p, " <-> ");
950  p += 5;
951  }
952  if (p + 1 < end) {
953  if (coap_print_addr(&session->remote_addr, (unsigned char*)p, end - p) > 0)
954  p += strlen(p);
955  }
956  if (session->ifindex > 0 && p + 1 < end)
957  p += snprintf(p, end - p, " (if%d)", session->ifindex);
958  if (p + 6 < end) {
959  if (session->proto == COAP_PROTO_UDP) {
960  strcpy(p, " UDP ");
961  p += 4;
962  } else if (session->proto == COAP_PROTO_DTLS) {
963  strcpy(p, " DTLS");
964  p += 5;
965  } else if (session->proto == COAP_PROTO_TCP) {
966  strcpy(p, " TCP ");
967  p += 4;
968  } else if (session->proto == COAP_PROTO_TLS) {
969  strcpy(p, " TLS ");
970  p += 4;
971  } else {
972  strcpy(p, " NONE");
973  p += 5;
974  }
975  }
976 
977  return szSession;
978 }
979 
980 const char *coap_endpoint_str(const coap_endpoint_t *endpoint) {
981  static char szEndpoint[128];
982  char *p = szEndpoint, *end = szEndpoint + sizeof(szEndpoint);
983  if (coap_print_addr(&endpoint->bind_addr, (unsigned char*)p, end - p) > 0)
984  p += strlen(p);
985  if (p + 6 < end) {
986  if (endpoint->proto == COAP_PROTO_UDP) {
987  strcpy(p, " UDP");
988  p += 4;
989  } else if (endpoint->proto == COAP_PROTO_DTLS) {
990  strcpy(p, " DTLS");
991  p += 5;
992  } else {
993  strcpy(p, " NONE");
994  p += 5;
995  }
996  }
997 
998  return szEndpoint;
999 }
1000 
1001 #endif /* COAP_SESSION_C_ */
uint8_t type
message type
Definition: pdu.h:288
unsigned mtu
path or CSM mtu
Definition: coap_session.h:63
void coap_session_send_csm(coap_session_t *session)
Notify session transport has just connected and CSM exchange can now start.
Definition: coap_session.c:290
#define LL_FOREACH(head, el)
Definition: utlist.h:413
coap_queue_t * sendqueue
Definition: net.h:165
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
Definition: coap_io.h:54
uint8_t * psk_identity
Definition: coap_session.h:84
#define COAP_DEFAULT_MTU
Definition: pdu.h:32
coap_session_t * coap_new_client_session(struct coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto)
Creates a new client session to the designated server.
Definition: coap_session.c:665
coap_tick_t last_rx_tx
Definition: coap_session.h:79
uint8_t con_active
Active CON request sent.
Definition: coap_session.h:73
void * app
application-specific data
Definition: coap_session.h:88
void coap_session_set_ack_timeout(coap_session_t *session, coap_fixed_point_t value)
Set the CoAP initial ack response timeout before the next re-transmit.
Definition: coap_session.c:35
#define COAP_SIGNALING_PING
Definition: pdu.h:181
uint8_t coap_proto_t
Definition: pdu.h:339
Abstraction of a fixed point number that can be used where necessary instead of a float...
Definition: coap_session.h:25
#define COAP_SESSION_TYPE_CLIENT
coap_session_type_t values
Definition: coap_session.h:42
coap_tid_t coap_wait_ack(coap_context_t *context, coap_session_t *session, coap_queue_t *node)
Definition: net.c:824
#define COAP_SIGNALING_CSM
Definition: pdu.h:180
void coap_socket_close(coap_socket_t *sock)
Definition: coap_io.c:626
#define COAP_DTLS_PKI_SETUP_VERSION
Latest PKI setup version.
Definition: coap_dtls.h:186
void coap_tls_free_session(coap_session_t *coap_session UNUSED)
Definition: coap_notls.c:159
unsigned int coap_session_get_max_transmit(coap_session_t *session)
Get the CoAP maximum retransmit before failure.
Definition: coap_session.c:56
coap_fixed_point_t coap_session_get_ack_timeout(coap_session_t *session)
Get the CoAP initial ack response timeout before the next re-transmit.
Definition: coap_session.c:61
struct coap_context_t * context
session&#39;s context
Definition: coap_session.h:70
coap_session_t * coap_new_server_session(struct coap_context_t *ctx, coap_endpoint_t *ep)
Creates a new server session for the specified endpoint.
Definition: coap_session.c:780
coap_fixed_point_t ack_timeout
timeout waiting for ack (default 2 secs)
Definition: coap_session.h:90
void * tls
security parameters
Definition: coap_session.h:71
#define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS
Definition: coap_session.h:33
coap_session_t * sessions
list of active sessions
Definition: coap_session.h:308
void * coap_session_get_app_data(const coap_session_t *session)
Returns any application-specific data that has been stored with session using the function coap_sessi...
Definition: coap_session.c:94
coap_endpoint_t * endpoint
the endpoints used for listening
Definition: net.h:166
#define COAP_SESSION_STATE_HANDSHAKE
Definition: coap_session.h:52
#define COAP_SOCKET_CONNECTED
the socket is connected
Definition: coap_io.h:57
#define COAP_SOCKET_BOUND
the socket is bound
Definition: coap_io.h:56
multi-purpose address abstraction
Definition: address.h:62
uint16_t tx_mid
the last message id that was used in this session
Definition: coap_session.h:72
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED)
Definition: coap_notls.c:65
ssize_t coap_socket_send(coap_socket_t *sock, coap_session_t *session, const uint8_t *data, size_t data_len)
Definition: coap_io.c:1396
unsigned ref
reference count from queues
Definition: coap_session.h:61
int coap_tid_t
coap_tid_t is used to store CoAP transaction id, i.e.
Definition: pdu.h:238
#define LL_PREPEND(head, add)
Definition: utlist.h:314
void coap_session_set_mtu(coap_session_t *session, unsigned mtu)
Set the session MTU.
Definition: coap_session.c:206
coap_tid_t coap_session_send_ping(coap_session_t *session)
Send a ping message for the session.
Definition: coap_session.c:316
unsigned tls_overhead
overhead of TLS layer
Definition: coap_session.h:62
uint8_t version
Definition: coap_dtls.h:192
#define COAP_MAX_MESSAGE_SIZE_TCP8
Definition: pdu.h:42
unsigned int coap_encode_var_safe(uint8_t *buf, size_t length, unsigned int val)
Encodes multiple-length byte sequences.
Definition: encode.c:45
int ifindex
the interface index
Definition: coap_io.h:199
#define COAP_PROTO_DTLS
Definition: pdu.h:345
int coap_socket_accept_tcp(coap_socket_t *server, coap_socket_t *new_client, coap_address_t *local_addr, coap_address_t *remote_addr)
Definition: coap_io.c:490
void * coap_dtls_new_client_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:98
coap_endpoint_t * coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto)
Create a new endpoint for communicating with peers.
Definition: coap_session.c:810
size_t coap_print_addr(const struct coap_address_t *addr, unsigned char *buf, size_t len)
Print the address into the defined buffer.
Definition: coap_debug.c:171
coap_tid_t coap_send(coap_session_t *session, coap_pdu_t *pdu)
Sends a CoAP message to given peer.
Definition: net.c:876
COAP_STATIC_INLINE void coap_address_init(coap_address_t *addr)
Resets the given coap_address_t object addr to its default values.
Definition: address.h:104
uint16_t default_mtu
default mtu for this interface
Definition: coap_session.h:305
void coap_delete_observers(coap_context_t *context, coap_session_t *session)
Removes any subscription for session and releases the allocated storage.
Definition: resource.c:729
int coap_socket_connect_tcp1(coap_socket_t *sock, const coap_address_t *local_if, const coap_address_t *server, int default_port, coap_address_t *local_addr, coap_address_t *remote_addr)
Definition: coap_io.c:268
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition: coap_dtls.c:891
int coap_dtls_context_set_pki(coap_context_t *ctx UNUSED, coap_dtls_pki_t *setup_data UNUSED, coap_dtls_role_t role UNUSED)
Definition: coap_notls.c:41
void * coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:155
coap_session_t * coap_new_client_session_pki(struct coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_pki_t *setup_data)
Creates a new client session to the designated server with PKI credentials.
Definition: coap_session.c:740
coap_address_t local_if
optional local interface address
Definition: coap_session.h:64
size_t coap_session_max_pdu_size(const coap_session_t *session)
Get maximum acceptable PDU size.
Definition: coap_session.c:189
#define COAP_EVENT_TCP_CONNECTED
TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS.
Definition: coap_event.h:41
ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for datagram data transmission.
Definition: coap_session.c:218
int dtls_event
Tracking any (D)TLS events on this sesison.
Definition: coap_session.h:93
coap_session_t * coap_session_get_by_peer(coap_context_t *ctx, const coap_address_t *remote_addr, int ifindex)
Definition: coap_session.c:923
#define COAP_PDU_DELAYED
Definition: pdu.h:249
void coap_session_set_ack_random_factor(coap_session_t *session, coap_fixed_point_t value)
Set the CoAP ack randomize factor.
Definition: coap_session.c:45
Debug.
Definition: coap_debug.h:49
void coap_endpoint_set_default_mtu(coap_endpoint_t *ep, unsigned mtu)
Set the endpoint&#39;s default MTU.
Definition: coap_session.c:896
coap_nack_handler_t nack_handler
Definition: net.h:189
#define COAP_SOCKET_WANT_ACCEPT
non blocking server socket is waiting for accept
Definition: coap_io.h:60
#define COAP_MAX_MESSAGE_SIZE_TCP16
Definition: pdu.h:43
#define COAP_EVENT_TCP_FAILED
Definition: coap_event.h:43
coap_nack_reason_t
Definition: coap_io.h:206
#define COAP_EVENT_SESSION_FAILED
Definition: coap_event.h:50
struct coap_context_t * context
endpoint&#39;s context
Definition: coap_session.h:303
coap_session_t * coap_session_reference(coap_session_t *session)
Increment reference counter on a session.
Definition: coap_session.c:71
const char * coap_endpoint_str(const coap_endpoint_t *endpoint)
Get endpoint description.
Definition: coap_session.c:980
void coap_dtls_free_session(coap_dtls_session_t *session UNUSED)
Definition: coap_dtls.c:925
void * coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:151
Abstraction of virtual endpoint that can be attached to coap_context_t.
Definition: coap_session.h:301
const char * coap_session_str(const coap_session_t *session)
Get session description.
Definition: coap_session.c:943
coap_address_t local_addr
local address and port
Definition: coap_session.h:66
#define COAP_SESSION_STATE_ESTABLISHED
Definition: coap_session.h:54
coap_tid_t id
CoAP transaction id.
Definition: net.h:46
unsigned int max_retransmit
maximum re-transmit count (default 4)
Definition: coap_session.h:89
#define COAP_DEFAULT_ACK_RANDOM_FACTOR
A factor that is used to randomize the wait time before a message is retransmitted to prevent synchro...
Definition: coap_session.h:395
uint16_t fractional_part
Fractional part of fixed point variable 1/1000 (3 points) precision.
Definition: coap_session.h:27
#define COAP_EVENT_SESSION_CONNECTED
CSM exchange events for reliable protocols only.
Definition: coap_event.h:48
#define COAP_PROTO_UDP
Definition: pdu.h:344
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
Definition: mem.h:75
struct coap_endpoint_t * coap_malloc_endpoint(void)
Definition: coap_io.c:181
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition: coap_notls.c:28
coap_pdu_t * pdu
the CoAP PDU to send
Definition: net.h:47
coap_tick_t t
when to send PDU for the next time
Definition: net.h:41
void coap_session_mfree(coap_session_t *session)
Definition: coap_session.c:147
size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto)
Compose the protocol specific header for the specified PDU.
Definition: pdu.c:582
#define COAP_PARTIAL_SESSION_TIMEOUT_TICKS
Definition: coap_session.h:32
#define COAP_INVALID_TID
Indicates an invalid transaction id.
Definition: pdu.h:241
coap_session_t * coap_endpoint_get_session(coap_endpoint_t *endpoint, const coap_packet_t *packet, coap_tick_t now)
Definition: coap_session.c:447
coap_address_t remote_addr
remote address and port
Definition: coap_session.h:65
void coap_session_set_max_retransmit(coap_session_t *session, unsigned int value)
Set the CoAP maximum retransmit count before failure.
Definition: coap_session.c:26
coap_address_t src
the packet&#39;s source address
Definition: coap_io.h:197
void coap_session_set_app_data(coap_session_t *session, void *app_data)
Stores data with the given session.
Definition: coap_session.c:88
unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r)
Calculates the initial timeout based on the session CoAP transmission parameters &#39;ack_timeout&#39;, &#39;ack_random_factor&#39;, and COAP_TICKS_PER_SECOND.
Definition: net.c:798
structure for CoAP PDUs token, if any, follows the fixed size header, then options until payload mark...
Definition: pdu.h:287
coap_session_t * coap_endpoint_new_dtls_session(coap_endpoint_t *endpoint, const coap_packet_t *packet, coap_tick_t now)
Definition: coap_session.c:527
#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE
Definition: pdu.h:187
struct coap_queue_t * delayqueue
list of delayed messages waiting to be sent
Definition: coap_session.h:74
coap_proto_t proto
protocol used
Definition: coap_session.h:58
Warning.
Definition: coap_debug.h:46
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition: coap_time.h:85
static coap_session_t * coap_session_accept(coap_session_t *session)
Definition: coap_session.c:638
#define assert(...)
Definition: mem.c:18
void coap_free_endpoint(coap_endpoint_t *ep)
Definition: coap_session.c:901
#define COAP_SOCKET_NOT_EMPTY
the socket is not empty
Definition: coap_io.h:55
coap_session_t hello
special session of DTLS hello messages
Definition: coap_session.h:309
unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED)
Definition: coap_notls.c:147
size_t partial_read
if > 0 indicates number of bytes already read for an incoming message
Definition: coap_session.h:77
coap_pdu_t * partial_pdu
incomplete incoming pdu
Definition: coap_session.h:78
ssize_t coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node)
Definition: coap_session.c:253
size_t used_size
used bytes of storage for token, options and payload
Definition: pdu.h:296
void coap_session_free(coap_session_t *session)
Definition: coap_session.c:170
struct coap_queue_t * next
Definition: net.h:40
coap_socket_t sock
socket object for the session, if any
Definition: coap_session.h:68
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Definition: coap_io.c:635
void coap_ticks(coap_tick_t *t)
Sets t to the internal time with COAP_TICKS_PER_SECOND resolution.
#define COAPS_DEFAULT_PORT
Definition: pdu.h:29
#define INET6_ADDRSTRLEN
int coap_dtls_context_set_psk(coap_context_t *ctx UNUSED, const char *hint UNUSED, coap_dtls_role_t role UNUSED)
Definition: coap_notls.c:57
coap_proto_t proto
protocol used on this interface
Definition: coap_session.h:304
#define COAP_MESSAGE_CON
Definition: pdu.h:72
unsigned int timeout
the randomized timeout value
Definition: net.h:44
#define COAP_PROTO_TLS
Definition: pdu.h:347
#define LL_APPEND(head, add)
Definition: utlist.h:338
static coap_session_t * coap_session_connect(coap_session_t *session)
Definition: coap_session.c:594
Generic resource handling.
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:82
Error.
Definition: coap_debug.h:45
coap_session_type_t type
client or server side socket
Definition: coap_session.h:59
#define COAP_DEFAULT_NSTART
The number of simultaneous outstanding interactions that a client maintains to a given server...
Definition: coap_session.h:408
#define COAP_EVENT_TCP_CLOSED
Definition: coap_event.h:42
coap_session_state_t state
current state of relationaship with peer
Definition: coap_session.h:60
Internal function invoked for client.
Definition: coap_dtls.h:265
size_t psk_identity_len
Definition: coap_session.h:85
#define COAP_SESSION_TYPE_SERVER
server-side
Definition: coap_session.h:43
size_t coap_add_option(coap_pdu_t *pdu, uint16_t type, size_t len, const uint8_t *data)
Adds option of given type to pdu that is passed as first parameter.
Definition: pdu.c:229
void coap_session_release(coap_session_t *session)
Decrement reference counter on a session.
Definition: coap_session.c:77
#define COAP_SESSION_TYPE_HELLO
server-side ephemeral session for responding to a client hello
Definition: coap_session.h:44
coap_fixed_point_t ack_random_factor
ack random factor backoff (default 1.5)
Definition: coap_session.h:91
int coap_remove_from_queue(coap_queue_t **queue, coap_session_t *session, coap_tid_t id, coap_queue_t **node)
This function removes the element with given id from the list given list.
Definition: net.c:1397
int ifindex
interface index
Definition: coap_session.h:67
#define COAP_DEFAULT_PORT
Definition: pdu.h:28
size_t partial_write
if > 0 indicates number of bytes already written from the pdu at the head of sendqueue ...
Definition: coap_session.h:75
#define COAP_EVENT_DTLS_CONNECTED
Definition: coap_event.h:34
int coap_address_equals(const coap_address_t *a, const coap_address_t *b)
Compares given address objects a and b.
Definition: address.c:36
int coap_handle_event(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
Definition: net.c:2310
void coap_delete_pdu(coap_pdu_t *pdu)
Dispose of an CoAP PDU and frees associated storage.
Definition: pdu.c:141
ssize_t coap_session_write(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for stream data transmission.
Definition: coap_session.c:239
coap_address_t dst
the packet&#39;s destination address
Definition: coap_io.h:198
COAP_STATIC_INLINE void coap_address_copy(coap_address_t *dst, const coap_address_t *src)
Definition: address.h:116
void * coap_dtls_new_server_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:94
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
Definition: coap_session.c:326
#define COAP_DEFAULT_ACK_TIMEOUT
Number of seconds when to expect an ACK or a response to an outstanding CON message.
Definition: coap_session.h:388
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
Definition: coap_io.h:58
#define LL_FOREACH_SAFE(head, el, tmp)
Definition: utlist.h:419
#define COAP_PROTO_RELIABLE(p)
Definition: coap_session.h:36
#define COAP_SESSION_STATE_CONNECTING
Definition: coap_session.h:51
#define COAP_MAX_MESSAGE_SIZE_TCP0
Definition: pdu.h:41
The structure used for defining the PKI setup data to be used.
Definition: coap_dtls.h:191
static coap_session_t * coap_session_create_client(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto)
Definition: coap_session.c:550
uint8_t coap_session_type_t
Definition: coap_session.h:38
#define COAP_SOCKET_WANT_CONNECT
non blocking client socket is waiting for connect
Definition: coap_io.h:61
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
#define LL_DELETE(head, del)
Definition: utlist.h:385
#define COAP_PROTO_NOT_RELIABLE(p)
Definition: coap_session.h:35
coap_log_t coap_get_log_level(void)
Get the current logging level.
Definition: coap_debug.c:71
unsigned int max_handshake_sessions
Maximum number of simultaneous negotating sessions per endpoint.
Definition: net.h:215
#define COAP_DEFAULT_MAX_PDU_RX_SIZE
Definition: pdu.h:51
uint8_t hdr_size
actaul size used for protocol-specific header
Definition: pdu.h:291
size_t psk_key_len
Definition: coap_session.h:87
coap_socket_flags_t flags
Definition: coap_io.h:48
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
Definition: coap_session.c:383
coap_session_t * sessions
client sessions
Definition: net.h:167
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:122
static coap_session_t * coap_make_session(coap_proto_t proto, coap_session_type_t type, const coap_address_t *local_if, const coap_address_t *local_addr, const coap_address_t *remote_addr, int ifindex, coap_context_t *context, coap_endpoint_t *endpoint)
Definition: coap_session.c:100
coap_socket_t sock
socket object for the interface, if any
Definition: coap_session.h:306
ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu)
Send a pdu according to the session&#39;s protocol.
Definition: net.c:627
coap_pdu_t * coap_pdu_init(uint8_t type, uint8_t code, uint16_t tid, size_t size)
Creates a new CoAP PDU with at least enough storage space for the given size maximum message size...
Definition: pdu.c:91
int coap_socket_connect_udp(coap_socket_t *sock, const coap_address_t *local_if, const coap_address_t *server, int default_port, coap_address_t *local_addr, coap_address_t *remote_addr)
Definition: coap_io.c:527
coap_session_t * session
the CoAP session
Definition: net.h:45
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
#define COAP_PROTO_NONE
coap_proto_t values
Definition: pdu.h:343
#define COAP_EVENT_SESSION_CLOSED
Definition: coap_event.h:49
coap_session_t * coap_new_client_session_psk(struct coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, const char *identity, const uint8_t *key, unsigned key_len)
Creates a new client session to the designated server with PSK credentials.
Definition: coap_session.c:680
unsigned char uint8_t
Definition: uthash.h:79
struct coap_endpoint_t * endpoint
session&#39;s endpoint
Definition: coap_session.h:69
#define prng(Buf, Length)
Fills Buf with Length bytes of random data.
Definition: prng.h:112
coap_fixed_point_t coap_session_get_ack_random_factor(coap_session_t *session)
Get the CoAP ack randomize factor.
Definition: coap_session.c:66
Critical.
Definition: coap_debug.h:44
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Definition: coap_io.c:192
#define COAP_SESSION_STATE_NONE
coap_session_state_t values
Definition: coap_session.h:50
Information.
Definition: coap_debug.h:48
int coap_socket_bind_tcp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Definition: coap_io.c:413
uint16_t integer_part
Integer part of fixed point variable.
Definition: coap_session.h:26
void coap_mfree_endpoint(struct coap_endpoint_t *ep)
Definition: coap_io.c:186
Queue entry.
Definition: net.h:39
uint8_t coap_session_state_t
Definition: coap_session.h:46
coap_queue_t * coap_new_node(void)
Creates a new node suitable for adding to the CoAP sendqueue.
Definition: net.c:254
coap_address_t bind_addr
local interface address
Definition: coap_session.h:307
#define COAP_PROTO_TCP
Definition: pdu.h:346
uint8_t * psk_key
Definition: coap_session.h:86
The CoAP stack&#39;s global state is stored in a coap_context_t object.
Definition: net.h:148
uint16_t tid
transaction id, if any, in regular host byte order
Definition: pdu.h:293
unsigned int max_idle_sessions
Maximum number of simultaneous unused sessions per endpoint.
Definition: net.h:214
#define COAP_DEFAULT_MAX_RETRANSMIT
Number of message retransmissions before message sending is stopped RFC 7252, Section 4...
Definition: coap_session.h:401
int coap_delete_node(coap_queue_t *node)
Destroys specified node.
Definition: net.c:225
#define COAP_SESSION_STATE_CSM
Definition: coap_session.h:53