/*
 * shctx.c - shared context management functions for SSL
 *
 * Copyright (C) 2011-2012 EXCELIANCE
 *
 * Author: Emeric Brun - emeric@exceliance.fr
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <sys/mman.h>
#ifndef USE_PRIVATE_CACHE
#ifdef USE_SYSCALL_FUTEX
#include <unistd.h>
#ifndef u32
#define u32 unsigned int
#endif
#include <linux/futex.h>
#include <sys/syscall.h>
#else /* USE_SYSCALL_FUTEX */
#include <pthread.h>
#endif /* USE_SYSCALL_FUTEX */
#endif
#include <arpa/inet.h>
#include "ebmbtree.h"
#include "proto/shctx.h"

struct shsess_packet_hdr {
	unsigned int eol;
	unsigned char final:1;
	unsigned char seq:7;
	unsigned char id[SSL_MAX_SSL_SESSION_ID_LENGTH];
};

struct shsess_packet {
	unsigned char version;
	unsigned char sig[SHA_DIGEST_LENGTH];
	struct shsess_packet_hdr hdr;
	unsigned char data[0];
};

struct shared_session {
	struct ebmb_node key;
	unsigned char key_data[SSL_MAX_SSL_SESSION_ID_LENGTH];
	unsigned char data[SHSESS_BLOCK_MIN_SIZE];
};

struct shared_block {
	union {
		struct shared_session session;
		unsigned char data[sizeof(struct shared_session)];
	} data;
	short int data_len;
	struct shared_block *p;
	struct shared_block *n;
};

struct shared_context {
#ifndef USE_PRIVATE_CACHE
#ifdef USE_SYSCALL_FUTEX
	unsigned int waiters;
#else /* USE_SYSCALL_FUTEX */
	pthread_mutex_t mutex;
#endif
#endif
	struct shsess_packet_hdr upd;
	unsigned char data[SHSESS_MAX_DATA_LEN];
	short int data_len;
	struct shared_block active;
	struct shared_block free;
};

/* Static shared context */
static struct shared_context *shctx = NULL;
#ifndef USE_PRIVATE_CACHE
static int use_shared_mem = 0;
#endif

/* Lock functions */
#ifdef USE_PRIVATE_CACHE
#define shared_context_lock()
#define shared_context_unlock()

#else
#ifdef USE_SYSCALL_FUTEX
#if defined (__i486__) || defined (__i586__) || defined (__i686__) || defined (__x86_64__)
static inline unsigned int xchg(unsigned int *ptr, unsigned int x)
{
	__asm volatile("lock xchgl %0,%1"
		     : "=r" (x), "+m" (*ptr)
		     : "0" (x)
		     : "memory");
	return x;
}

static inline unsigned int cmpxchg(unsigned int *ptr, unsigned int old, unsigned int new)
{
	unsigned int ret;

	__asm volatile("lock cmpxchgl %2,%1"
		     : "=a" (ret), "+m" (*ptr)
		     : "r" (new), "0" (old)
		     : "memory");
	return ret;
}

static inline unsigned char atomic_dec(unsigned int *ptr)
{
	unsigned char ret;
	__asm volatile("lock decl %0\n"
		     "setne %1\n"
		     : "+m" (*ptr), "=qm" (ret)
		     :
		     : "memory");
	return ret;
}

#else /* if no x86_64 or i586 arch: use less optimized gcc >= 4.1 built-ins */
static inline unsigned int xchg(unsigned int *ptr, unsigned int x)
{
	return __sync_lock_test_and_set(ptr, x);
}

static inline unsigned int cmpxchg(unsigned int *ptr, unsigned int old, unsigned int new)
{
	return __sync_val_compare_and_swap(ptr, old, new);
}

static inline unsigned char atomic_dec(unsigned int *ptr)
{
	return __sync_sub_and_fetch(ptr, 1) ? 1 : 0;
}

#endif

static inline void _shared_context_lock(void)
{
	unsigned int x;

	x = cmpxchg(&shctx->waiters, 0, 1);
	if (x) {
		if (x != 2)
			x = xchg(&shctx->waiters, 2);

		while (x) {
			syscall(SYS_futex, &shctx->waiters, FUTEX_WAIT, 2, NULL, 0, 0);
			x = xchg(&shctx->waiters, 2);
		}
	}
}

static inline void _shared_context_unlock(void)
{
	if (atomic_dec(&shctx->waiters)) {
		shctx->waiters = 0;
		syscall(SYS_futex, &shctx->waiters, FUTEX_WAKE, 1, NULL, 0, 0);
	}
}

#define shared_context_lock()   if (use_shared_mem) _shared_context_lock()

#define shared_context_unlock() if (use_shared_mem) _shared_context_unlock()

#else /* USE_SYSCALL_FUTEX */

#define shared_context_lock()   if (use_shared_mem) pthread_mutex_lock(&shctx->mutex)

#define shared_context_unlock() if (use_shared_mem) pthread_mutex_unlock(&shctx->mutex)

#endif
#endif

/* List Macros */

#define shblock_unset(s)	(s)->n->p = (s)->p; \
				(s)->p->n = (s)->n;

#define shblock_set_free(s)	shblock_unset(s) \
				(s)->n = &shctx->free; \
				(s)->p = shctx->free.p; \
				shctx->free.p->n = s; \
				shctx->free.p = s;


#define shblock_set_active(s)	shblock_unset(s) \
				(s)->n = &shctx->active; \
				(s)->p = shctx->active.p; \
				shctx->active.p->n = s; \
				shctx->active.p = s;


/* Tree Macros */

#define shsess_tree_delete(s)	ebmb_delete(&(s)->key);

#define shsess_tree_insert(s)	(struct shared_session *)ebmb_insert(&shctx->active.data.session.key.node.branches, \
								     &(s)->key, SSL_MAX_SSL_SESSION_ID_LENGTH);

#define shsess_tree_lookup(k)	(struct shared_session *)ebmb_lookup(&shctx->active.data.session.key.node.branches, \
								     (k), SSL_MAX_SSL_SESSION_ID_LENGTH);

/* shared session functions */

/* Free session blocks, returns number of freed blocks */
static int shsess_free(struct shared_session *shsess)
{
	struct shared_block *block;
	int ret = 1;

	if (((struct shared_block *)shsess)->data_len <= sizeof(shsess->data)) {
		shblock_set_free((struct shared_block *)shsess);
		return ret;
	}
	block = ((struct shared_block *)shsess)->n;
	shblock_set_free((struct shared_block *)shsess);
	while (1) {
		struct shared_block *next;

		if (block->data_len <= sizeof(block->data)) {
			/* last block */
			shblock_set_free(block);
			ret++;
			break;
		}
		next = block->n;
		shblock_set_free(block);
		ret++;
		block = next;
	}
	return ret;
}

/* This function frees enough blocks to store a new session of data_len.
 * Returns a ptr on a free block if it succeeds, or NULL if there are not
 * enough blocks to store that session.
 */
static struct shared_session *shsess_get_next(int data_len)
{
	int head = 0;
	struct shared_block *b;

	b = shctx->free.n;
	while (b != &shctx->free) {
		if (!head) {
			data_len -= sizeof(b->data.session.data);
			head = 1;
		}
		else
			data_len -= sizeof(b->data.data);
		if (data_len <= 0)
			return &shctx->free.n->data.session;
		b = b->n;
	}
	b = shctx->active.n;
	while (b != &shctx->active) {
		int freed;

		shsess_tree_delete(&b->data.session);
		freed = shsess_free(&b->data.session);
		if (!head)
			data_len -= sizeof(b->data.session.data) + (freed-1)*sizeof(b->data.data);
		else
			data_len -= freed*sizeof(b->data.data);
		if (data_len <= 0)
			return &shctx->free.n->data.session;
		b = shctx->active.n;
	}
	return NULL;
}

/* store a session into the cache
 * s_id : session id padded with zero to SSL_MAX_SSL_SESSION_ID_LENGTH
 * data: asn1 encoded session
 * data_len: asn1 encoded session length
 * Returns 1 id session was stored (else 0)
 */
static int shsess_store(unsigned char *s_id, unsigned char *data, int data_len)
{
	struct shared_session *shsess, *oldshsess;

	shsess = shsess_get_next(data_len);
	if (!shsess) {
		/* Could not retrieve enough free blocks to store that session */
		return 0;
	}

	/* prepare key */
	memcpy(shsess->key_data, s_id, SSL_MAX_SSL_SESSION_ID_LENGTH);

	/* it returns the already existing node
           or current node if none, never returns null */
	oldshsess = shsess_tree_insert(shsess);
	if (oldshsess != shsess) {
		/* free all blocks used by old node */
		shsess_free(oldshsess);
		shsess = oldshsess;
	}

	((struct shared_block *)shsess)->data_len = data_len;
	if (data_len <= sizeof(shsess->data)) {
		/* Store on a single block */
		memcpy(shsess->data, data, data_len);
		shblock_set_active((struct shared_block *)shsess);
	}
	else {
		unsigned char *p;
		/* Store on multiple blocks */
		int cur_len;

		memcpy(shsess->data, data, sizeof(shsess->data));
		p = data + sizeof(shsess->data);
		cur_len = data_len - sizeof(shsess->data);
		shblock_set_active((struct shared_block *)shsess);
		while (1) {
			/* Store next data on free block.
			 * shsess_get_next guarantees that there are enough
			 * free blocks in queue.
			 */
			struct shared_block *block;

			block = shctx->free.n;
			if (cur_len <= sizeof(block->data)) {
				/* This is the last block */
				block->data_len = cur_len;
				memcpy(block->data.data, p, cur_len);
				shblock_set_active(block);
				break;
			}
			/* Intermediate block */
			block->data_len = cur_len;
			memcpy(block->data.data, p, sizeof(block->data));
			p += sizeof(block->data.data);
			cur_len -= sizeof(block->data.data);
			shblock_set_active(block);
		}
	}

	return 1;
}


/* SSL context callbacks */

/* SSL callback used on new session creation */
int shctx_new_cb(SSL *ssl, SSL_SESSION *sess)
{
	unsigned char encsess[sizeof(struct shsess_packet)+SHSESS_MAX_DATA_LEN];
	struct shsess_packet *packet = (struct shsess_packet *)encsess;
	unsigned char *p;
	int data_len, sid_length, sid_ctx_length;


	/* Session id is already stored in to key and session id is known
	 * so we dont store it to keep size.
	 */
	sid_length = sess->session_id_length;
	sess->session_id_length = 0;
	sid_ctx_length = sess->sid_ctx_length;
	sess->sid_ctx_length = 0;

	/* check if buffer is large enough for the ASN1 encoded session */
	data_len = i2d_SSL_SESSION(sess, NULL);
	if (data_len > SHSESS_MAX_DATA_LEN)
		goto err;

	/* process ASN1 session encoding before the lock */
	p = packet->data;
	i2d_SSL_SESSION(sess, &p);

	memcpy(packet->hdr.id, sess->session_id, sid_length);
	if (sid_length < SSL_MAX_SSL_SESSION_ID_LENGTH)
		memset(&packet->hdr.id[sid_length], 0, SSL_MAX_SSL_SESSION_ID_LENGTH-sid_length);

	shared_context_lock();

	/* store to cache */
	shsess_store(packet->hdr.id, packet->data, data_len);

	shared_context_unlock();

err:
	/* reset original length values */
	sess->session_id_length = sid_length;
	sess->sid_ctx_length = sid_ctx_length;

	return 0; /* do not increment session reference count */
}

/* SSL callback used on lookup an existing session cause none found in internal cache */
SSL_SESSION *shctx_get_cb(SSL *ssl, unsigned char *key, int key_len, int *do_copy)
{
	struct shared_session *shsess;
	unsigned char data[SHSESS_MAX_DATA_LEN], *p;
	unsigned char tmpkey[SSL_MAX_SSL_SESSION_ID_LENGTH];
	int data_len;
	SSL_SESSION *sess;

	/* allow the session to be freed automatically by openssl */
	*do_copy = 0;

	/* tree key is zeros padded sessionid */
	if (key_len < SSL_MAX_SSL_SESSION_ID_LENGTH) {
		memcpy(tmpkey, key, key_len);
		memset(tmpkey + key_len, 0, SSL_MAX_SSL_SESSION_ID_LENGTH - key_len);
		key = tmpkey;
	}

	/* lock cache */
	shared_context_lock();

	/* lookup for session */
	shsess = shsess_tree_lookup(key);
	if (!shsess) {
		/* no session found: unlock cache and exit */
		shared_context_unlock();
		return NULL;
	}

	data_len = ((struct shared_block *)shsess)->data_len;
	if (data_len <= sizeof(shsess->data)) {
		/* Session stored on single block */
		memcpy(data, shsess->data, data_len);
		shblock_set_active((struct shared_block *)shsess);
	}
	else {
		/* Session stored on multiple blocks */
		struct shared_block *block;

		memcpy(data, shsess->data, sizeof(shsess->data));
		p = data + sizeof(shsess->data);
		block = ((struct shared_block *)shsess)->n;
		shblock_set_active((struct shared_block *)shsess);
		while (1) {
			/* Retrieve data from next block */
			struct shared_block *next;

			if (block->data_len <= sizeof(block->data.data)) {
				/* This is the last block */
				memcpy(p, block->data.data, block->data_len);
				p += block->data_len;
				shblock_set_active(block);
				break;
			}
			/* Intermediate block */
			memcpy(p, block->data.data, sizeof(block->data.data));
			p += sizeof(block->data.data);
			next = block->n;
			shblock_set_active(block);
			block = next;
		}
	}

	shared_context_unlock();

	/* decode ASN1 session */
	p = data;
	sess = d2i_SSL_SESSION(NULL, (const unsigned char **)&p, data_len);
	/* Reset session id and session id contenxt */
	if (sess) {
		memcpy(sess->session_id, key, key_len);
		sess->session_id_length = key_len;
		memcpy(sess->sid_ctx, (const unsigned char *)SHCTX_APPNAME, strlen(SHCTX_APPNAME));
		sess->sid_ctx_length = ssl->sid_ctx_length;
	}

	return sess;
}

/* SSL callback used to signal session is no more used in internal cache */
void shctx_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
{
	struct shared_session *shsess;
	unsigned char tmpkey[SSL_MAX_SSL_SESSION_ID_LENGTH];
	unsigned char *key = sess->session_id;
	(void)ctx;

	/* tree key is zeros padded sessionid */
	if (sess->session_id_length < SSL_MAX_SSL_SESSION_ID_LENGTH) {
		memcpy(tmpkey, sess->session_id, sess->session_id_length);
		memset(tmpkey+sess->session_id_length, 0, SSL_MAX_SSL_SESSION_ID_LENGTH - sess->session_id_length);
		key = tmpkey;
	}

	shared_context_lock();

	/* lookup for session */
	shsess = shsess_tree_lookup(key);
	if (shsess) {
		/* free session */
		shsess_tree_delete(shsess);
		shsess_free(shsess);
	}

	/* unlock cache */
	shared_context_unlock();
}

/* Allocate shared memory context.
 * <size> is maximum cached sessions.
 * If <size> is set to less or equal to 0, ssl cache is disabled.
 * Returns: -1 on alloc failure, <size> if it performs context alloc,
 * and 0 if cache is already allocated.
 */
int shared_context_init(int size, int shared)
{
	int i;
#ifndef USE_PRIVATE_CACHE
#ifndef USE_SYSCALL_FUTEX
	pthread_mutexattr_t attr;
#endif /* USE_SYSCALL_FUTEX */
#endif
	struct shared_block *prev,*cur;
	int maptype = MAP_PRIVATE;

	if (shctx)
		return 0;

	if (size<=0)
		return 0;

	/* Increate size by one to reserve one node for lookup */
	size++;
#ifndef USE_PRIVATE_CACHE
	if (shared)
		maptype = MAP_SHARED;
#endif

	shctx = (struct shared_context *)mmap(NULL, sizeof(struct shared_context)+(size*sizeof(struct shared_block)),
	                                      PROT_READ | PROT_WRITE, maptype | MAP_ANON, -1, 0);
	if (!shctx || shctx == MAP_FAILED) {
		shctx = NULL;
		return -1;
	}

#ifndef USE_PRIVATE_CACHE
#ifdef USE_SYSCALL_FUTEX
	shctx->waiters = 0;
#else
	pthread_mutexattr_init(&attr);
	pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
	pthread_mutex_init(&shctx->mutex, &attr);
#endif
	if (maptype == MAP_SHARED)
		use_shared_mem = 1;
#endif

	memset(&shctx->active.data.session.key, 0, sizeof(struct ebmb_node));
	memset(&shctx->free.data.session.key, 0, sizeof(struct ebmb_node));

	/* No duplicate authorized in tree: */
	shctx->active.data.session.key.node.branches = EB_ROOT_UNIQUE;

	/* Init remote update cache */
	shctx->upd.eol = 0;
	shctx->upd.seq = 0;
	shctx->data_len = 0;

	cur = &shctx->active;
	cur->n = cur->p = cur;

	cur = &shctx->free;
	for (i = 0 ; i < size ; i++) {
		prev = cur;
		cur = (struct shared_block *)((char *)prev + sizeof(struct shared_block));
		prev->n = cur;
		cur->p = prev;
	}
	cur->n = &shctx->free;
	shctx->free.p = cur;

	return size;
}


/* Set session cache mode to server and disable openssl internal cache.
 * Set shared cache callbacks on an ssl context.
 * Shared context MUST be firstly initialized */
void shared_context_set_cache(SSL_CTX *ctx)
{
	SSL_CTX_set_session_id_context(ctx, (const unsigned char *)SHCTX_APPNAME, strlen(SHCTX_APPNAME));

	if (!shctx) {
		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
		return;
	}

	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER |
	                                    SSL_SESS_CACHE_NO_INTERNAL |
	                                    SSL_SESS_CACHE_NO_AUTO_CLEAR);

	/* Set callbacks */
	SSL_CTX_sess_set_new_cb(ctx, shctx_new_cb);
	SSL_CTX_sess_set_get_cb(ctx, shctx_get_cb);
	SSL_CTX_sess_set_remove_cb(ctx, shctx_remove_cb);
}
