Commit 6539b8ca authored by Ralf S. Engelschall's avatar Ralf S. Engelschall
Browse files

Kick out all old mutex code and base SSLMutex on APR locks.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89022 13f79535-47bb-0310-9956-ffa450edef68
parent 6e90b2b2
Loading
Loading
Loading
Loading
+9 −78
Original line number Diff line number Diff line
@@ -226,65 +226,6 @@
#define SSL_SESSION_CACHE_TIMEOUT  300
#endif

/*
 * Support for file locking: Try to determine whether we should use fcntl() or
 * flock().  Would be better ap_config.h could provide this... :-(
  */
#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
#define SSL_USE_FCNTL 1
#include <fcntl.h>
#endif
#if defined(USE_FLOCK_SERIALIZED_ACCEPT)
#define SSL_USE_FLOCK 1
#include <sys/file.h>
#endif
#if !defined(SSL_USE_FCNTL) && !defined(SSL_USE_FLOCK)
#define SSL_USE_FLOCK 1
#if !defined(MPE)
#include <sys/file.h>
#endif
#ifndef LOCK_UN
#undef SSL_USE_FLOCK
#define SSL_USE_FCNTL 1
#include <fcntl.h>
#endif
#endif
#ifdef AIX
#undef SSL_USE_FLOCK
#define SSL_USE_FCNTL 1
#include <fcntl.h>
#endif

/*
 * Support for Mutex
 */
#define SSL_MUTEX_LOCK_MODE ( S_IRUSR|S_IWUSR )
#if defined(USE_SYSVSEM_SERIALIZED_ACCEPT) ||\
    (defined(__FreeBSD__) && defined(__FreeBSD_version) &&\
     __FreeBSD_version >= 300000) ||\
    (defined(LINUX) && defined(__GLIBC__) && defined(__GLIBC_MINOR__) &&\
     LINUX >= 2 && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) ||\
    defined(SOLARIS2) || defined(__hpux) ||\
    (defined (__digital__) && defined (__unix__))
#define SSL_CAN_USE_SEM
#define SSL_HAVE_IPCSEM
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/* 
 * Some platforms have a `union semun' pre-defined but Single Unix
 * Specification (SUSv2) says in semctl(2): `If required, it is of
 * type union semun, which the application program must explicitly
 * declare'. So we define it always ourself to avoid problems (but under
 * a different name to avoid a namespace clash).
 */
union ssl_ipc_semun {
    long val;
    struct semid_ds *buf;
    unsigned short int *array;
};
#endif

/*
 * Support for MM library
 */
@@ -430,8 +371,7 @@ typedef enum {
typedef enum {
    SSL_MUTEXMODE_UNSET  = UNSET,
    SSL_MUTEXMODE_NONE   = 0,
    SSL_MUTEXMODE_FILE   = 1,
    SSL_MUTEXMODE_SEM    = 2
    SSL_MUTEXMODE_USED   = 1
} ssl_mutexmode_t;

/*
@@ -488,8 +428,7 @@ typedef struct {
    table_t        *tSessionCacheDataTable;
    ssl_mutexmode_t nMutexMode;
    char           *szMutexFile;
    int             nMutexFD;
    int             nMutexSEMID;
    apr_lock_t     *pMutex;
    array_header   *aRandSeed;
    ssl_ds_table   *tTmpKeys;
    void           *pTmpKeys[SSL_TKPIDX_MAX];
@@ -710,21 +649,13 @@ void ssl_ds_table_wipeout(ssl_ds_table *);
void          ssl_ds_table_kill(ssl_ds_table *);

/*  Mutex Support  */
void         ssl_mutex_init(server_rec *, pool *);
void         ssl_mutex_reinit(server_rec *, pool *);
void         ssl_mutex_on(server_rec *);
void         ssl_mutex_off(server_rec *);
void         ssl_mutex_kill(server_rec *s);
void         ssl_mutex_file_create(server_rec *, pool *);
void         ssl_mutex_file_open(server_rec *, pool *);
void         ssl_mutex_file_remove(void *);
BOOL         ssl_mutex_file_acquire(void);
BOOL         ssl_mutex_file_release(void);
void         ssl_mutex_sem_create(server_rec *, pool *);
void         ssl_mutex_sem_open(server_rec *, pool *);
void         ssl_mutex_sem_remove(void *);
BOOL         ssl_mutex_sem_acquire(void);
BOOL         ssl_mutex_sem_release(void);
#endif /* XXX */
int          ssl_mutex_init(server_rec *, apr_pool_t *);
int          ssl_mutex_reinit(server_rec *, apr_pool_t *);
int          ssl_mutex_on(server_rec *);
int          ssl_mutex_off(server_rec *);
int          ssl_mutex_kill(server_rec *);
#if 0 /* XXX */

/*  Logfile Support  */
void         ssl_log_open(server_rec *, server_rec *, pool *);
+6 −10
Original line number Diff line number Diff line
@@ -96,8 +96,7 @@ void ssl_config_global_create(void)
        mc->tSessionCacheDataTable = NULL;
        mc->nMutexMode             = SSL_MUTEXMODE_UNSET;
        mc->szMutexFile            = NULL;
        mc->nMutexFD               = -1;
        mc->nMutexSEMID            = -1;
        mc->pMutex                 = NULL;
        mc->aRandSeed              = ap_make_array(pPool, 4, sizeof(ssl_randseed_t));
        mc->tPrivateKey            = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
        mc->tPublicCert            = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
@@ -324,21 +323,18 @@ const char *ssl_cmd_SSLMutex(
        return err;
    if (ssl_config_global_isfixed())
        return NULL;
    if (strcEQ(arg, "none")) {
    if (strcEQ(arg, "none") || strcEQ(arg, "no")) {
        mc->nMutexMode  = SSL_MUTEXMODE_NONE;
    }
    else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) {
        mc->nMutexMode  = SSL_MUTEXMODE_FILE;
        mc->nMutexMode  = SSL_MUTEXMODE_USED;
        mc->szMutexFile = ap_psprintf(mc->pPool, "%s.%lu",
                                      ap_server_root_relative(cmd->pool, "mutex", arg+5),
                                      (unsigned long)getpid());
    }
    else if (strcEQ(arg, "sem")) {
#ifdef SSL_CAN_USE_SEM
        mc->nMutexMode  = SSL_MUTEXMODE_SEM;
#else
        return "SSLMutex: Semaphores not available on this platform";
#endif
    else if (strcEQ(arg, "sem") || strcEQ(arg, "yes")) {
        mc->nMutexMode  = SSL_MUTEXMODE_USED;
        mc->szMutexFile = NULL; /* APR determines temporary filename */
    }
    else
        return "SSLMutex: Invalid argument";
+28 −286
Original line number Diff line number Diff line
@@ -64,321 +64,63 @@

#if 0 /* XXX */

/*  _________________________________________________________________
**
**  Mutex Support (Common)
**  _________________________________________________________________
*/

void ssl_mutex_init(server_rec *s, pool *p)
{
    SSLModConfigRec *mc = myModConfig();

    if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
        ssl_mutex_file_create(s, p);
    else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
        ssl_mutex_sem_create(s, p);
    return;
}

void ssl_mutex_reinit(server_rec *s, pool *p)
{
    SSLModConfigRec *mc = myModConfig();

    if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
        ssl_mutex_file_open(s, p);
    else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
        ssl_mutex_sem_open(s, p);
    return;
}

void ssl_mutex_on(server_rec *s)
{
    SSLModConfigRec *mc = myModConfig();
    BOOL ok = TRUE;

    if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
        ok = ssl_mutex_file_acquire();
    else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
        ok = ssl_mutex_sem_acquire();
    if (!ok)
        ssl_log(s, SSL_LOG_WARN, "Failed to acquire global mutex lock");
    return;
}

void ssl_mutex_off(server_rec *s)
{
    SSLModConfigRec *mc = myModConfig();
    BOOL ok = TRUE;

    if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
        ok = ssl_mutex_file_release();
    else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
        ok = ssl_mutex_sem_release();
    if (!ok)
        ssl_log(s, SSL_LOG_WARN, "Failed to release global mutex lock");
    return;
}

void ssl_mutex_kill(server_rec *s)
{
    SSLModConfigRec *mc = myModConfig();

    if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
        ssl_mutex_file_remove(s);
    else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
        ssl_mutex_sem_remove(s);
    return;
}


/*  _________________________________________________________________
**
**  Mutex Support (Lockfile)
**  _________________________________________________________________
*/

void ssl_mutex_file_create(server_rec *s, pool *p)
int ssl_mutex_init(server_rec *s, apr_pool_t *p)
{
    SSLModConfigRec *mc = myModConfig();

    /* create the lockfile */
    unlink(mc->szMutexFile);
    if ((mc->nMutexFD = ap_popenf(p, mc->szMutexFile,
                                  O_WRONLY|O_CREAT, SSL_MUTEX_LOCK_MODE)) < 0) {
        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                "Parent process could not create SSLMutex lockfile %s",
                mc->szMutexFile);
        ssl_die();
    }
    ap_pclosef(p, mc->nMutexFD);

    /* make sure the childs have access to this file */
#ifndef OS2
    if (geteuid() == 0 /* is superuser */)
        chown(mc->szMutexFile, ap_user_id, -1 /* no gid change */);
#endif

    /* open the lockfile for real */
    if ((mc->nMutexFD = ap_popenf(p, mc->szMutexFile,
                                  O_WRONLY, SSL_MUTEX_LOCK_MODE)) < 0) {
        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                "Parent could not open SSLMutex lockfile %s",
                mc->szMutexFile);
        ssl_die();
    }
    return;
}

void ssl_mutex_file_open(server_rec *s, pool *p)
{
    SSLModConfigRec *mc = myModConfig();

    /* open the lockfile (once per child) to get a unique fd */
    if ((mc->nMutexFD = ap_popenf(p, mc->szMutexFile,
                                  O_WRONLY, SSL_MUTEX_LOCK_MODE)) < 0) {
        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                "Child could not open SSLMutex lockfile %s",
                mc->szMutexFile);
        ssl_die();
    }
    return;
}

void ssl_mutex_file_remove(void *data)
{
    SSLModConfigRec *mc = myModConfig();

    /* remove the mutex lockfile */
    unlink(mc->szMutexFile);
    return;
}

#ifdef SSL_USE_FCNTL
static struct flock   lock_it;
static struct flock unlock_it;
#endif

BOOL ssl_mutex_file_acquire(void)
{
    int rc = -1;
    SSLModConfigRec *mc = myModConfig();

#ifdef SSL_USE_FCNTL
    lock_it.l_whence = SEEK_SET; /* from current point */
    lock_it.l_start  = 0;        /* -"- */
    lock_it.l_len    = 0;        /* until end of file */
    lock_it.l_type   = F_WRLCK;  /* set exclusive/write lock */
    lock_it.l_pid    = 0;        /* pid not actually interesting */

    while (   ((rc = fcntl(mc->nMutexFD, F_SETLKW, &lock_it)) < 0)
           && (errno == EINTR)                                    ) 
        ;
#endif
#ifdef SSL_USE_FLOCK
    while (   ((rc = flock(mc->nMutexFD, LOCK_EX)) < 0)
           && (errno == EINTR)                         )
        ;
#endif

    if (rc < 0)
    if (mc->nMutexMode == SSL_MUTEXMODE_NONE) 
        return TRUE;
    if (apr_lock_create(&mc->pMutex, APR_MUTEX, APR_LOCKALL, 
                        mc->szMutexFile, p) != APR_SUCCESS)
        return FALSE;
    else
    return TRUE;
}

BOOL ssl_mutex_file_release(void)
int ssl_mutex_reinit(server_rec *s, apr_pool_t *p)
{
    int rc = -1;
    SSLModConfigRec *mc = myModConfig();

#ifdef SSL_USE_FCNTL
    unlock_it.l_whence = SEEK_SET; /* from current point */
    unlock_it.l_start  = 0;        /* -"- */
    unlock_it.l_len    = 0;        /* until end of file */
    unlock_it.l_type   = F_UNLCK;  /* unlock */
    unlock_it.l_pid    = 0;        /* pid not actually interesting */

    while (   (rc = fcntl(mc->nMutexFD, F_SETLKW, &unlock_it)) < 0
           && (errno == EINTR)                                    )
        ;
#endif
#ifdef SSL_USE_FLOCK
    while (   (rc = flock(mc->nMutexFD, LOCK_UN)) < 0
           && (errno == EINTR)                       ) 
        ;
#endif

    if (rc < 0)
    if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
        return TRUE;
    if (apr_lock_child_init(&mc->pMutex, mc->szMutexFile, p) != APR_SUCCESS)
        return FALSE;
    else
    return TRUE;
}

/*  _________________________________________________________________
**
**  Mutex Support (Process Semaphore)
**  _________________________________________________________________
*/

void ssl_mutex_sem_create(server_rec *s, pool *p)
int ssl_mutex_on(server_rec *s)
{
#ifdef SSL_CAN_USE_SEM
    int semid;
    SSLModConfigRec *mc = myModConfig();
#ifdef SSL_HAVE_IPCSEM
    union ssl_ipc_semun semctlarg;
    struct semid_ds semctlbuf;
#endif

#ifdef SSL_HAVE_IPCSEM
    semid = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
    if (semid == -1 && errno == EEXIST)
        semid = semget(IPC_PRIVATE, 1, IPC_EXCL|S_IRUSR|S_IWUSR);
    if (semid == -1) {
        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                "Parent process could not create private SSLMutex semaphore");
        ssl_die();
    }
    semctlarg.val = 0;
    if (semctl(semid, 0, SETVAL, semctlarg) < 0) {
        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                "Parent process could not initialize SSLMutex semaphore value");
        ssl_die();
    }
    semctlbuf.sem_perm.uid  = ap_user_id;
    semctlbuf.sem_perm.gid  = ap_group_id;
    semctlbuf.sem_perm.mode = 0660;
    semctlarg.buf = &semctlbuf;
    if (semctl(semid, 0, IPC_SET, semctlarg) < 0) {
        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                "Parent process could not set permissions for SSLMutex semaphore");
        ssl_die();
    }
#endif
#ifdef SSL_HAVE_W32SEM
    semid = (int)ap_create_mutex("mod_ssl_mutex");
#endif
    mc->nMutexSEMID = semid;
#endif
    return;
}

void ssl_mutex_sem_open(server_rec *s, pool *p)
{
#ifdef SSL_CAN_USE_SEM
#ifdef SSL_HAVE_W32SEM
    SSLModConfigRec *mc = myModConfig();

    mc->nMutexSEMID = (int)ap_open_mutex("mod_ssl_mutex");
#endif
#endif
    return;
    if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
        return TRUE;
    if (apr_lock_acquire(mc->pMutex) != APR_SUCCESS) {
        ssl_log(s, SSL_LOG_WARN, "Failed to acquire global mutex lock");
        return FALSE;
    }

void ssl_mutex_sem_remove(void *data)
{
#ifdef SSL_CAN_USE_SEM
    SSLModConfigRec *mc = myModConfig();

#ifdef SSL_HAVE_IPCSEM
    semctl(mc->nMutexSEMID, 0, IPC_RMID, 0);
#endif
#ifdef SSL_HAVE_W32SEM
    ap_destroy_mutex((mutex *)mc->nMutexSEMID);
#endif
#endif
    return;
    return TRUE;
}

BOOL ssl_mutex_sem_acquire(void)
int ssl_mutex_off(server_rec *s)
{
    int rc = 0;
#ifdef SSL_CAN_USE_SEM
    SSLModConfigRec *mc = myModConfig();

#ifdef SSL_HAVE_IPCSEM
    struct sembuf sb[] = {
        { 0, 0, 0 },       /* wait for semaphore */
        { 0, 1, SEM_UNDO } /* increment semaphore */
    };

    while (   (rc = semop(mc->nMutexSEMID, sb, 2)) < 0
           && (errno == EINTR)                        ) 
        ;
#endif
#ifdef SSL_HAVE_W32SEM
    rc = ap_acquire_mutex((mutex *)mc->nMutexSEMID);
#endif
#endif
    if (rc != 0)
    if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
        return TRUE;
    if (apr_lock_release(mc->pMutex) != APR_SUCCESS) {
        ssl_log(s, SSL_LOG_WARN, "Failed to release global mutex lock");
        return FALSE;
    else
    }
    return TRUE;
}

BOOL ssl_mutex_sem_release(void)
int ssl_mutex_kill(server_rec *s)
{
    int rc = 0;
#ifdef SSL_CAN_USE_SEM
    SSLModConfigRec *mc = myModConfig();

#ifdef SSL_HAVE_IPCSEM
    struct sembuf sb[] = {
        { 0, -1, SEM_UNDO } /* decrements semaphore */
    };

    while (   (rc = semop(mc->nMutexSEMID, sb, 1)) < 0 
           && (errno == EINTR)                        ) 
        ;
#endif
#ifdef SSL_HAVE_W32SEM
    rc = ap_release_mutex((mutex *)mc->nMutexSEMID);
#endif
#endif
    if (rc != 0)
    if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
        return TRUE;
    if (apr_lock_destroy(mc->pMutex) != APR_SUCCESS)
        return FALSE;
    else
    return TRUE;
}