From 5ff0336491cf3d94d3b8ee37162a98fcb42b1151 Mon Sep 17 00:00:00 2001 From: toddouska Date: Thu, 1 May 2014 09:28:33 -0700 Subject: [PATCH] add custom kqueue event for crl monitor shutdown --- cyassl/internal.h | 1 + src/crl.c | 80 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/cyassl/internal.h b/cyassl/internal.h index b2dd3cc60..f74c2d68e 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1057,6 +1057,7 @@ struct CYASSL_CRL { CRL_Monitor monitors[2]; /* PEM and DER possible */ #ifdef HAVE_CRL_MONITOR pthread_t tid; /* monitoring thread */ + int mfd; /* monitor fd, -1 if no init yet */ #endif }; diff --git a/src/crl.c b/src/crl.c index b3d114a49..98e4868d1 100644 --- a/src/crl.c +++ b/src/crl.c @@ -34,6 +34,10 @@ #include #include +#ifdef HAVE_CRL_MONITOR + static int StopMonitor(int mfd); +#endif + /* Initialze CRL members */ int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm) @@ -45,7 +49,8 @@ int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm) crl->monitors[0].path = NULL; crl->monitors[1].path = NULL; #ifdef HAVE_CRL_MONITOR - crl->tid = 0; + crl->tid = 0; + crl->mfd = -1; /* mfd for bsd is kqueue fd */ #endif if (InitMutex(&crl->crlLock) != 0) return BAD_MUTEX_E; @@ -113,8 +118,13 @@ void FreeCRL(CYASSL_CRL* crl, int dynamic) #ifdef HAVE_CRL_MONITOR if (crl->tid != 0) { - CYASSL_MSG("Canceling monitor thread"); - pthread_cancel(crl->tid); + CYASSL_MSG("stopping monitor thread"); + if (StopMonitor(crl->mfd) == 0) + pthread_join(crl->tid, NULL); + else { + CYASSL_MSG("stop monitor failed, cancel instead"); + pthread_cancel(crl->tid); + } } #endif FreeMutex(&crl->crlLock); @@ -339,6 +349,7 @@ static int SwapLists(CYASSL_CRL* crl) #include #include #include +#include #ifdef __MACH__ #define XEVENT_MODE O_EVTONLY @@ -347,22 +358,53 @@ static int SwapLists(CYASSL_CRL* crl) #endif +/* we need a unique kqueue user filter fd for crl in case user is doing custom + * events too */ +#ifndef CRL_CUSTOM_FD + #define CRL_CUSTOM_FD 123456 +#endif + + +/* shutdown monitor thread, 0 on success */ +static int StopMonitor(int mfd) +{ + struct kevent change; + + /* trigger custom shutdown */ + EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); + if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) { + CYASSL_MSG("kevent trigger customer event failed"); + return -1; + } + + return 0; +} + + /* OS X monitoring */ static void* DoMonitor(void* arg) { - int fPEM, fDER, kq; + int fPEM, fDER; struct kevent change; CYASSL_CRL* crl = (CYASSL_CRL*)arg; CYASSL_ENTER("DoMonitor"); - kq = kqueue(); - if (kq == -1) { + crl->mfd = kqueue(); + if (crl->mfd == -1) { CYASSL_MSG("kqueue failed"); return NULL; } + /* listen for custom shutdown event */ + EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL); + if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) { + CYASSL_MSG("kevent monitor customer event failed"); + close(crl->mfd); + return NULL; + } + fPEM = -1; fDER = -1; @@ -370,6 +412,7 @@ static void* DoMonitor(void* arg) fPEM = open(crl->monitors[0].path, XEVENT_MODE); if (fPEM == -1) { CYASSL_MSG("PEM event dir open failed"); + close(crl->mfd); return NULL; } } @@ -378,6 +421,7 @@ static void* DoMonitor(void* arg) fDER = open(crl->monitors[1].path, XEVENT_MODE); if (fDER == -1) { CYASSL_MSG("DER event dir open failed"); + close(crl->mfd); return NULL; } } @@ -392,7 +436,7 @@ static void* DoMonitor(void* arg) for (;;) { struct kevent event; - int numEvents = kevent(kq, &change, 1, &event, 1, NULL); + int numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL); CYASSL_MSG("Got kevent"); @@ -401,11 +445,23 @@ static void* DoMonitor(void* arg) continue; } + if (event.filter == EVFILT_USER) { + CYASSL_MSG("Got user shutdown event, breaking out"); + break; + } + if (SwapLists(crl) < 0) { CYASSL_MSG("SwapLists problem, continue"); } } + if (fPEM != -1) + close(fPEM); + if (fDER != -1) + close(fDER); + + close(crl->mfd); + return NULL; } @@ -416,6 +472,16 @@ static void* DoMonitor(void* arg) #include #include + +/* shutdown monitor thread, 0 on success */ +static int StopMonitor(int mfd) +{ + + + return -1; +} + + /* linux monitoring */ static void* DoMonitor(void* arg) {