• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * coap_session_internal.h -- Structures, Enums & Functions that are not
3  * exposed to application programming
4  *
5  * Copyright (C) 2010-2019 Olaf Bergmann <bergmann@tzi.org>
6  *
7  * SPDX-License-Identifier: BSD-2-Clause
8  *
9  * This file is part of the CoAP library libcoap. Please see README for terms
10  * of use.
11  */
12 
13 /**
14  * @file coap_session_internal.h
15  * @brief COAP session internal information
16  */
17 
18 #ifndef COAP_SESSION_INTERNAL_H_
19 #define COAP_SESSION_INTERNAL_H_
20 
21 #include "coap_io_internal.h"
22 
23 #define COAP_DEFAULT_SESSION_TIMEOUT 300
24 #define COAP_PARTIAL_SESSION_TIMEOUT_TICKS (30 * COAP_TICKS_PER_SECOND)
25 #define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS 100
26 
27 /**
28  * @defgroup session_internal Sessions (Internal)
29  * CoAP Session Structures, Enums and Functions that are not exposed to
30  * applications
31  * @{
32  */
33 
34 /**
35  * Only used for servers for hashing incoming packets. Cannot have local IP
36  * address as this may be an initial multicast and subsequent unicast address
37  */
38 struct coap_addr_hash_t {
39   coap_address_t remote;       /**< remote address and port */
40   uint16_t lport;              /**< local port */
41   coap_proto_t proto;          /**< CoAP protocol */
42 };
43 
44 /**
45  * Abstraction of virtual session that can be attached to coap_context_t
46  * (client) or coap_endpoint_t (server).
47  */
48 struct coap_session_t {
49   coap_proto_t proto;               /**< protocol used */
50   coap_session_type_t type;         /**< client or server side socket */
51   coap_session_state_t state;       /**< current state of relationaship with
52                                          peer */
53   unsigned ref;                     /**< reference count from queues */
54   size_t tls_overhead;              /**< overhead of TLS layer */
55   size_t mtu;                       /**< path or CSM mtu */
56   coap_addr_hash_t addr_hash;  /**< Address hash for server incoming packets */
57   UT_hash_handle hh;
58   coap_addr_tuple_t addr_info;      /**< key: remote/local address info */
59   int ifindex;                      /**< interface index */
60   coap_socket_t sock;               /**< socket object for the session, if
61                                          any */
62   coap_endpoint_t *endpoint;        /**< session's endpoint */
63   coap_context_t *context;          /**< session's context */
64   void *tls;                        /**< security parameters */
65   uint16_t tx_mid;                  /**< the last message id that was used in
66                                          this session */
67   uint8_t con_active;               /**< Active CON request sent */
68   uint8_t csm_block_supported;      /**< CSM TCP blocks supported */
69   coap_mid_t last_ping_mid;         /**< the last keepalive message id that was
70                                          used in this session */
71   coap_queue_t *delayqueue;         /**< list of delayed messages waiting to
72                                          be sent */
73   coap_lg_xmit_t *lg_xmit;          /**< list of large transmissions */
74   coap_lg_crcv_t *lg_crcv;       /**< Client list of expected large receives */
75   coap_lg_srcv_t *lg_srcv;       /**< Server list of expected large receives */
76   size_t partial_write;             /**< if > 0 indicates number of bytes
77                                          already written from the pdu at the
78                                          head of sendqueue */
79   uint8_t read_header[8];           /**< storage space for header of incoming
80                                          message header */
81   size_t partial_read;              /**< if > 0 indicates number of bytes
82                                          already read for an incoming message */
83   coap_pdu_t *partial_pdu;          /**< incomplete incoming pdu */
84   coap_tick_t last_rx_tx;
85   coap_tick_t last_tx_rst;
86   coap_tick_t last_ping;
87   coap_tick_t last_pong;
88   coap_tick_t csm_tx;
89   coap_dtls_cpsk_t cpsk_setup_data; /**< client provided PSK initial setup
90                                          data */
91   coap_bin_const_t *psk_identity;   /**< If client, this field contains the
92                                       current identity for server; When this
93                                       field is NULL, the current identity is
94                                       contained in cpsk_setup_data
95 
96                                       If server, this field contains the client
97                                       provided identity.
98 
99                                       Value maintained internally */
100   coap_bin_const_t *psk_key;        /**< If client, this field contains the
101                                       current pre-shared key for server;
102                                       When this field is NULL, the current
103                                       key is contained in cpsk_setup_data
104 
105                                       If server, this field contains the
106                                       client's current key.
107 
108                                       Value maintained internally */
109   coap_bin_const_t *psk_hint;       /**< If client, this field contains the
110                                       server provided identity hint.
111 
112                                       If server, this field contains the
113                                       current hint for the client; When this
114                                       field is NULL, the current hint is
115                                       contained in context->spsk_setup_data
116 
117                                       Value maintained internally */
118   void *app;                        /**< application-specific data */
119   unsigned int max_retransmit;      /**< maximum re-transmit count (default
120                                          4) */
121   coap_fixed_point_t ack_timeout;   /**< timeout waiting for ack (default 2
122                                          secs) */
123   coap_fixed_point_t ack_random_factor; /**< ack random factor backoff (default
124                                              1.5) */
125   unsigned int dtls_timeout_count;      /**< dtls setup retry counter */
126   int dtls_event;                       /**< Tracking any (D)TLS events on this
127                                              sesison */
128   uint8_t block_mode;             /**< Zero or more COAP_BLOCK_ or'd options */
129   uint64_t tx_token;              /**< Next token number to use */
130 };
131 
132 /**
133  * Abstraction of virtual endpoint that can be attached to coap_context_t. The
134  * keys (port, bind_addr) must uniquely identify this endpoint.
135  */
136 struct coap_endpoint_t {
137   struct coap_endpoint_t *next;
138   coap_context_t *context;        /**< endpoint's context */
139   coap_proto_t proto;             /**< protocol used on this interface */
140   uint16_t default_mtu;           /**< default mtu for this interface */
141   coap_socket_t sock;             /**< socket object for the interface, if
142                                        any */
143   coap_address_t bind_addr;       /**< local interface address */
144   coap_session_t *sessions;       /**< hash table or list of active sessions */
145 };
146 
147 /**
148  * Notify session transport has just connected and CSM exchange can now start.
149  *
150  * @param session The CoAP session.
151  */
152 void coap_session_send_csm(coap_session_t *session);
153 
154 /**
155  * Notify session that it has just connected or reconnected.
156  *
157  * @param session The CoAP session.
158  */
159 void coap_session_connected(coap_session_t *session);
160 
161 /**
162  * Refresh the session's current Identity Hint (PSK).
163  * Note: A copy of @p psk_hint is maintained in the session by libcoap.
164  *
165  * @param session  The current coap_session_t object.
166  * @param psk_hint If NULL, the Identity Hint will revert to the
167  *                 initial Identity Hint used at session setup.
168  *
169  * @return @c 1 if successful, else @c 0.
170  */
171 int coap_session_refresh_psk_hint(coap_session_t *session,
172                                   const coap_bin_const_t *psk_hint);
173 
174 /**
175  * Refresh the session's current pre-shared key (PSK).
176  * Note: A copy of @p psk_key is maintained in the session by libcoap.
177  *
178  * @param session  The current coap_session_t object.
179  * @param psk_key  If NULL, the pre-shared key will revert to the
180  *                 initial pre-shared key used as session setup.
181  *
182  * @return @c 1 if successful, else @c 0.
183  */
184 int coap_session_refresh_psk_key(coap_session_t *session,
185                                  const coap_bin_const_t *psk_key);
186 
187 /**
188  * Creates a new server session for the specified endpoint.
189  * @param ctx The CoAP context.
190  * @param ep An endpoint where an incoming connection request is pending.
191  *
192  * @return A new CoAP session or NULL if failed. Call coap_session_release to
193  * add to unused queue.
194  */
195 coap_session_t *coap_new_server_session(
196   coap_context_t *ctx,
197   coap_endpoint_t *ep
198 );
199 
200 /**
201  * Function interface for datagram data transmission. This function returns
202  * the number of bytes that have been transmitted, or a value less than zero
203  * on error.
204  *
205  * @param session          Session to send data on.
206  * @param data             The data to send.
207  * @param datalen          The actual length of @p data.
208  *
209  * @return                 The number of bytes written on success, or a value
210  *                         less than zero on error.
211  */
212 ssize_t coap_session_send(coap_session_t *session,
213   const uint8_t *data, size_t datalen);
214 
215 /**
216  * Function interface for stream data transmission. This function returns
217  * the number of bytes that have been transmitted, or a value less than zero
218  * on error. The number of bytes written may be less than datalen because of
219  * congestion control.
220  *
221  * @param session          Session to send data on.
222  * @param data             The data to send.
223  * @param datalen          The actual length of @p data.
224  *
225  * @return                 The number of bytes written on success, or a value
226  *                         less than zero on error.
227  */
228 ssize_t coap_session_write(coap_session_t *session,
229   const uint8_t *data, size_t datalen);
230 
231 /**
232  * Send a pdu according to the session's protocol. This function returns
233  * the number of bytes that have been transmitted, or a value less than zero
234  * on error.
235  *
236  * @param session          Session to send pdu on.
237  * @param pdu              The pdu to send.
238  *
239  * @return                 The number of bytes written on success, or a value
240  *                         less than zero on error.
241  */
242 ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu);
243 
244 ssize_t
245 coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu,
246                        coap_queue_t *node);
247 
248 /**
249  * Lookup the server session for the packet received on an endpoint, or create
250  * a new one.
251  *
252  * @param endpoint Active endpoint the packet was received on.
253  * @param packet Received packet.
254  * @param now The current time in ticks.
255  * @return The CoAP session or @c NULL if error.
256  */
257 coap_session_t *coap_endpoint_get_session(coap_endpoint_t *endpoint,
258   const coap_packet_t *packet, coap_tick_t now);
259 
260 /**
261  * Create a new DTLS session for the @p session.
262  * Note: the @p session is released if no DTLS server session can be created.
263  *
264  * @ingroup dtls_internal
265  *
266  * @param session   Session to add DTLS session to
267  * @param now       The current time in ticks.
268  *
269  * @return CoAP session or @c NULL if error.
270  */
271 coap_session_t *coap_session_new_dtls_session(coap_session_t *session,
272   coap_tick_t now);
273 
274 void coap_session_free(coap_session_t *session);
275 void coap_session_mfree(coap_session_t *session);
276 
277 /** @} */
278 
279 #define SESSIONS_ADD(e, obj) \
280   HASH_ADD(hh, (e), addr_hash, sizeof((obj)->addr_hash), (obj))
281 
282 #define SESSIONS_DELETE(e, obj) \
283   HASH_DELETE(hh, (e), (obj))
284 
285 #define SESSIONS_ITER(e, el, rtmp)  \
286   HASH_ITER(hh, (e), el, rtmp)
287 
288 #define SESSIONS_ITER_SAFE(e, el, rtmp) \
289 for ((el) = (e); (el) && ((rtmp) = (el)->hh.next, 1); (el) = (rtmp))
290 
291 #define SESSIONS_FIND(e, k, res) {                     \
292     HASH_FIND(hh, (e), &(k), sizeof(k), (res)); \
293   }
294 
295 #endif /* COAP_SESSION_INTERNAL_H_ */
296