Skip to content
This repository
Browse code

Shared cache: add callback and function to receive/send cache updates

from/to a remote host
Note: Send call back provide encoded session into an aligned buffer
      large enougth to add a footer and send it directly to a peer
      using a sendto
  • Loading branch information...
commit 1de11737909092a9d255c8f09157bbcf652aed8a 1 parent 7b0cfa1
emeric authored Emeric committed

Showing 2 changed files with 101 additions and 6 deletions. Show diff stats Hide diff stats

  1. +68 6 shctx.c
  2. +33 0 shctx.h
74 shctx.c
@@ -18,13 +18,10 @@
18 18 #include "ebtree/ebmbtree.h"
19 19 #include "shctx.h"
20 20
21   -#ifndef SHSESS_MAX_DATA_LEN
22   -#define SHSESS_MAX_DATA_LEN 512
23   -#endif
24   -
25 21 struct shared_session {
26 22 struct ebmb_node key;
27 23 unsigned char key_data[SSL_MAX_SSL_SESSION_ID_LENGTH];
  24 + long c_date;
28 25 int data_len;
29 26 unsigned char data[SHSESS_MAX_DATA_LEN];
30 27 struct shared_session *p;
@@ -45,6 +42,9 @@ struct shared_context {
45 42 /* Static shared context */
46 43 static struct shared_context *shctx = NULL;
47 44
  45 +/* Callbacks */
  46 +static void (*shared_session_new_cbk)(unsigned char *session, unsigned int session_len, long cdate);
  47 +
48 48
49 49 /* Lock functions */
50 50 #ifdef USE_SYSCALL_FUTEX
@@ -166,8 +166,9 @@ static inline void shared_context_unlock(void)
166 166 int shctx_new_cb(SSL *ssl, SSL_SESSION *sess) {
167 167 (void)ssl;
168 168 struct shared_session *shsess;
169   - unsigned char data[SHSESS_MAX_DATA_LEN],*p;
  169 + unsigned char *data,*p;
170 170 unsigned int data_len;
  171 + unsigned char encsess[SHSESS_MAX_ENCODED_LEN];
171 172
172 173 /* check if session reserved size in aligned buffer is large enougth for the ASN1 encode session */
173 174 data_len=i2d_SSL_SESSION(sess, NULL);
@@ -175,7 +176,7 @@ int shctx_new_cb(SSL *ssl, SSL_SESSION *sess) {
175 176 return 1;
176 177
177 178 /* process ASN1 session encoding before the lock: lower cost */
178   - p = data;
  179 + p = data = encsess+SSL_MAX_SSL_SESSION_ID_LENGTH;
179 180 i2d_SSL_SESSION(sess, &p);
180 181
181 182 shared_context_lock();
@@ -193,10 +194,23 @@ int shctx_new_cb(SSL *ssl, SSL_SESSION *sess) {
193 194 shsess->data_len = data_len;
194 195 memcpy(shsess->data, data, data_len);
195 196
  197 + /* store creation date */
  198 + shsess->c_date = SSL_SESSION_get_time(sess);
  199 +
196 200 shsess_set_active(shsess);
197 201
198 202 shared_context_unlock();
199 203
  204 + if (shared_session_new_cbk) { /* if user level callback is set */
  205 +
  206 + /* copy sessionid padded with 0 into the sessionid + data aligned buffer */
  207 + memcpy(encsess, sess->session_id, sess->session_id_length);
  208 + if (sess->session_id_length < SSL_MAX_SSL_SESSION_ID_LENGTH)
  209 + memset(encsess+sess->session_id_length, 0, SSL_MAX_SSL_SESSION_ID_LENGTH-sess->session_id_length);
  210 +
  211 + shared_session_new_cbk(encsess, SSL_MAX_SSL_SESSION_ID_LENGTH+data_len, SSL_SESSION_get_time(sess));
  212 + }
  213 +
200 214 return 0; /* do not increment session reference count */
201 215 }
202 216
@@ -207,6 +221,7 @@ SSL_SESSION *shctx_get_cb(SSL *ssl, unsigned char *key, int key_len, int *do_cop
207 221 unsigned char data[SHSESS_MAX_DATA_LEN], *p;
208 222 unsigned char tmpkey[SSL_MAX_SSL_SESSION_ID_LENGTH];
209 223 unsigned int data_len;
  224 + long cdate;
210 225 SSL_SESSION *sess;
211 226
212 227 /* allow the session to be freed automatically by openssl */
@@ -230,6 +245,9 @@ SSL_SESSION *shctx_get_cb(SSL *ssl, unsigned char *key, int key_len, int *do_cop
230 245 return NULL;
231 246 }
232 247
  248 + /* backup creation date to reset in session after ASN1 decode */
  249 + cdate = shsess->c_date;
  250 +
233 251 /* copy ASN1 session data to decode outside the lock */
234 252 data_len = shsess->data_len;
235 253 memcpy(data, shsess->data, shsess->data_len);
@@ -242,6 +260,10 @@ SSL_SESSION *shctx_get_cb(SSL *ssl, unsigned char *key, int key_len, int *do_cop
242 260 p = data;
243 261 sess = d2i_SSL_SESSION(NULL, (const unsigned char **)&p, data_len);
244 262
  263 + /* reset creation date */
  264 + if (sess)
  265 + SSL_SESSION_set_time(sess, cdate);
  266 +
245 267 return sess;
246 268 }
247 269
@@ -271,6 +293,46 @@ void shctx_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) {
271 293 shared_context_unlock();
272 294 }
273 295
  296 +/* User level function called to add a session to the cache (remote updates) */
  297 +void shctx_sess_add(const unsigned char *encsess, unsigned int len, long cdate) {
  298 + struct shared_session *shsess;
  299 +
  300 + /* check buffer is at least padded key long + 1 byte
  301 + and data_len not too long */
  302 + if ( (len <= SSL_MAX_SSL_SESSION_ID_LENGTH)
  303 + || (len > SHSESS_MAX_DATA_LEN+SSL_MAX_SSL_SESSION_ID_LENGTH) )
  304 + return;
  305 +
  306 +
  307 + shared_context_lock();
  308 +
  309 + shsess = shsess_get_next();
  310 +
  311 + shsess_tree_delete(shsess);
  312 +
  313 + shsess_set_key(shsess, encsess, SSL_MAX_SSL_SESSION_ID_LENGTH);
  314 +
  315 + /* it returns the already existing node or current node if none, never returns null */
  316 + shsess = shsess_tree_insert(shsess);
  317 +
  318 + /* store into cache and update earlier on session get events */
  319 + if (cdate)
  320 + shsess->c_date = (long)cdate;
  321 +
  322 + /* copy ASN1 session data into cache */
  323 + shsess->data_len = len-SSL_MAX_SSL_SESSION_ID_LENGTH;
  324 + memcpy(shsess->data, encsess+SSL_MAX_SSL_SESSION_ID_LENGTH, shsess->data_len);
  325 +
  326 + shsess_set_active(shsess);
  327 +
  328 + shared_context_unlock();
  329 +}
  330 +
  331 +/* Function used to set a callback on new session creation */
  332 +void shsess_set_new_cbk(void (*func)(unsigned char *, unsigned int, long)) {
  333 + shared_session_new_cbk = func;
  334 +}
  335 +
274 336 /* Init shared memory context if not allocated and set SSL context callbacks
275 337 * size is the max number of stored session
276 338 * Returns: -1 on alloc failure, size if performs context alloc, and 0 if just perform
33 shctx.h
@@ -10,6 +10,39 @@
10 10 #ifndef SHCTX_H
11 11 #define SHCTX_H
12 12 #include <openssl/ssl.h>
  13 +#include <stdint.h>
  14 +
  15 +#ifndef SHSESS_MAX_FOOTER_LEN
  16 +#define SHSESS_MAX_FOOTER_LEN sizeof(uint32_t) \
  17 + + EVP_MAX_MD_SIZE
  18 +#endif
  19 +
  20 +#ifndef SHSESS_MAX_DATA_LEN
  21 +#define SHSESS_MAX_DATA_LEN 512
  22 +#endif
  23 +
  24 +#define SHSESS_MAX_ENCODED_LEN SSL_MAX_SSL_SESSION_ID_LENGTH \
  25 + + SHSESS_MAX_DATA_LEN \
  26 + + SHSESS_MAX_FOOTER_LEN
  27 +
  28 +
  29 +/* Callback called on a new session event:
  30 + * session contains the sessionid zeros padded to SSL_MAX_SSL_SESSION_ID_LENGTH
  31 + * followed by ASN1 session encoding.
  32 + * len is set to SSL_MAX_SSL_SESSION_ID_LENGTH + ASN1 session length
  33 + * len is always less than SSL_MAX_SSL_SESSION_ID_LENGTH + SHSESS_MAX_DATA_LEN.
  34 + * Remaining Bytes from len to SHSESS_MAX_ENCODED_LEN can be used to add a footer.
  35 + * cdate is the creation date timestamp.
  36 + */
  37 +void shsess_set_new_cbk(void (*func)(unsigned char *session, unsigned int len, long cdate));
  38 +
  39 +/* Add a session into the cache,
  40 + * session contains the sessionid zeros padded to SSL_MAX_SSL_SESSION_ID_LENGTH
  41 + * followed by ASN1 session encoding.
  42 + * len is set to SSL_MAX_SSL_SESSION_ID_LENGTH + ASN1 data length.
  43 + * if len greater than SHSESS_MAX_ENCODED_LEN, session is not added.
  44 + * if cdate not 0, on get events session creation date will be reset to cdate */
  45 +void shctx_sess_add(const unsigned char *session, unsigned int session_len, long cdate);
13 46
14 47 /* Init shared memory context if not allocated and set SSL context callbacks
15 48 * size is the max number of stored session

0 comments on commit 1de1173

Please sign in to comment.
Something went wrong with that request. Please try again.