/*
 *   stunnel       TLS offloading and load-balancing proxy
 *   Copyright (C) 1998-2015 Michal Trojnara <Michal.Trojnara@mirt.net>
 *
 *   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.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *   See the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this program; if not, see <http://www.gnu.org/licenses>.
 *
 *   Linking stunnel statically or dynamically with other modules is making
 *   a combined work based on stunnel. Thus, the terms and conditions of
 *   the GNU General Public License cover the whole combination.
 *
 *   In addition, as a special exception, the copyright holder of stunnel
 *   gives you permission to combine stunnel with free software programs or
 *   libraries that are released under the GNU LGPL and with code included
 *   in the standard release of OpenSSL under the OpenSSL License (or
 *   modified versions of such code, with unchanged license). You may copy
 *   and distribute such a system following the terms of the GNU GPL for
 *   stunnel and the licenses of the other code concerned.
 *
 *   Note that people who make modified versions of stunnel are not obligated
 *   to grant this special exception for their modified versions; it is their
 *   choice whether to do so. The GNU General Public License gives permission
 *   to release a modified version without this exception; this exception
 *   also makes it possible to release a modified version which carries
 *   forward this exception.
 */

#include "common.h"
#include "prototypes.h"

volatile int tls_initialized=0;

NOEXPORT void tls_platform_init();
NOEXPORT void free_function(void *);

/**************************************** thread local storage */

/* this has to be the first function called from ui_*.c */
void tls_init() {
    tls_platform_init();
    tls_initialized=1;
    ui_tls=tls_alloc(NULL, NULL, "ui");
    CRYPTO_set_mem_ex_functions(str_alloc_detached_debug,
        str_realloc_debug, free_function);
}

/* this has to be the first function called by a new thread */
TLS_DATA *tls_alloc(CLI *c, TLS_DATA *inherited, char *txt) {
    TLS_DATA *tls_data;

    if(inherited) { /* reuse the thread-local storage after fork() */
        tls_data=inherited;
        str_free(tls_data->id);
    } else {
        tls_data=calloc(1, sizeof(TLS_DATA));
        if(!tls_data)
            fatal("Out of memory");
        if(c)
            c->tls=tls_data;
        str_init(tls_data);
        tls_data->c=c;
        tls_data->opt=c?c->opt:&service_options;
    }
    tls_data->id="unconfigured";
    tls_set(tls_data);

    /* str.c functions can be used below this point */
    if(txt) {
        tls_data->id=str_dup(txt);
        str_detach(tls_data->id); /* it is deallocated after str_stats() */
    } else if(c) {
        tls_data->id=log_id(c);
        str_detach(tls_data->id); /* it is deallocated after str_stats() */
    }

    return tls_data;
}

/* per-thread thread-local storage cleanup */
void tls_cleanup() {
    TLS_DATA *tls_data;

    tls_data=tls_get();
    if(!tls_data)
        return;
    str_cleanup(tls_data);
    str_free(tls_data->id); /* detached allocation */
    tls_set(NULL);
    free(tls_data);
}

#ifdef USE_UCONTEXT

static TLS_DATA *global_tls=NULL;

NOEXPORT void tls_platform_init() {
}

void tls_set(TLS_DATA *tls_data) {
    if(ready_head)
        ready_head->tls=tls_data;
    else /* ucontext threads not initialized */
        global_tls=tls_data;
}

TLS_DATA *tls_get() {
    if(ready_head)
        return ready_head->tls;
    else /* ucontext threads not initialized */
        return global_tls;
}

#endif /* USE_UCONTEXT */

#ifdef USE_FORK

static TLS_DATA *global_tls=NULL;

NOEXPORT void tls_platform_init() {
}

void tls_set(TLS_DATA *tls_data) {
    global_tls=tls_data;
}

TLS_DATA *tls_get() {
    return global_tls;
}

#endif /* USE_FORK */

#ifdef USE_PTHREAD

static pthread_key_t pthread_key;

NOEXPORT void tls_platform_init() {
    pthread_key_create(&pthread_key, NULL);
}

void tls_set(TLS_DATA *tls_data) {
    pthread_setspecific(pthread_key, tls_data);
}

TLS_DATA *tls_get() {
    return pthread_getspecific(pthread_key);
}

#endif /* USE_PTHREAD */

#ifdef USE_WIN32

static DWORD tls_index;

NOEXPORT void tls_platform_init() {
    tls_index=TlsAlloc();
}

void tls_set(TLS_DATA *tls_data) {
    TlsSetValue(tls_index, tls_data);
}

TLS_DATA *tls_get() {
    return TlsGetValue(tls_index);
}

#endif /* USE_WIN32 */

/**************************************** OpenSSL allocator hook */

NOEXPORT void free_function(void *ptr) {
    /* CRYPTO_set_mem_ex_functions() needs a function rather than a macro */
    /* unfortunately, OpenSSL provides no file:line information here */
    str_free_debug(ptr, "OpenSSL", 0);
}

/* end of tls.c */
