libcoap  4.3.0rc3
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 #include "coap3/coap_internal.h"
10 
11 #ifndef COAP_SESSION_C_
12 #define COAP_SESSION_C_
13 
14 #include <stdio.h>
15 
16 #ifdef COAP_EPOLL_SUPPORT
17 #include <sys/epoll.h>
18 #include <sys/timerfd.h>
19 #endif /* COAP_EPOLL_SUPPORT */
20 #include <errno.h>
21 
22 void
23 coap_session_set_max_retransmit (coap_session_t *session, unsigned int value) {
24  if (value > 0)
25  session->max_retransmit = value;
26  coap_log(LOG_DEBUG, "***%s: session max_retransmit set to %d\n",
27  coap_session_str(session), session->max_retransmit);
28  return;
29 }
30 
31 void
33  if (value.integer_part > 0 && value.fractional_part < 1000)
34  session->ack_timeout = value;
35  coap_log(LOG_DEBUG, "***%s: session ack_timeout set to %d.%03d\n",
36  coap_session_str(session), session->ack_timeout.integer_part,
37  session->ack_timeout.fractional_part);
38  return;
39 }
40 
41 void
43  coap_fixed_point_t value) {
44  if (value.integer_part > 0 && value.fractional_part < 1000)
45  session->ack_random_factor = value;
46  coap_log(LOG_DEBUG, "***%s: session ack_random_factor set to %d.%03d\n",
49  return;
50 }
51 
52 unsigned int
54  return session->max_retransmit;
55 }
56 
59  return session->ack_timeout;
60 }
61 
64  return session->ack_random_factor;
65 }
66 
69  ++session->ref;
70  return session;
71 }
72 
73 void
75  if (session) {
76 #ifndef __COVERITY__
77  assert(session->ref > 0);
78  if (session->ref > 0)
79  --session->ref;
80  if (session->ref == 0 && session->type == COAP_SESSION_TYPE_CLIENT)
81  coap_session_free(session);
82 #else /* __COVERITY__ */
83  /* Coverity scan is fooled by the reference counter leading to
84  * false positives for USE_AFTER_FREE. */
85  --session->ref;
86  __coverity_negative_sink__(session->ref);
87  /* Indicate that resources are released properly. */
88  if (session->ref == 0 && session->type == COAP_SESSION_TYPE_CLIENT) {
89  __coverity_free__(session);
90  }
91 #endif /* __COVERITY__ */
92  }
93 }
94 
95 void
96 coap_session_set_app_data(coap_session_t *session, void *app_data) {
97  assert(session);
98  session->app = app_data;
99 }
100 
101 void *
103  assert(session);
104  return session->app;
105 }
106 
107 static coap_session_t *
109  const coap_addr_hash_t *addr_hash, const coap_address_t *local_addr,
110  const coap_address_t *remote_addr, int ifindex, coap_context_t *context,
111  coap_endpoint_t *endpoint) {
113  if (!session)
114  return NULL;
115  memset(session, 0, sizeof(*session));
116  session->proto = proto;
117  session->type = type;
118  if (addr_hash)
119  memcpy(&session->addr_hash, addr_hash, sizeof(session->addr_hash));
120  else
121  memset(&session->addr_hash, 0, sizeof(session->addr_hash));
122  if (local_addr)
123  coap_address_copy(&session->addr_info.local, local_addr);
124  else
125  coap_address_init(&session->addr_info.local);
126  if (remote_addr)
127  coap_address_copy(&session->addr_info.remote, remote_addr);
128  else
130  session->ifindex = ifindex;
131  session->context = context;
132  session->endpoint = endpoint;
133  session->block_mode = context->block_mode;
134  if (endpoint)
135  session->mtu = endpoint->default_mtu;
136  else
137  session->mtu = COAP_DEFAULT_MTU;
138  if (proto == COAP_PROTO_DTLS) {
139  session->tls_overhead = 29;
140  if (session->tls_overhead >= session->mtu) {
141  session->tls_overhead = session->mtu;
142  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
143  }
144  }
148  session->dtls_event = -1;
149  session->last_ping_mid = COAP_INVALID_MID;
150 
151  /* initialize message id */
152  coap_prng((unsigned char *)&session->tx_mid, sizeof(session->tx_mid));
153 
154  return session;
155 }
156 
158  coap_queue_t *q, *tmp;
159  coap_cache_entry_t *cp, *ctmp;
160  coap_lg_xmit_t *lq, *ltmp;
161  coap_lg_crcv_t *cq, *etmp;
162  coap_lg_srcv_t *sq, *stmp;
163 
164  /* Need to do this before (D)TLS and socket is closed down */
165  LL_FOREACH_SAFE(session->lg_crcv, cq, etmp) {
166  if (cq->observe_set) {
167  /* Need to close down observe */
168  if (coap_cancel_observe(session, cq->app_token, COAP_MESSAGE_NON)) {
169  /* Need to delete node we set up for NON */
170  coap_queue_t *queue = session->context->sendqueue;
171 
172  while (queue) {
173  if (queue->session == session) {
174  coap_delete_node(queue);
175  break;
176  }
177  queue = queue->next;
178  }
179  }
180  }
181  LL_DELETE(session->lg_crcv, cq);
182  coap_block_delete_lg_crcv(session, cq);
183  }
184 
185  if (session->partial_pdu)
186  coap_delete_pdu(session->partial_pdu);
187  if (session->proto == COAP_PROTO_DTLS)
188  coap_dtls_free_session(session);
189 #if !COAP_DISABLE_TCP
190  else if (session->proto == COAP_PROTO_TLS)
191  coap_tls_free_session(session);
192 #endif /* !COAP_DISABLE_TCP */
193  if (session->sock.flags != COAP_SOCKET_EMPTY)
194  coap_socket_close(&session->sock);
195  if (session->psk_identity)
196  coap_free(session->psk_identity);
197  if (session->psk_key)
198  coap_free(session->psk_key);
199  if (session->psk_hint)
200  coap_free(session->psk_hint);
201 
202  HASH_ITER(hh, session->context->cache, cp, ctmp) {
203  /* cp->session is NULL if not session based */
204  if (cp->session == session) {
205  coap_delete_cache_entry(session->context, cp);
206  }
207  }
208  LL_FOREACH_SAFE(session->delayqueue, q, tmp) {
209  if (q->pdu->type==COAP_MESSAGE_CON && session->context && session->context->nack_handler)
211  coap_delete_node(q);
212  }
213  LL_FOREACH_SAFE(session->lg_xmit, lq, ltmp) {
214  LL_DELETE(session->lg_xmit, lq);
215  coap_block_delete_lg_xmit(session, lq);
216  }
217  LL_FOREACH_SAFE(session->lg_srcv, sq, stmp) {
218  LL_DELETE(session->lg_srcv, sq);
219  coap_block_delete_lg_srcv(session, sq);
220  }
221 }
222 
224  if (!session)
225  return;
226  assert(session->ref == 0);
227  if (session->ref)
228  return;
229  coap_session_mfree(session);
230  if (session->endpoint) {
231  if (session->endpoint->sessions)
232  SESSIONS_DELETE(session->endpoint->sessions, session);
233  } else if (session->context) {
234  if (session->context->sessions)
235  SESSIONS_DELETE(session->context->sessions, session);
236  }
237  coap_log(LOG_DEBUG, "***%s: session closed\n", coap_session_str(session));
238 
239  coap_free_type(COAP_SESSION, session);
240 }
241 
243  size_t max_with_header = (size_t)(session->mtu - session->tls_overhead);
244 #if COAP_DISABLE_TCP
245  return max_with_header > 4 ? max_with_header - 4 : 0;
246 #else /* !COAP_DISABLE_TCP */
247  if (COAP_PROTO_NOT_RELIABLE(session->proto))
248  return max_with_header > 4 ? max_with_header - 4 : 0;
249  /* we must assume there is no token to be on the safe side */
250  if (max_with_header <= 2)
251  return 0;
252  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP0 + 2)
253  return max_with_header - 2;
254  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP8 + 3)
255  return max_with_header - 3;
256  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP16 + 4)
257  return max_with_header - 4;
258  else
259  return max_with_header - 6;
260 #endif /* !COAP_DISABLE_TCP */
261 }
262 
263 void coap_session_set_mtu(coap_session_t *session, unsigned mtu) {
264 #if defined(WITH_CONTIKI) || defined(WITH_LWIP)
265  if (mtu > COAP_MAX_MESSAGE_SIZE_TCP16 + 4)
266  mtu = COAP_MAX_MESSAGE_SIZE_TCP16 + 4;
267 #endif
268  session->mtu = mtu;
269  if (session->tls_overhead >= session->mtu) {
270  session->tls_overhead = session->mtu;
271  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
272  }
273 }
274 
275 ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen) {
276  ssize_t bytes_written;
277 
278  coap_socket_t *sock = &session->sock;
279  if (sock->flags == COAP_SOCKET_EMPTY) {
280  assert(session->endpoint != NULL);
281  sock = &session->endpoint->sock;
282  }
283 
284  bytes_written = coap_socket_send(sock, session, data, datalen);
285  if (bytes_written == (ssize_t)datalen) {
286  coap_ticks(&session->last_rx_tx);
287  coap_log(LOG_DEBUG, "* %s: sent %zd bytes\n",
288  coap_session_str(session), datalen);
289  } else {
290  coap_log(LOG_DEBUG, "* %s: failed to send %zd bytes\n",
291  coap_session_str(session), datalen);
292  }
293  return bytes_written;
294 }
295 
296 ssize_t coap_session_write(coap_session_t *session, const uint8_t *data, size_t datalen) {
297  ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
298  if (bytes_written > 0) {
299  coap_ticks(&session->last_rx_tx);
300  coap_log(LOG_DEBUG, "* %s: sent %zd bytes\n",
301  coap_session_str(session), datalen);
302  } else if (bytes_written < 0) {
303  coap_log(LOG_DEBUG, "* %s: failed to send %zd bytes\n",
304  coap_session_str(session), datalen );
305  }
306  return bytes_written;
307 }
308 
309 ssize_t
311  coap_queue_t *node)
312 {
313  if ( node ) {
314  coap_queue_t *removed = NULL;
315  coap_remove_from_queue(&session->context->sendqueue, session, node->id, &removed);
316  assert(removed == node);
318  node->session = NULL;
319  node->t = 0;
320  } else {
321  coap_queue_t *q = NULL;
322  /* Check that the same mid is not getting re-used in violation of RFC7252 */
323  LL_FOREACH(session->delayqueue, q) {
324  if (q->id == pdu->mid) {
325  coap_log(LOG_ERR, "** %s: mid=0x%x: already in-use - dropped\n",
326  coap_session_str(session), pdu->mid);
327  return COAP_INVALID_MID;
328  }
329  }
330  node = coap_new_node();
331  if (node == NULL)
332  return COAP_INVALID_MID;
333  node->id = pdu->mid;
334  node->pdu = pdu;
335  if (pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
336  uint8_t r;
337  coap_prng(&r, sizeof(r));
338  /* add timeout in range [ACK_TIMEOUT...ACK_TIMEOUT * ACK_RANDOM_FACTOR] */
339  node->timeout = coap_calc_timeout(session, r);
340  }
341  }
342  LL_APPEND(session->delayqueue, node);
343  coap_log(LOG_DEBUG, "** %s: mid=0x%x: delayed\n",
344  coap_session_str(session), node->id);
345  return COAP_PDU_DELAYED;
346 }
347 
348 #if !COAP_DISABLE_TCP
350  coap_pdu_t *pdu;
351  uint8_t buf[4];
352  assert(COAP_PROTO_RELIABLE(session->proto));
353  coap_log(LOG_DEBUG, "***%s: sending CSM\n", coap_session_str(session));
354  session->state = COAP_SESSION_STATE_CSM;
355  session->partial_write = 0;
356  if (session->mtu == 0)
357  session->mtu = COAP_DEFAULT_MTU; /* base value */
359  if ( pdu == NULL
361  coap_encode_var_safe(buf, sizeof(buf),
362  COAP_DEFAULT_MAX_PDU_RX_SIZE), buf) == 0
364  coap_encode_var_safe(buf, sizeof(buf),
365  0), buf) == 0
366  || coap_pdu_encode_header(pdu, session->proto) == 0
367  ) {
369  } else {
370  ssize_t bytes_written = coap_session_send_pdu(session, pdu);
371  if (bytes_written != (ssize_t)pdu->used_size + pdu->hdr_size)
373  }
374  if (pdu)
375  coap_delete_pdu(pdu);
376 }
377 #endif /* !COAP_DISABLE_TCP */
378 
380  coap_pdu_t *ping = NULL;
381  if (session->state != COAP_SESSION_STATE_ESTABLISHED)
382  return COAP_INVALID_MID;
383  if (COAP_PROTO_NOT_RELIABLE(session->proto)) {
384  uint16_t mid = coap_new_message_id (session);
385  ping = coap_pdu_init(COAP_MESSAGE_CON, 0, mid, 0);
386  }
387 #if !COAP_DISABLE_TCP
388  else {
390  }
391 #endif /* !COAP_DISABLE_TCP */
392  if (!ping)
393  return COAP_INVALID_MID;
394  return coap_send(session, ping);
395 }
396 
398  if (session->state != COAP_SESSION_STATE_ESTABLISHED) {
399  coap_log(LOG_DEBUG, "***%s: session connected\n",
400  coap_session_str(session));
401  if (session->state == COAP_SESSION_STATE_CSM)
403  }
404 
406  session->partial_write = 0;
407 
408  if ( session->proto==COAP_PROTO_DTLS) {
409  session->tls_overhead = coap_dtls_get_overhead(session);
410  if (session->tls_overhead >= session->mtu) {
411  session->tls_overhead = session->mtu;
412  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
413  }
414  }
415 
416  while (session->delayqueue && session->state == COAP_SESSION_STATE_ESTABLISHED) {
417  ssize_t bytes_written;
418  coap_queue_t *q = session->delayqueue;
419  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
420  if (session->con_active >= COAP_DEFAULT_NSTART)
421  break;
422  session->con_active++;
423  }
424  /* Take entry off the queue */
425  session->delayqueue = q->next;
426  q->next = NULL;
427 
428  coap_log(LOG_DEBUG, "** %s: mid=0x%x: transmitted after delay\n",
429  coap_session_str(session), (int)q->pdu->mid);
430  bytes_written = coap_session_send_pdu(session, q->pdu);
431  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
432  if (coap_wait_ack(session->context, session, q) >= 0)
433  q = NULL;
434  }
435  if (COAP_PROTO_NOT_RELIABLE(session->proto)) {
436  if (q)
437  coap_delete_node(q);
438  if (bytes_written < 0)
439  break;
440  } else {
441  if (bytes_written <= 0 || (size_t)bytes_written < q->pdu->used_size + q->pdu->hdr_size) {
442  q->next = session->delayqueue;
443  session->delayqueue = q;
444  if (bytes_written > 0)
445  session->partial_write = (size_t)bytes_written;
446  break;
447  } else {
448  coap_delete_node(q);
449  }
450  }
451  }
452 }
453 
455 #if !COAP_DISABLE_TCP
456  coap_session_state_t state = session->state;
457 #endif /* !COAP_DISABLE_TCP */
458 
459  coap_log(LOG_DEBUG, "***%s: session disconnected (reason %d)\n",
460  coap_session_str(session), reason);
461  coap_delete_observers( session->context, session );
462 
463  if ( session->tls) {
464  if (session->proto == COAP_PROTO_DTLS)
465  coap_dtls_free_session(session);
466 #if !COAP_DISABLE_TCP
467  else if (session->proto == COAP_PROTO_TLS)
468  coap_tls_free_session(session);
469 #endif /* !COAP_DISABLE_TCP */
470  session->tls = NULL;
471  }
472 
473  if (session->proto == COAP_PROTO_UDP)
475  else
476  session->state = COAP_SESSION_STATE_NONE;
477 
478  session->con_active = 0;
479 
480  if (session->partial_pdu) {
481  coap_delete_pdu(session->partial_pdu);
482  session->partial_pdu = NULL;
483  }
484  session->partial_read = 0;
485 
486  while (session->delayqueue) {
487  coap_queue_t *q = session->delayqueue;
488  session->delayqueue = q->next;
489  q->next = NULL;
490  coap_log(LOG_DEBUG, "** %s: mid=0x%x: not transmitted after disconnect\n",
491  coap_session_str(session), q->id);
492  if (q->pdu->type==COAP_MESSAGE_CON
493  && COAP_PROTO_NOT_RELIABLE(session->proto)
494  && reason == COAP_NACK_ICMP_ISSUE)
495  {
496  /* Make sure that we try a re-transmit later on ICMP error */
497  if (coap_wait_ack(session->context, session, q) >= 0) {
498  if (session->context->nack_handler) {
499  session->context->nack_handler(session, q->pdu, reason, q->id);
500  }
501  q = NULL;
502  }
503  }
504  if (q && q->pdu->type == COAP_MESSAGE_CON
505  && session->context->nack_handler)
506  {
507  session->context->nack_handler(session, q->pdu, reason, q->id);
508  }
509  if (q)
510  coap_delete_node(q);
511  }
512  if (reason != COAP_NACK_ICMP_ISSUE) {
513  coap_cancel_session_messages(session->context, session, reason);
514  }
515  else if (session->context->nack_handler) {
516  coap_queue_t *q = session->context->sendqueue;
517  while (q) {
518  if (q->session == session) {
519  session->context->nack_handler(session, q->pdu, reason, q->id);
520  }
521  q = q->next;
522  }
523  }
524 
525 #if !COAP_DISABLE_TCP
526  if (COAP_PROTO_RELIABLE(session->proto)) {
527  if (session->sock.flags != COAP_SOCKET_EMPTY) {
528  coap_socket_close(&session->sock);
529  coap_handle_event(session->context,
532  }
533  if (state != COAP_SESSION_STATE_NONE) {
534  coap_handle_event(session->context,
537  }
538  }
539 #endif /* !COAP_DISABLE_TCP */
540 }
541 
542 static void
544  const coap_addr_tuple_t *addr_info) {
545  memset(addr_hash, 0, sizeof(coap_addr_hash_t));
546  coap_address_copy(&addr_hash->remote, &addr_info->remote);
547  addr_hash->lport = coap_address_get_port(&addr_info->local);
548  addr_hash->proto = proto;
549 }
550 
553  const coap_packet_t *packet, coap_tick_t now) {
554  coap_session_t *session;
555  coap_session_t *rtmp;
556  unsigned int num_idle = 0;
557  unsigned int num_hs = 0;
558  coap_session_t *oldest = NULL;
559  coap_session_t *oldest_hs = NULL;
560  coap_addr_hash_t addr_hash;
561 
562  coap_make_addr_hash(&addr_hash, endpoint->proto, &packet->addr_info);
563  SESSIONS_FIND(endpoint->sessions, addr_hash, session);
564  if (session) {
565  /* Maybe mcast or unicast IP address which is not in the hash */
566  coap_address_copy(&session->addr_info.local, &packet->addr_info.local);
567  session->ifindex = packet->ifindex;
568  session->last_rx_tx = now;
569  return session;
570  }
571 
572  SESSIONS_ITER(endpoint->sessions, session, rtmp) {
573  if (session->ref == 0 && session->delayqueue == NULL) {
574  if (session->type == COAP_SESSION_TYPE_SERVER) {
575  ++num_idle;
576  if (oldest==NULL || session->last_rx_tx < oldest->last_rx_tx)
577  oldest = session;
578 
579  if (session->state == COAP_SESSION_STATE_HANDSHAKE) {
580  ++num_hs;
581  /* See if this is a partial (D)TLS session set up
582  which needs to be cleared down to prevent DOS */
583  if ((session->last_rx_tx + COAP_PARTIAL_SESSION_TIMEOUT_TICKS) < now) {
584  if (oldest_hs == NULL ||
585  session->last_rx_tx < oldest_hs->last_rx_tx)
586  oldest_hs = session;
587  }
588  }
589  }
590  else if (session->type == COAP_SESSION_TYPE_HELLO) {
591  ++num_hs;
592  /* See if this is a partial (D)TLS session set up for Client Hello
593  which needs to be cleared down to prevent DOS */
594  if ((session->last_rx_tx + COAP_PARTIAL_SESSION_TIMEOUT_TICKS) < now) {
595  if (oldest_hs == NULL ||
596  session->last_rx_tx < oldest_hs->last_rx_tx)
597  oldest_hs = session;
598  }
599  }
600  }
601  }
602 
603  if (endpoint->context->max_idle_sessions > 0 &&
604  num_idle >= endpoint->context->max_idle_sessions) {
605  coap_session_free(oldest);
606  }
607  else if (oldest_hs) {
608  coap_log(LOG_WARNING, "***%s: Incomplete session timed out\n",
609  coap_session_str(oldest_hs));
610  coap_session_free(oldest_hs);
611  }
612 
613  if (num_hs > (endpoint->context->max_handshake_sessions ?
614  endpoint->context->max_handshake_sessions :
616  /* Maxed out on number of sessions in (D)TLS negotiation state */
618  "Oustanding sessions in COAP_SESSION_STATE_HANDSHAKE too "
619  "large. New request ignored\n");
620  return NULL;
621  }
622 
623  if (endpoint->proto == COAP_PROTO_DTLS) {
624  /*
625  * Need to check that this actually is a Client Hello before wasting
626  * time allocating and then freeing off session.
627  */
628 
629  /*
630  * Generic header structure of the DTLS record layer.
631  * typedef struct __attribute__((__packed__)) {
632  * uint8_t content_type; content type of the included message
633  * uint16_t version; Protocol version
634  * uint16_t epoch; counter for cipher state changes
635  * uint8_t sequence_number[6]; sequence number
636  * uint16_t length; length of the following fragment
637  * uint8_t handshake; If content_type == DTLS_CT_HANDSHAKE
638  * } dtls_record_handshake_t;
639  */
640 #define OFF_CONTENT_TYPE 0 /* offset of content_type in dtls_record_handshake_t */
641 #define DTLS_CT_ALERT 21 /* Content Type Alert */
642 #define DTLS_CT_HANDSHAKE 22 /* Content Type Handshake */
643 #define OFF_HANDSHAKE_TYPE 13 /* offset of handshake in dtls_record_handshake_t */
644 #define DTLS_HT_CLIENT_HELLO 1 /* Client Hello handshake type */
645 
646 #ifdef WITH_LWIP
647  const uint8_t *payload = (const uint8_t*)packet->pbuf->payload;
648  size_t length = packet->pbuf->len;
649 #else /* ! WITH_LWIP */
650  const uint8_t *payload = (const uint8_t*)packet->payload;
651  size_t length = packet->length;
652 #endif /* ! WITH_LWIP */
653  if (length < (OFF_HANDSHAKE_TYPE + 1)) {
655  "coap_dtls_hello: ContentType %d Short Packet (%zu < %d) dropped\n",
656  payload[OFF_CONTENT_TYPE], length,
657  OFF_HANDSHAKE_TYPE + 1);
658  return NULL;
659  }
660  if (payload[OFF_CONTENT_TYPE] != DTLS_CT_HANDSHAKE ||
662  /* only log if not a late alert */
663  if (payload[OFF_CONTENT_TYPE] != DTLS_CT_ALERT)
665  "coap_dtls_hello: ContentType %d Handshake %d dropped\n",
666  payload[OFF_CONTENT_TYPE], payload[OFF_HANDSHAKE_TYPE]);
667  return NULL;
668  }
669  }
670  session = coap_make_session(endpoint->proto, COAP_SESSION_TYPE_SERVER,
671  &addr_hash, &packet->addr_info.local,
672  &packet->addr_info.remote,
673  packet->ifindex, endpoint->context, endpoint);
674  if (session) {
675  session->last_rx_tx = now;
676  if (endpoint->proto == COAP_PROTO_UDP)
678  else if (endpoint->proto == COAP_PROTO_DTLS) {
679  session->type = COAP_SESSION_TYPE_HELLO;
680  }
681  SESSIONS_ADD(endpoint->sessions, session);
682  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
683  coap_session_str(session));
684  }
685  return session;
686 }
687 
690  coap_tick_t now) {
691  if (session) {
692  session->last_rx_tx = now;
693  session->type = COAP_SESSION_TYPE_SERVER;
694  session->tls = coap_dtls_new_server_session(session);
695  if (session->tls) {
697  } else {
698  coap_session_free(session);
699  session = NULL;
700  }
701  }
702  return session;
703 }
704 
705 #ifdef COAP_EPOLL_SUPPORT
706 static void
707 coap_epoll_ctl_add(coap_socket_t *sock,
708  uint32_t events,
709  const char *func
710 ) {
711  int ret;
712  struct epoll_event event;
713  coap_context_t *context;
714 
715  if (sock == NULL)
716  return;
717 
718  context = sock->session ? sock->session->context :
719  sock->endpoint ? sock->endpoint->context : NULL;
720  if (context == NULL)
721  return;
722 
723  /* Needed if running 32bit as ptr is only 32bit */
724  memset(&event, 0, sizeof(event));
725  event.events = events;
726  event.data.ptr = sock;
727 
728  ret = epoll_ctl(context->epfd, EPOLL_CTL_ADD, sock->fd, &event);
729  if (ret == -1) {
731  "%s: epoll_ctl ADD failed: %s (%d)\n",
732  func,
733  coap_socket_strerror(), errno);
734  }
735 }
736 #endif /* COAP_EPOLL_SUPPORT */
737 
738 static coap_session_t *
740  coap_context_t *ctx,
741  const coap_address_t *local_if,
742  const coap_address_t *server,
743  coap_proto_t proto
744 ) {
745  coap_session_t *session = NULL;
746 
747  assert(server);
748 
749  switch(proto) {
750  case COAP_PROTO_UDP:
751  break;
752  case COAP_PROTO_DTLS:
753  if (!coap_dtls_is_supported()) {
754  coap_log(LOG_CRIT, "coap_new_client_session*: DTLS not supported\n");
755  return NULL;
756  }
757  break;
758  case COAP_PROTO_TCP:
759  if (!coap_tcp_is_supported()) {
760  coap_log(LOG_CRIT, "coap_new_client_session*: TCP not supported\n");
761  return NULL;
762  }
763  break;
764  case COAP_PROTO_TLS:
765  if (!coap_tls_is_supported()) {
766  coap_log(LOG_CRIT, "coap_new_client_session*: TLS not supported\n");
767  return NULL;
768  }
769  break;
770  case COAP_PROTO_NONE:
771  default:
772  assert(0);
773  break;
774  }
775  session = coap_make_session(proto, COAP_SESSION_TYPE_CLIENT, NULL,
776  local_if, server, 0, ctx, NULL);
777  if (!session)
778  goto error;
779 
780  coap_session_reference(session);
781 
782  if (proto == COAP_PROTO_UDP || proto == COAP_PROTO_DTLS) {
783  if (!coap_socket_connect_udp(&session->sock, local_if, server,
785  &session->addr_info.local, &session->addr_info.remote)) {
786  goto error;
787  }
788 #if !COAP_DISABLE_TCP
789  } else if (proto == COAP_PROTO_TCP || proto == COAP_PROTO_TLS) {
790  if (!coap_socket_connect_tcp1(&session->sock, local_if, server,
792  &session->addr_info.local, &session->addr_info.remote)) {
793  goto error;
794  }
795 #endif /* !COAP_DISABLE_TCP */
796  }
797 
798 #ifdef COAP_EPOLL_SUPPORT
799  session->sock.session = session;
800  coap_epoll_ctl_add(&session->sock,
801  EPOLLIN |
802  ((session->sock.flags & COAP_SOCKET_WANT_CONNECT) ?
803  EPOLLOUT : 0),
804  __func__);
805 #endif /* COAP_EPOLL_SUPPORT */
806 
808  if (local_if)
809  session->sock.flags |= COAP_SOCKET_BOUND;
810  SESSIONS_ADD(ctx->sessions, session);
811  return session;
812 
813 error:
814  coap_session_release(session);
815  return NULL;
816 }
817 
818 static coap_session_t *
820  if (session->proto == COAP_PROTO_UDP) {
822  } else if (session->proto == COAP_PROTO_DTLS) {
823  session->tls = coap_dtls_new_client_session(session);
824  if (session->tls) {
826  } else {
827  /* Need to free session object. As a new session may not yet
828  * have been referenced, we call coap_session_reference() first
829  * before trying to release the object.
830  */
831  coap_session_reference(session);
832  coap_session_release(session);
833  return NULL;
834  }
835 #if !COAP_DISABLE_TCP
836  } else {
837  if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS) {
838  if (session->sock.flags & COAP_SOCKET_WANT_CONNECT) {
840  } else if (session->proto == COAP_PROTO_TLS) {
841  int connected = 0;
842  session->tls = coap_tls_new_client_session(session, &connected);
843  if (session->tls) {
845  if (connected)
846  coap_session_send_csm(session);
847  } else {
848  /* Need to free session object. As a new session may not yet
849  * have been referenced, we call coap_session_reference()
850  * first before trying to release the object.
851  */
852  coap_session_reference(session);
853  coap_session_release(session);
854  return NULL;
855  }
856  } else {
857  coap_session_send_csm(session);
858  }
859  }
860 #endif /* !COAP_DISABLE_TCP */
861  }
862  coap_ticks(&session->last_rx_tx);
863  return session;
864 }
865 
866 static coap_session_t *
868 #if !COAP_DISABLE_TCP
869  if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS)
871  if (session->proto == COAP_PROTO_TCP) {
872  coap_session_send_csm(session);
873  } else if (session->proto == COAP_PROTO_TLS) {
874  int connected = 0;
875  session->tls = coap_tls_new_server_session(session, &connected);
876  if (session->tls) {
878  if (connected) {
880  coap_session_send_csm(session);
881  }
882  } else {
883  /* Need to free session object. As a new session may not yet
884  * have been referenced, we call coap_session_reference() first
885  * before trying to release the object.
886  */
887  coap_session_reference(session);
888  coap_session_release(session);
889  session = NULL;
890  }
891  }
892 #endif /* COAP_DISABLE_TCP */
893  return session;
894 }
895 
897  coap_context_t *ctx,
898  const coap_address_t *local_if,
899  const coap_address_t *server,
900  coap_proto_t proto
901 ) {
902  coap_session_t *session = coap_session_create_client(ctx, local_if, server, proto);
903  if (session) {
904  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
905  coap_session_str(session));
906  session = coap_session_connect(session);
907  }
908  return session;
909 }
910 
912  coap_context_t *ctx,
913  const coap_address_t *local_if,
914  const coap_address_t *server,
915  coap_proto_t proto,
916  const char *identity,
917  const uint8_t *key,
918  unsigned key_len
919 ) {
920  coap_dtls_cpsk_t setup_data;
921 
922  memset (&setup_data, 0, sizeof(setup_data));
923 
924  if (identity) {
925  setup_data.psk_info.identity.s = (const uint8_t *)identity;
926  setup_data.psk_info.identity.length = strlen(identity);
927  }
928 
929  if (key && key_len > 0) {
930  setup_data.psk_info.key.s = key;
931  setup_data.psk_info.key.length = key_len;
932  }
933 
934  return coap_new_client_session_psk2(ctx, local_if, server,
935  proto, &setup_data);
936 }
937 
939  coap_context_t *ctx,
940  const coap_address_t *local_if,
941  const coap_address_t *server,
942  coap_proto_t proto,
943  coap_dtls_cpsk_t *setup_data
944 ) {
945  coap_session_t *session = coap_session_create_client(ctx, local_if,
946  server, proto);
947 
948  if (!session)
949  return NULL;
950 
951  session->cpsk_setup_data = *setup_data;
952  if (setup_data->psk_info.identity.s) {
953  session->psk_identity =
955  setup_data->psk_info.identity.length);
956  if (!session->psk_identity) {
957  coap_log(LOG_WARNING, "Cannot store session Identity (PSK)\n");
958  coap_session_release(session);
959  return NULL;
960  }
961  }
962  else if (coap_dtls_is_supported()) {
963  coap_log(LOG_WARNING, "Identity (PSK) not defined\n");
964  coap_session_release(session);
965  return NULL;
966  }
967 
968  if (setup_data->psk_info.key.s && setup_data->psk_info.key.length > 0) {
969  session->psk_key = coap_new_bin_const(setup_data->psk_info.key.s,
970  setup_data->psk_info.key.length);
971  if (!session->psk_key) {
972  coap_log(LOG_WARNING, "Cannot store session pre-shared key (PSK)\n");
973  coap_session_release(session);
974  return NULL;
975  }
976  }
977  else if (coap_dtls_is_supported()) {
978  coap_log(LOG_WARNING, "Pre-shared key (PSK) not defined\n");
979  coap_session_release(session);
980  return NULL;
981  }
982 
983  if (coap_dtls_is_supported()) {
984  if (!coap_dtls_context_set_cpsk(ctx, setup_data)) {
985  coap_session_release(session);
986  return NULL;
987  }
988  }
989  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
990  coap_session_str(session));
991  return coap_session_connect(session);
992 }
993 
995  const coap_bin_const_t *psk_hint
996 ) {
997  /* We may be refreshing the hint with the same hint */
998  coap_bin_const_t *old_psk_hint = session->psk_hint;
999 
1000  if (psk_hint && psk_hint->s) {
1001  if (session->psk_hint) {
1002  if (coap_binary_equal(session->psk_hint, psk_hint))
1003  return 1;
1004  }
1005  session->psk_hint = coap_new_bin_const(psk_hint->s,
1006  psk_hint->length);
1007  if (!session->psk_hint) {
1008  coap_log(LOG_ERR, "No memory to store identity hint (PSK)\n");
1009  if (old_psk_hint)
1010  coap_delete_bin_const(old_psk_hint);
1011  return 0;
1012  }
1013  }
1014  else {
1015  session->psk_hint = NULL;
1016  }
1017  if (old_psk_hint)
1018  coap_delete_bin_const(old_psk_hint);
1019 
1020  return 1;
1021 }
1022 
1024  const coap_bin_const_t *psk_key
1025 ) {
1026  /* We may be refreshing the key with the same key */
1027  coap_bin_const_t *old_psk_key = session->psk_key;
1028 
1029  if (psk_key && psk_key->s) {
1030  if (session->psk_key) {
1031  if (coap_binary_equal(session->psk_key, psk_key))
1032  return 1;
1033  }
1034  session->psk_key = coap_new_bin_const(psk_key->s, psk_key->length);
1035  if (!session->psk_key) {
1036  coap_log(LOG_ERR, "No memory to store pre-shared key (PSK)\n");
1037  if (old_psk_key)
1038  coap_delete_bin_const(old_psk_key);
1039  return 0;
1040  }
1041  }
1042  else {
1043  session->psk_key = NULL;
1044  }
1045  if (old_psk_key)
1046  coap_delete_bin_const(old_psk_key);
1047 
1048  return 1;
1049 }
1050 
1051 const coap_bin_const_t *
1053  if (session)
1054  return session->psk_hint;
1055  return NULL;
1056 }
1057 
1058 const coap_bin_const_t *
1060  if (session)
1061  return session->psk_key;
1062  return NULL;
1063 }
1064 
1066  coap_context_t *ctx,
1067  const coap_address_t *local_if,
1068  const coap_address_t *server,
1069  coap_proto_t proto,
1070  coap_dtls_pki_t* setup_data
1071 ) {
1072  coap_session_t *session;
1073 
1074  if (coap_dtls_is_supported()) {
1075  if (!setup_data) {
1076  return NULL;
1077  } else {
1078  if (setup_data->version != COAP_DTLS_PKI_SETUP_VERSION) {
1079  coap_log(LOG_ERR,
1080  "coap_new_client_session_pki: Wrong version of setup_data\n");
1081  return NULL;
1082  }
1083  }
1084 
1085  }
1086  session = coap_session_create_client(ctx, local_if, server, proto);
1087 
1088  if (!session) {
1089  return NULL;
1090  }
1091 
1092  if (coap_dtls_is_supported()) {
1093  /* we know that setup_data is not NULL */
1094  if (!coap_dtls_context_set_pki(ctx, setup_data, COAP_DTLS_ROLE_CLIENT)) {
1095  coap_session_release(session);
1096  return NULL;
1097  }
1098  }
1099  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
1100  coap_session_str(session));
1101  return coap_session_connect(session);
1102 }
1103 
1105  coap_context_t *ctx,
1106  coap_endpoint_t *ep
1107 ) {
1108  coap_session_t *session;
1110  NULL, NULL, NULL, 0, ctx, ep );
1111  if (!session)
1112  goto error;
1113 
1114 #if !COAP_DISABLE_TCP
1115  if (!coap_socket_accept_tcp(&ep->sock, &session->sock,
1116  &session->addr_info.local,
1117  &session->addr_info.remote))
1118  goto error;
1119  coap_make_addr_hash(&session->addr_hash, session->proto, &session->addr_info);
1120 
1121 #endif /* !COAP_DISABLE_TCP */
1124 #ifdef COAP_EPOLL_SUPPORT
1125  session->sock.session = session;
1126  coap_epoll_ctl_add(&session->sock,
1127  EPOLLIN,
1128  __func__);
1129 #endif /* COAP_EPOLL_SUPPORT */
1130  SESSIONS_ADD(ep->sessions, session);
1131  if (session) {
1132  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
1133  coap_session_str(session));
1134  session = coap_session_accept(session);
1135  }
1136  return session;
1137 
1138 error:
1139  coap_session_free(session);
1140  return NULL;
1141 }
1142 
1143 void
1145  const uint8_t *data) {
1146  session->tx_token = coap_decode_var_bytes8(data, len);
1147 }
1148 
1149 void coap_session_new_token(coap_session_t *session, size_t *len,
1150  uint8_t *data) {
1151  *len = coap_encode_var_safe8(data,
1152  sizeof(session->tx_token), ++session->tx_token);
1153 }
1154 
1155 uint16_t
1157  return ++session->tx_mid;
1158 }
1159 
1160 const coap_address_t *
1162  if (session)
1163  return &session->addr_info.remote;
1164  return NULL;
1165 }
1166 
1167 const coap_address_t *
1169  if (session)
1170  return &session->addr_info.local;
1171  return NULL;
1172 }
1173 
1176  if (session)
1177  return session->context;
1178  return NULL;
1179 }
1180 
1183  if (session)
1184  return session->proto;
1185  return 0;
1186 }
1187 
1190  if (session)
1191  return session->type;
1192  return 0;
1193 }
1194 
1195 int
1197  if (session && session->type == COAP_SESSION_TYPE_SERVER) {
1198  coap_session_reference(session);
1199  session->type = COAP_SESSION_TYPE_CLIENT;
1200  return 1;
1201  }
1202  return 0;
1203 }
1204 
1207  if (session)
1208  return session->state;
1209  return 0;
1210 }
1211 
1213  if (session)
1214  return session->ifindex;
1215  return -1;
1216 }
1217 
1219  coap_tls_library_t *tls_lib) {
1220  if (session)
1221  return coap_dtls_get_tls(session, tls_lib);
1222  return NULL;
1223 }
1224 
1225 #ifndef WITH_LWIP
1227 coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto) {
1228  coap_endpoint_t *ep = NULL;
1229 
1230  assert(context);
1231  assert(listen_addr);
1232  assert(proto != COAP_PROTO_NONE);
1233 
1234  if (proto == COAP_PROTO_DTLS && !coap_dtls_is_supported()) {
1235  coap_log(LOG_CRIT, "coap_new_endpoint: DTLS not supported\n");
1236  goto error;
1237  }
1238 
1239  if (proto == COAP_PROTO_TLS && !coap_tls_is_supported()) {
1240  coap_log(LOG_CRIT, "coap_new_endpoint: TLS not supported\n");
1241  goto error;
1242  }
1243 
1244  if (proto == COAP_PROTO_TCP && !coap_tcp_is_supported()) {
1245  coap_log(LOG_CRIT, "coap_new_endpoint: TCP not supported\n");
1246  goto error;
1247  }
1248 
1249  if (proto == COAP_PROTO_DTLS || proto == COAP_PROTO_TLS) {
1250  if (!coap_dtls_context_check_keys_enabled(context)) {
1252  "coap_new_endpoint: one of coap_context_set_psk() or "
1253  "coap_context_set_pki() not called\n");
1254  goto error;
1255  }
1256  }
1257 
1258  ep = coap_malloc_endpoint();
1259  if (!ep) {
1260  coap_log(LOG_WARNING, "coap_new_endpoint: malloc");
1261  goto error;
1262  }
1263 
1264  memset(ep, 0, sizeof(coap_endpoint_t));
1265  ep->context = context;
1266  ep->proto = proto;
1267 
1268  if (proto==COAP_PROTO_UDP || proto==COAP_PROTO_DTLS) {
1269  if (!coap_socket_bind_udp(&ep->sock, listen_addr, &ep->bind_addr))
1270  goto error;
1272 #if !COAP_DISABLE_TCP
1273  } else if (proto==COAP_PROTO_TCP || proto==COAP_PROTO_TLS) {
1274  if (!coap_socket_bind_tcp(&ep->sock, listen_addr, &ep->bind_addr))
1275  goto error;
1277 #endif /* !COAP_DISABLE_TCP */
1278  } else {
1279  coap_log(LOG_CRIT, "coap_new_endpoint: protocol not supported\n");
1280  goto error;
1281  }
1282 
1283  if (LOG_DEBUG <= coap_get_log_level()) {
1284 #ifndef INET6_ADDRSTRLEN
1285 #define INET6_ADDRSTRLEN 40
1286 #endif
1287  unsigned char addr_str[INET6_ADDRSTRLEN + 8];
1288 
1289  if (coap_print_addr(&ep->bind_addr, addr_str, INET6_ADDRSTRLEN + 8)) {
1290  coap_log(LOG_DEBUG, "created %s endpoint %s\n",
1291  ep->proto == COAP_PROTO_TLS ? "TLS "
1292  : ep->proto == COAP_PROTO_TCP ? "TCP "
1293  : ep->proto == COAP_PROTO_DTLS ? "DTLS" : "UDP ",
1294  addr_str);
1295  }
1296  }
1297 
1299 
1301 
1302 #ifdef COAP_EPOLL_SUPPORT
1303  ep->sock.endpoint = ep;
1304  coap_epoll_ctl_add(&ep->sock,
1305  EPOLLIN,
1306  __func__);
1307 #endif /* COAP_EPOLL_SUPPORT */
1308 
1309  LL_PREPEND(context->endpoint, ep);
1310  return ep;
1311 
1312 error:
1313  coap_free_endpoint(ep);
1314  return NULL;
1315 }
1316 
1318  ep->default_mtu = (uint16_t)mtu;
1319 }
1320 
1321 void
1323  if (ep) {
1324  coap_session_t *session, *rtmp;
1325 
1326  SESSIONS_ITER_SAFE(ep->sessions, session, rtmp) {
1327  assert(session->ref == 0);
1328  if (session->ref == 0) {
1329  coap_session_free(session);
1330  }
1331  }
1332  if (ep->sock.flags != COAP_SOCKET_EMPTY) {
1333  /*
1334  * ep->sock.endpoint is set in coap_new_endpoint().
1335  * ep->sock.session is never set.
1336  *
1337  * session->sock.session is set for both clients and servers (when a
1338  * new session is accepted), but does not affect the endpoint.
1339  *
1340  * So, it is safe to call coap_socket_close() after all the sessions
1341  * have been freed above as we are only working with the endpoint sock.
1342  */
1343 #ifdef COAP_EPOLL_SUPPORT
1344  assert(ep->sock.session == NULL);
1345 #endif /* COAP_EPOLL_SUPPORT */
1346  coap_socket_close(&ep->sock);
1347  }
1348 
1349  if (ep->context && ep->context->endpoint) {
1350  LL_DELETE(ep->context->endpoint, ep);
1351  }
1352  coap_mfree_endpoint(ep);
1353  }
1354 }
1355 #endif /* WITH_LWIP */
1356 
1359  const coap_address_t *remote_addr,
1360  int ifindex) {
1361  coap_session_t *s, *rtmp;
1362  coap_endpoint_t *ep;
1363  SESSIONS_ITER(ctx->sessions, s, rtmp) {
1364  if (s->ifindex == ifindex && coap_address_equals(&s->addr_info.remote,
1365  remote_addr))
1366  return s;
1367  }
1368  LL_FOREACH(ctx->endpoint, ep) {
1369  SESSIONS_ITER(ep->sessions, s, rtmp) {
1370  if (s->ifindex == ifindex && coap_address_equals(&s->addr_info.remote,
1371  remote_addr))
1372  return s;
1373  }
1374  }
1375  return NULL;
1376 }
1377 
1378 const char *coap_session_str(const coap_session_t *session) {
1379  static char szSession[2 * (INET6_ADDRSTRLEN + 8) + 24];
1380  char *p = szSession, *end = szSession + sizeof(szSession);
1381  if (coap_print_addr(&session->addr_info.local,
1382  (unsigned char*)p, end - p) > 0)
1383  p += strlen(p);
1384  if (p + 6 < end) {
1385  strcpy(p, " <-> ");
1386  p += 5;
1387  }
1388  if (p + 1 < end) {
1389  if (coap_print_addr(&session->addr_info.remote,
1390  (unsigned char*)p, end - p) > 0)
1391  p += strlen(p);
1392  }
1393  if (session->ifindex > 0 && p + 1 < end)
1394  p += snprintf(p, end - p, " (if%d)", session->ifindex);
1395  if (p + 6 < end) {
1396  if (session->proto == COAP_PROTO_UDP) {
1397  strcpy(p, " UDP ");
1398  p += 4;
1399  } else if (session->proto == COAP_PROTO_DTLS) {
1400  strcpy(p, " DTLS");
1401  p += 5;
1402  } else if (session->proto == COAP_PROTO_TCP) {
1403  strcpy(p, " TCP ");
1404  p += 4;
1405  } else if (session->proto == COAP_PROTO_TLS) {
1406  strcpy(p, " TLS ");
1407  p += 4;
1408  } else {
1409  strcpy(p, " NONE");
1410  p += 5;
1411  }
1412  }
1413 
1414  return szSession;
1415 }
1416 
1417 const char *coap_endpoint_str(const coap_endpoint_t *endpoint) {
1418  static char szEndpoint[128];
1419  char *p = szEndpoint, *end = szEndpoint + sizeof(szEndpoint);
1420  if (coap_print_addr(&endpoint->bind_addr, (unsigned char*)p, end - p) > 0)
1421  p += strlen(p);
1422  if (p + 6 < end) {
1423  if (endpoint->proto == COAP_PROTO_UDP) {
1424  strcpy(p, " UDP");
1425  p += 4;
1426  } else if (endpoint->proto == COAP_PROTO_DTLS) {
1427  strcpy(p, " DTLS");
1428  p += 5;
1429  } else {
1430  strcpy(p, " NONE");
1431  p += 5;
1432  }
1433  }
1434 
1435  return szEndpoint;
1436 }
1437 
1438 #endif /* COAP_SESSION_C_ */
void coap_address_init(coap_address_t *addr)
Resets the given coap_address_t object addr to its default values.
Definition: address.c:100
uint16_t coap_address_get_port(const coap_address_t *addr)
Returns the port from addr in host byte order.
Definition: address.c:31
int coap_address_equals(const coap_address_t *a, const coap_address_t *b)
Compares given address objects a and b.
Definition: address.c:58
COAP_STATIC_INLINE void coap_address_copy(coap_address_t *dst, const coap_address_t *src)
Definition: address.h:150
Pulls together all the internal only header files.
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:240
void coap_socket_close(coap_socket_t *sock)
Definition: coap_io.c:366
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:1506
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Definition: coap_io.c:425
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Definition: coap_io.c:152
const char * coap_socket_strerror(void)
Definition: coap_io.c:1500
void coap_mfree_endpoint(coap_endpoint_t *ep)
Definition: coap_io.c:147
coap_endpoint_t * coap_malloc_endpoint(void)
Definition: coap_io.c:142
coap_nack_reason_t
Definition: coap_io.h:62
@ COAP_NACK_NOT_DELIVERABLE
Definition: coap_io.h:64
@ COAP_NACK_TLS_FAILED
Definition: coap_io.h:66
@ COAP_NACK_ICMP_ISSUE
Definition: coap_io.h:67
#define COAP_SOCKET_WANT_ACCEPT
non blocking server socket is waiting for accept
#define COAP_SOCKET_NOT_EMPTY
the socket is not empty
#define COAP_SOCKET_BOUND
the socket is bound
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
#define COAP_SOCKET_WANT_CONNECT
non blocking client socket is waiting for connect
#define COAP_SOCKET_CONNECTED
the socket is connected
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
void * coap_dtls_new_server_session(coap_session_t *session COAP_UNUSED)
Definition: coap_notls.c:103
int coap_dtls_context_set_pki(coap_context_t *ctx COAP_UNUSED, const coap_dtls_pki_t *setup_data COAP_UNUSED, const coap_dtls_role_t role COAP_UNUSED)
Definition: coap_notls.c:33
void * coap_dtls_new_client_session(coap_session_t *session COAP_UNUSED)
Definition: coap_notls.c:107
unsigned int coap_dtls_get_overhead(coap_session_t *session COAP_UNUSED)
Definition: coap_notls.c:157
void * coap_tls_new_client_session(coap_session_t *session COAP_UNUSED, int *connected COAP_UNUSED)
Definition: coap_notls.c:161
void * coap_tls_new_server_session(coap_session_t *session COAP_UNUSED, int *connected COAP_UNUSED)
Definition: coap_notls.c:165
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx COAP_UNUSED)
Definition: coap_notls.c:63
int coap_dtls_context_set_cpsk(coap_context_t *ctx COAP_UNUSED, coap_dtls_cpsk_t *setup_data COAP_UNUSED)
Definition: coap_notls.c:49
void coap_dtls_free_session(coap_session_t *coap_session COAP_UNUSED)
Definition: coap_notls.c:111
void * coap_dtls_get_tls(const coap_session_t *c_session COAP_UNUSED, coap_tls_library_t *tls_lib)
Definition: coap_notls.c:74
void coap_tls_free_session(coap_session_t *coap_session COAP_UNUSED)
Definition: coap_notls.c:169
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:23
coap_mid_t coap_session_send_ping(coap_session_t *session)
Send a ping message for the session.
Definition: coap_session.c:379
#define DTLS_HT_CLIENT_HELLO
#define OFF_HANDSHAKE_TYPE
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:42
coap_fixed_point_t coap_session_get_ack_random_factor(const coap_session_t *session)
Get the CoAP ack randomize factor.
Definition: coap_session.c:63
static void coap_make_addr_hash(coap_addr_hash_t *addr_hash, coap_proto_t proto, const coap_addr_tuple_t *addr_info)
Definition: coap_session.c:543
#define DTLS_CT_HANDSHAKE
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:739
coap_session_t * coap_session_get_by_peer(const coap_context_t *ctx, const coap_address_t *remote_addr, int ifindex)
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:32
#define OFF_CONTENT_TYPE
static coap_session_t * coap_make_session(coap_proto_t proto, coap_session_type_t type, const coap_addr_hash_t *addr_hash, 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:108
static coap_session_t * coap_session_accept(coap_session_t *session)
Definition: coap_session.c:867
static coap_session_t * coap_session_connect(coap_session_t *session)
Definition: coap_session.c:819
coap_fixed_point_t coap_session_get_ack_timeout(const coap_session_t *session)
Get the CoAP initial ack response timeout before the next re-transmit.
Definition: coap_session.c:58
#define INET6_ADDRSTRLEN
#define DTLS_CT_ALERT
unsigned int coap_session_get_max_retransmit(const coap_session_t *session)
Get the CoAP maximum retransmit before failure.
Definition: coap_session.c:53
#define SESSIONS_ADD(e, obj)
#define SESSIONS_ITER_SAFE(e, el, rtmp)
#define COAP_PARTIAL_SESSION_TIMEOUT_TICKS
#define SESSIONS_DELETE(e, obj)
#define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS
#define SESSIONS_ITER(e, el, rtmp)
#define SESSIONS_FIND(e, k, res)
int coap_tcp_is_supported(void)
Check whether TCP is available.
Definition: coap_tcp.c:31
void coap_block_delete_lg_srcv(coap_session_t *session, coap_lg_srcv_t *lg_srcv)
Definition: block.c:863
void coap_block_delete_lg_crcv(coap_session_t *session, coap_lg_crcv_t *lg_crcv)
Definition: block.c:848
void coap_block_delete_lg_xmit(coap_session_t *session, coap_lg_xmit_t *lg_xmit)
Definition: block.c:876
int coap_cancel_observe(coap_session_t *session, coap_binary_t *token, coap_pdu_type_t type)
Cancel an observe that is being tracked by the client large receive logic when using coap_send_large(...
Definition: block.c:277
void coap_delete_cache_entry(coap_context_t *ctx, coap_cache_entry_t *cache_entry)
Remove a cache-entry from the hash list and free off all the appropriate contents apart from app_data...
Definition: coap_cache.c:205
#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:410
#define COAP_DEFAULT_MAX_RETRANSMIT
Number of message retransmissions before message sending is stopped RFC 7252, Section 4....
Definition: coap_session.h:418
#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:401
#define COAP_DEFAULT_NSTART
The number of simultaneous outstanding interactions that a client maintains to a given server.
Definition: coap_session.h:425
void coap_ticks(coap_tick_t *t)
Sets t to the internal time with COAP_TICKS_PER_SECOND resolution.
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition: coap_time.h:120
int coap_prng(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
Definition: coap_prng.c:85
int coap_remove_from_queue(coap_queue_t **queue, coap_session_t *session, coap_mid_t id, coap_queue_t **node)
This function removes the element with given id from the list given list.
Definition: net.c:1936
int coap_delete_node(coap_queue_t *node)
Destroys specified node.
Definition: net.c:229
coap_queue_t * coap_new_node(void)
Creates a new node suitable for adding to the CoAP sendqueue.
Definition: net.c:258
unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r)
Calculates the initial timeout based on the session CoAP transmission parameters 'ack_timeout',...
Definition: net.c:945
coap_mid_t coap_wait_ack(coap_context_t *context, coap_session_t *session, coap_queue_t *node)
Definition: net.c:971
void coap_cancel_session_messages(coap_context_t *context, coap_session_t *session, coap_nack_reason_t reason)
Cancels all outstanding messages for session session.
Definition: net.c:1980
uint16_t coap_new_message_id(coap_session_t *session)
Returns a new message id and updates session->tx_mid accordingly.
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:3171
coap_mid_t coap_send(coap_session_t *session, coap_pdu_t *pdu)
Sends a CoAP message to given peer.
Definition: net.c:1155
coap_session_t * coap_session_new_dtls_session(coap_session_t *session, coap_tick_t now)
Create a new DTLS session for the session.
Definition: coap_session.c:689
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition: coap_notls.c:20
#define COAP_DTLS_PKI_SETUP_VERSION
Latest PKI setup version.
Definition: coap_dtls.h:237
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition: coap_notls.c:15
coap_tls_library_t
Definition: coap_dtls.h:50
@ COAP_DTLS_ROLE_CLIENT
Internal function invoked for client.
Definition: coap_dtls.h:30
unsigned int coap_encode_var_safe(uint8_t *buf, size_t length, unsigned int val)
Encodes multiple-length byte sequences.
Definition: encode.c:38
uint64_t coap_decode_var_bytes8(const uint8_t *buf, size_t len)
Decodes multiple-length byte sequences.
Definition: encode.c:58
unsigned int coap_encode_var_safe8(uint8_t *buf, size_t length, uint64_t val)
Encodes multiple-length byte sequences.
Definition: encode.c:68
#define COAP_EVENT_TCP_CLOSED
Definition: coap_event.h:39
#define COAP_EVENT_SESSION_CONNECTED
CSM exchange events for reliable protocols only.
Definition: coap_event.h:45
#define COAP_EVENT_SESSION_FAILED
Definition: coap_event.h:47
#define COAP_EVENT_TCP_FAILED
Definition: coap_event.h:40
#define COAP_EVENT_SESSION_CLOSED
Definition: coap_event.h:46
#define COAP_EVENT_DTLS_CONNECTED
Definition: coap_event.h:31
#define COAP_EVENT_TCP_CONNECTED
TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS.
Definition: coap_event.h:38
coap_log_t coap_get_log_level(void)
Get the current logging level.
Definition: coap_debug.c:61
const char * coap_session_str(const coap_session_t *session)
Get session description.
size_t coap_print_addr(const coap_address_t *addr, unsigned char *buf, size_t len)
Print the address into the defined buffer.
Definition: coap_debug.c:171
const char * coap_endpoint_str(const coap_endpoint_t *endpoint)
Get endpoint description.
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:150
@ LOG_ERR
Error.
Definition: coap_debug.h:53
@ LOG_CRIT
Critical.
Definition: coap_debug.h:52
@ LOG_INFO
Information.
Definition: coap_debug.h:56
@ LOG_WARNING
Warning.
Definition: coap_debug.h:54
@ LOG_DEBUG
Debug.
Definition: coap_debug.h:57
#define COAP_PDU_DELAYED
#define COAP_MAX_MESSAGE_SIZE_TCP8
#define COAP_DEFAULT_MAX_PDU_RX_SIZE
#define COAP_MAX_MESSAGE_SIZE_TCP0
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:1125
#define COAP_MAX_MESSAGE_SIZE_TCP16
#define COAP_DEFAULT_PORT
Definition: pdu.h:33
void coap_delete_pdu(coap_pdu_t *pdu)
Dispose of an CoAP PDU and frees associated storage.
Definition: pdu.c:140
int coap_mid_t
coap_mid_t is used to store the CoAP Message ID of a CoAP PDU.
Definition: pdu.h:229
coap_proto_t
CoAP protocol types.
Definition: pdu.h:278
#define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER
Definition: pdu.h:176
size_t coap_add_option(coap_pdu_t *pdu, coap_option_num_t number, size_t len, const uint8_t *data)
Adds option of given number to pdu that is passed as first parameter.
Definition: pdu.c:541
#define COAPS_DEFAULT_PORT
Definition: pdu.h:34
#define COAP_INVALID_MID
Indicates an invalid message id.
Definition: pdu.h:232
#define COAP_DEFAULT_MTU
Definition: pdu.h:37
coap_pdu_t * coap_pdu_init(coap_pdu_type_t type, coap_pdu_code_t code, coap_mid_t mid, size_t size)
Creates a new CoAP PDU with at least enough storage space for the given size maximum message size.
Definition: pdu.c:85
#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE
Definition: pdu.h:175
@ COAP_PROTO_DTLS
Definition: pdu.h:281
@ COAP_PROTO_UDP
Definition: pdu.h:280
@ COAP_PROTO_NONE
Definition: pdu.h:279
@ COAP_PROTO_TLS
Definition: pdu.h:283
@ COAP_PROTO_TCP
Definition: pdu.h:282
@ COAP_SIGNALING_CODE_CSM
Definition: pdu.h:329
@ COAP_SIGNALING_CODE_PING
Definition: pdu.h:330
@ COAP_MESSAGE_NON
Definition: pdu.h:56
@ COAP_MESSAGE_CON
Definition: pdu.h:55
coap_session_t * coap_endpoint_get_session(coap_endpoint_t *endpoint, const coap_packet_t *packet, coap_tick_t now)
Lookup the server session for the packet received on an endpoint, or create a new one.
Definition: coap_session.c:552
ssize_t coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node)
Definition: coap_session.c:310
int coap_session_refresh_psk_hint(coap_session_t *session, const coap_bin_const_t *psk_hint)
Refresh the session's current Identity Hint (PSK).
Definition: coap_session.c:994
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:349
coap_session_t * coap_new_server_session(coap_context_t *ctx, coap_endpoint_t *ep)
Creates a new server session for the specified endpoint.
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:275
int coap_session_refresh_psk_key(coap_session_t *session, const coap_bin_const_t *psk_key)
Refresh the session's current pre-shared key (PSK).
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
Definition: coap_session.c:397
ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu)
Send a pdu according to the session's protocol.
Definition: net.c:764
void coap_session_free(coap_session_t *session)
Definition: coap_session.c:223
void coap_session_mfree(coap_session_t *session)
Definition: coap_session.c:157
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:296
void * coap_session_get_tls(const coap_session_t *session, coap_tls_library_t *tls_lib)
Get the session TLS security ptr (TLS type dependent)
coap_session_type_t
coap_session_type_t values
Definition: coap_session.h:39
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:102
void coap_free_endpoint(coap_endpoint_t *ep)
const coap_address_t * coap_session_get_addr_local(const coap_session_t *session)
Get the local IP address from the session.
void coap_session_set_mtu(coap_session_t *session, unsigned mtu)
Set the session MTU.
Definition: coap_session.c:263
const coap_bin_const_t * coap_session_get_psk_key(const coap_session_t *session)
Get the session's current pre-shared key (PSK).
coap_proto_t coap_session_get_proto(const coap_session_t *session)
Get the session protocol type.
coap_context_t * coap_session_get_context(const coap_session_t *session)
Get the session context.
size_t coap_session_max_pdu_size(const coap_session_t *session)
Get maximum acceptable PDU size.
Definition: coap_session.c:242
coap_session_state_t coap_session_get_state(const coap_session_t *session)
Get the session state.
coap_session_state_t
coap_session_state_t values
Definition: coap_session.h:50
coap_session_t * coap_new_client_session_psk(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:911
#define COAP_PROTO_NOT_RELIABLE(p)
Definition: coap_session.h:33
coap_session_t * coap_session_reference(coap_session_t *session)
Increment reference counter on a session.
Definition: coap_session.c:68
coap_session_t * coap_new_client_session(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:896
void coap_session_init_token(coap_session_t *session, size_t len, const uint8_t *data)
Initializes the token value to use as a starting point.
#define COAP_PROTO_RELIABLE(p)
Definition: coap_session.h:34
void coap_session_new_token(coap_session_t *session, size_t *len, uint8_t *data)
Creates a new token for use.
void coap_session_set_app_data(coap_session_t *session, void *app_data)
Stores data with the given session.
Definition: coap_session.c:96
void coap_session_release(coap_session_t *session)
Decrement reference counter on a session.
Definition: coap_session.c:74
coap_session_t * coap_new_client_session_pki(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.
void coap_endpoint_set_default_mtu(coap_endpoint_t *ep, unsigned mtu)
Set the endpoint's default MTU.
const coap_address_t * coap_session_get_addr_remote(const coap_session_t *session)
Get the remote IP address from the session.
const coap_bin_const_t * coap_session_get_psk_hint(const coap_session_t *session)
Get the server session's current Identity Hint (PSK).
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.
int coap_session_set_type_client(coap_session_t *session)
Set the session type to client.
coap_session_t * coap_new_client_session_psk2(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_cpsk_t *setup_data)
Creates a new client session to the designated server with PSK credentials.
Definition: coap_session.c:938
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
Definition: coap_session.c:454
int coap_session_get_ifindex(const coap_session_t *session)
Get the session if index.
coap_session_type_t coap_session_get_type(const coap_session_t *session)
Get the session type.
@ COAP_SESSION_TYPE_HELLO
server-side ephemeral session for responding to a client hello
Definition: coap_session.h:43
@ COAP_SESSION_TYPE_SERVER
server-side
Definition: coap_session.h:42
@ COAP_SESSION_TYPE_CLIENT
client-side
Definition: coap_session.h:41
@ COAP_SESSION_STATE_HANDSHAKE
Definition: coap_session.h:53
@ COAP_SESSION_STATE_CSM
Definition: coap_session.h:54
@ COAP_SESSION_STATE_ESTABLISHED
Definition: coap_session.h:55
@ COAP_SESSION_STATE_NONE
Definition: coap_session.h:51
@ COAP_SESSION_STATE_CONNECTING
Definition: coap_session.h:52
void coap_delete_bin_const(coap_bin_const_t *s)
Deletes the given const binary data and releases any memory allocated.
Definition: str.c:102
#define coap_binary_equal(binary1, binary2)
Compares the two binary data for equality.
Definition: str.h:195
coap_bin_const_t * coap_new_bin_const(const uint8_t *data, size_t size)
Take the specified byte array (text) and create a coap_bin_const_t * Returns a new const binary objec...
Definition: str.c:93
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:830
int coap_socket_bind_tcp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Create a new TCP socket and then listen for new incoming TCP sessions.
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)
Create a new TCP socket and initiate the connection.
int coap_socket_accept_tcp(coap_socket_t *server, coap_socket_t *new_client, coap_address_t *local_addr, coap_address_t *remote_addr)
Accept a new incoming TCP session.
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.
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:103
@ COAP_SESSION
Definition: mem.h:44
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
Only used for servers for hashing incoming packets.
uint16_t lport
local port
coap_address_t remote
remote address and port
coap_proto_t proto
CoAP protocol.
coap_address_t remote
remote address and port
Definition: coap_io.h:49
coap_address_t local
local address and port
Definition: coap_io.h:50
multi-purpose address abstraction
Definition: address.h:94
CoAP binary data definition with const data.
Definition: str.h:56
size_t length
length of binary data
Definition: str.h:57
const uint8_t * s
read-only binary data
Definition: str.h:58
coap_session_t * session
The CoAP stack's global state is stored in a coap_context_t object.
coap_session_t * sessions
client sessions
coap_nack_handler_t nack_handler
unsigned int max_handshake_sessions
Maximum number of simultaneous negotating sessions per endpoint.
coap_queue_t * sendqueue
coap_cache_entry_t * cache
CoAP cache-entry cache.
coap_endpoint_t * endpoint
the endpoints used for listening
uint8_t block_mode
Zero or more COAP_BLOCK_ or'd options.
unsigned int max_idle_sessions
Maximum number of simultaneous unused sessions per endpoint.
coap_bin_const_t key
Definition: coap_dtls.h:307
coap_bin_const_t identity
Definition: coap_dtls.h:306
The structure used for defining the Client PSK setup data to be used.
Definition: coap_dtls.h:336
coap_dtls_cpsk_info_t psk_info
Client PSK definition.
Definition: coap_dtls.h:365
The structure used for defining the PKI setup data to be used.
Definition: coap_dtls.h:242
uint8_t version
Definition: coap_dtls.h:243
Abstraction of virtual endpoint that can be attached to coap_context_t.
coap_context_t * context
endpoint's context
uint16_t default_mtu
default mtu for this interface
coap_session_t * sessions
hash table or list of active sessions
coap_address_t bind_addr
local interface address
coap_socket_t sock
socket object for the interface, if any
coap_proto_t proto
protocol used on this interface
Abstraction of a fixed point number that can be used where necessary instead of a float.
Definition: coap_session.h:27
uint16_t fractional_part
Fractional part of fixed point variable 1/1000 (3 points) precision.
Definition: coap_session.h:29
uint16_t integer_part
Integer part of fixed point variable.
Definition: coap_session.h:28
Structure to hold large body (many blocks) client receive information.
coap_binary_t * app_token
app requesting PDU token
uint8_t observe_set
Set if this is an observe receive PDU.
Structure to hold large body (many blocks) server receive information.
Structure to hold large body (many blocks) transmission information.
size_t length
length of payload
coap_addr_tuple_t addr_info
local and remote addresses
unsigned char payload[COAP_RXBUFFER_SIZE]
payload
int ifindex
the interface index
structure for CoAP PDUs token, if any, follows the fixed size header, then options until payload mark...
uint8_t hdr_size
actual size used for protocol-specific header
coap_mid_t mid
message id, if any, in regular host byte order
size_t used_size
used bytes of storage for token, options and payload
coap_pdu_type_t type
message type
Queue entry.
coap_session_t * session
the CoAP session
coap_pdu_t * pdu
the CoAP PDU to send
unsigned int timeout
the randomized timeout value
struct coap_queue_t * next
coap_mid_t id
CoAP message id.
coap_tick_t t
when to send PDU for the next time
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
coap_lg_xmit_t * lg_xmit
list of large transmissions
coap_bin_const_t * psk_key
If client, this field contains the current pre-shared key for server; When this field is NULL,...
coap_endpoint_t * endpoint
session's endpoint
coap_socket_t sock
socket object for the session, if any
unsigned int max_retransmit
maximum re-transmit count (default 4)
coap_pdu_t * partial_pdu
incomplete incoming pdu
coap_bin_const_t * psk_identity
If client, this field contains the current identity for server; When this field is NULL,...
coap_session_state_t state
current state of relationaship with peer
uint64_t tx_token
Next token number to use.
uint8_t block_mode
Zero or more COAP_BLOCK_ or'd options.
coap_addr_tuple_t addr_info
key: remote/local address info
coap_proto_t proto
protocol used
uint16_t tx_mid
the last message id that was used in this session
coap_bin_const_t * psk_hint
If client, this field contains the server provided identity hint.
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
size_t mtu
path or CSM mtu
size_t partial_read
if > 0 indicates number of bytes already read for an incoming message
int dtls_event
Tracking any (D)TLS events on this sesison.
void * tls
security parameters
coap_fixed_point_t ack_random_factor
ack random factor backoff (default 1.5)
uint8_t con_active
Active CON request sent.
coap_queue_t * delayqueue
list of delayed messages waiting to be sent
size_t tls_overhead
overhead of TLS layer
void * app
application-specific data
coap_mid_t last_ping_mid
the last keepalive message id that was used in this session
coap_lg_srcv_t * lg_srcv
Server list of expected large receives.
coap_lg_crcv_t * lg_crcv
Client list of expected large receives.
coap_fixed_point_t ack_timeout
timeout waiting for ack (default 2 secs)
coap_session_type_t type
client or server side socket
coap_context_t * context
session's context
size_t partial_write
if > 0 indicates number of bytes already written from the pdu at the head of sendqueue
coap_addr_hash_t addr_hash
Address hash for server incoming packets.
int ifindex
interface index
coap_session_t * session
coap_endpoint_t * endpoint
coap_socket_flags_t flags