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