[Mofify]
1.修改多线程多并发时evhttp异常退出问题 2.添加openssl锁初始化回调函数
This commit is contained in:
@@ -15,25 +15,12 @@
|
|||||||
#include <x509.h>
|
#include <x509.h>
|
||||||
#include <evp.h>
|
#include <evp.h>
|
||||||
|
|
||||||
enum rt_command_type{
|
|
||||||
RT_COMMAND_UKNOWN,
|
|
||||||
|
|
||||||
RT_COMMAND_INSERT,
|
|
||||||
RT_COMMAND_DELETE,
|
|
||||||
RT_COMMAND_CHANGE,
|
|
||||||
RT_COMMAND_SELECT,
|
|
||||||
RT_COMMAND_SET_TIME
|
|
||||||
};
|
|
||||||
|
|
||||||
struct redis_t{
|
|
||||||
enum rt_command_type type;
|
|
||||||
struct redisAsyncContext *cl_ctx;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct request_t{
|
struct request_t{
|
||||||
#define DATALEN 64
|
#define DATALEN 64
|
||||||
char host[DATALEN];
|
char host[DATALEN];
|
||||||
|
|
||||||
|
int thread_id;
|
||||||
|
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
int valid;
|
int valid;
|
||||||
@@ -41,19 +28,6 @@ struct request_t{
|
|||||||
struct evhttp_request *evh_req;
|
struct evhttp_request *evh_req;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cert_trapper_t{
|
|
||||||
|
|
||||||
int thread_id;
|
|
||||||
|
|
||||||
EVP_PKEY *key;
|
|
||||||
|
|
||||||
X509 *root;
|
|
||||||
|
|
||||||
struct request_t *req;
|
|
||||||
|
|
||||||
struct redis_t *redis;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct config_bucket_t{
|
struct config_bucket_t{
|
||||||
unsigned int thread_nu;
|
unsigned int thread_nu;
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@
|
|||||||
#define DEFAULT_PRIVATEKEY_NAME "private.key"
|
#define DEFAULT_PRIVATEKEY_NAME "private.key"
|
||||||
#define DEFAULT_CA_CERTIFICATE "ca.cer"
|
#define DEFAULT_CA_CERTIFICATE "ca.cer"
|
||||||
|
|
||||||
|
static libevent_thread *threads;
|
||||||
|
|
||||||
|
#define sizeof_seconds(x) (x * 24 * 60 * 60)
|
||||||
|
|
||||||
void connectCallback(const struct redisAsyncContext *c, int status) {
|
void connectCallback(const struct redisAsyncContext *c, int status) {
|
||||||
if (status != REDIS_OK) {
|
if (status != REDIS_OK) {
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Redis connect error : %s\n", c->errstr);
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Redis connect error : %s\n", c->errstr);
|
||||||
@@ -51,10 +55,6 @@ void connectCallback(const struct redisAsyncContext *c, int status) {
|
|||||||
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Redis server connected...\n");
|
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Redis server connected...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static libevent_thread *threads;
|
|
||||||
|
|
||||||
#define sizeof_seconds(x) (x * 24 * 60 * 60)
|
|
||||||
|
|
||||||
void disconnectCallback(const struct redisAsyncContext *c, int status) {
|
void disconnectCallback(const struct redisAsyncContext *c, int status) {
|
||||||
if (status != REDIS_OK) {
|
if (status != REDIS_OK) {
|
||||||
printf("Redis disconnect error: %s\n", c->errstr);
|
printf("Redis disconnect error: %s\n", c->errstr);
|
||||||
@@ -63,6 +63,56 @@ void disconnectCallback(const struct redisAsyncContext *c, int status) {
|
|||||||
printf("Redis server disconnected...\n");
|
printf("Redis server disconnected...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rt_mutex *mutex_buf = NULL;
|
||||||
|
|
||||||
|
static unsigned long pthreads_thread_id(void)
|
||||||
|
{
|
||||||
|
return ((unsigned long)pthread_self());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pthreads_locking_callback(int mode, int n, const char __attribute__((__unused__))*file,
|
||||||
|
int __attribute__((__unused__))line)
|
||||||
|
{
|
||||||
|
if(mode & CRYPTO_LOCK)
|
||||||
|
rt_mutex_lock(&(mutex_buf[n]));
|
||||||
|
else
|
||||||
|
rt_mutex_unlock(&(mutex_buf[n]));
|
||||||
|
}
|
||||||
|
|
||||||
|
int thread_setup(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mutex_buf = malloc(CRYPTO_num_locks() * sizeof(rt_mutex));
|
||||||
|
if(!mutex_buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(i = 0; i < CRYPTO_num_locks(); i++)
|
||||||
|
rt_mutex_init(&(mutex_buf[i]), NULL);
|
||||||
|
|
||||||
|
CRYPTO_set_id_callback(pthreads_thread_id);
|
||||||
|
CRYPTO_set_locking_callback(pthreads_locking_callback);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thread_cleanup(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(!mutex_buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
CRYPTO_set_id_callback(NULL);
|
||||||
|
CRYPTO_set_locking_callback(NULL);
|
||||||
|
|
||||||
|
for(i = 0; i < CRYPTO_num_locks(); i++)
|
||||||
|
rt_mutex_destroy(&(mutex_buf[i]));
|
||||||
|
|
||||||
|
free(mutex_buf);
|
||||||
|
mutex_buf = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ssl_rand(void *p, size_t sz)
|
ssl_rand(void *p, size_t sz)
|
||||||
{
|
{
|
||||||
@@ -144,7 +194,7 @@ ssl_x509_v3ext_copy_by_nid(X509 *crt, X509 *origcrt, int nid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
X509 *
|
X509 *
|
||||||
openssl_x509_modify_by_cert(X509 *cacrt, EVP_PKEY *cakey, X509 *origcrt, EVP_PKEY *key,
|
x509_modify_by_cert(X509 *cacrt, EVP_PKEY *cakey, X509 *origcrt, EVP_PKEY *key,
|
||||||
int days, const char *extraname, const char *crlurl)
|
int days, const char *extraname, const char *crlurl)
|
||||||
{
|
{
|
||||||
X509_NAME *subject, *issuer;
|
X509_NAME *subject, *issuer;
|
||||||
@@ -423,36 +473,6 @@ finish:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//string?ssl
|
|
||||||
X509 *openssl_str_to_x509(char *cert)
|
|
||||||
{
|
|
||||||
X509* x = NULL;
|
|
||||||
BIO *bp = NULL;
|
|
||||||
char *in_buf = NULL;
|
|
||||||
|
|
||||||
int len = strlen(cert);
|
|
||||||
|
|
||||||
in_buf = (char *)malloc(len + 1);
|
|
||||||
if (!in_buf)
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
strncpy(in_buf, cert, len + 1);
|
|
||||||
|
|
||||||
if ( (bp = BIO_new(BIO_s_mem())) == NULL){
|
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "unable to create BIO for output\n");
|
|
||||||
free(in_buf);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
BIO_printf(bp, "%s", in_buf);
|
|
||||||
|
|
||||||
x = PEM_read_bio_X509(bp, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
BIO_free(bp);
|
|
||||||
free(in_buf);
|
|
||||||
finish:
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
static void callback(int __attribute__((__unused__))p, int __attribute__((__unused__))n,
|
static void callback(int __attribute__((__unused__))p, int __attribute__((__unused__))n,
|
||||||
void __attribute__((__unused__))*arg)
|
void __attribute__((__unused__))*arg)
|
||||||
{
|
{
|
||||||
@@ -567,7 +587,7 @@ int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
X509 *openssl_creat_cert(char *host, int days)
|
X509 *x509_create_cert(char *host, int days)
|
||||||
{
|
{
|
||||||
X509 *x509 = NULL;
|
X509 *x509 = NULL;
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
@@ -583,30 +603,27 @@ X509 *openssl_creat_cert(char *host, int days)
|
|||||||
return x509;
|
return x509;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cert_redis_init(struct event_base *base, struct redis_t *redisCtx)
|
int cert_redis_init(struct event_base *base, struct redisAsyncContext **cl_ctx)
|
||||||
{
|
{
|
||||||
int xret = -1;
|
int xret = -1;
|
||||||
struct redisAsyncContext *cl_ctx = NULL;
|
|
||||||
struct config_bucket_t *redis = cert_default_config();
|
struct config_bucket_t *redis = cert_default_config();
|
||||||
|
|
||||||
cl_ctx = redisAsyncConnect(redis->r_ip, redis->r_port);
|
*cl_ctx = redisAsyncConnect(redis->r_ip, redis->r_port);
|
||||||
if(cl_ctx->err) {
|
if((*cl_ctx)->err) {
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Redis Connect error : %s", cl_ctx->errstr);
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Redis Connect error : %s", (*cl_ctx)->errstr);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
redisCtx->cl_ctx = cl_ctx;
|
redisLibeventAttach((*cl_ctx), base);
|
||||||
|
redisAsyncSetConnectCallback((*cl_ctx), connectCallback);
|
||||||
|
redisAsyncSetDisconnectCallback((*cl_ctx), disconnectCallback);
|
||||||
xret = 0;
|
xret = 0;
|
||||||
|
|
||||||
redisLibeventAttach(cl_ctx, base);
|
|
||||||
redisAsyncSetConnectCallback(cl_ctx, connectCallback);
|
|
||||||
redisAsyncSetDisconnectCallback(cl_ctx, disconnectCallback);
|
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
return xret;
|
return xret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
redis_async_set_callback(redisAsyncContext __attribute__((__unused__))*c, void *r,
|
setCallback(redisAsyncContext __attribute__((__unused__))*c, void *r,
|
||||||
void *privdata)
|
void *privdata)
|
||||||
{
|
{
|
||||||
redisReply *reply = (redisReply*)r;
|
redisReply *reply = (redisReply*)r;
|
||||||
@@ -628,7 +645,7 @@ evhttp_socket_send(struct evhttp_request *req, char *sendbuf)
|
|||||||
/* This holds the content we're sending. */
|
/* This holds the content we're sending. */
|
||||||
evb = evbuffer_new();
|
evb = evbuffer_new();
|
||||||
|
|
||||||
if (sendbuf[0] == '\0'){
|
if (sendbuf[0] == '\0' && req == NULL){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
evhttp_add_header(evhttp_request_get_output_headers(req),
|
evhttp_add_header(evhttp_request_get_output_headers(req),
|
||||||
@@ -657,15 +674,16 @@ release_resources(struct cert_trapper_t *certCtx, char *cert, char *pubkey, int
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void openssl_issued_by_rootCA(char *host, EVP_PKEY *key, X509 *root, char *ca_s, char *pubkey)
|
int x509_mkcert(char *host, EVP_PKEY *key, X509 *root, char *ca_s, char *pubkey)
|
||||||
{
|
{
|
||||||
|
int xret = -1;
|
||||||
struct config_bucket_t *rte = cert_default_config();
|
struct config_bucket_t *rte = cert_default_config();
|
||||||
|
|
||||||
X509* ca = openssl_creat_cert(host, rte->days);
|
X509* ca = x509_create_cert(host, rte->days);
|
||||||
if (!ca){
|
if (!ca){
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
X509* x509 = openssl_x509_modify_by_cert(root, key, ca, X509_get_pubkey(root),
|
X509* x509 = x509_modify_by_cert(root, key, ca, X509_get_pubkey(root),
|
||||||
rte->days, NULL, NULL);
|
rte->days, NULL, NULL);
|
||||||
if (!x509){
|
if (!x509){
|
||||||
goto err;
|
goto err;
|
||||||
@@ -677,59 +695,76 @@ void openssl_issued_by_rootCA(char *host, EVP_PKEY *key, X509 *root, char *ca_s,
|
|||||||
err:
|
err:
|
||||||
X509_free(ca);
|
X509_free(ca);
|
||||||
finish:
|
finish:
|
||||||
return;
|
return xret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void redis_async_get_callback(redisAsyncContext *c, void *r, void *privdata)
|
int create_x509(struct request_t *request, redisAsyncContext *c, char *sendbuf)
|
||||||
|
{
|
||||||
|
int xret = -1;
|
||||||
|
|
||||||
|
libevent_thread *thread = threads + request->thread_id;
|
||||||
|
|
||||||
|
struct config_bucket_t *rte = cert_default_config();
|
||||||
|
char cert[SG_DATA_SIZE] = {0}, pubkey[SG_DATA_SIZE] = {0};
|
||||||
|
|
||||||
|
x509_mkcert(request->host, thread->key, thread->root, cert, pubkey);
|
||||||
|
if (cert[0] == '\0' && pubkey[0] == '\0'){
|
||||||
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to issue certificate");
|
||||||
|
evhttp_send_error(request->evh_req, HTTP_BADREQUEST, 0);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
CA_SIGN_ADD(1);
|
||||||
|
snprintf(sendbuf, SG_DATA_SIZE * 2, "%s%s", pubkey, cert);
|
||||||
|
|
||||||
|
xret = redisAsyncCommand(c, setCallback, request->host, "SETEX %s %d %s",
|
||||||
|
request->host, sizeof_seconds(rte->days), sendbuf);
|
||||||
|
if (xret < 0){
|
||||||
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to set information to redis server");
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
xret = 0;
|
||||||
|
finish:
|
||||||
|
return xret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getCallback(redisAsyncContext *c, void *r, void *privdata)
|
||||||
{
|
{
|
||||||
int xret = -1;
|
int xret = -1;
|
||||||
char sendbuf[SG_DATA_SIZE * 2] = {0};
|
char sendbuf[SG_DATA_SIZE * 2] = {0};
|
||||||
char cert[SG_DATA_SIZE] = {0}, pubkey[SG_DATA_SIZE] = {0};
|
|
||||||
redisReply *reply = (redisReply*)r;
|
redisReply *reply = (redisReply*)r;
|
||||||
|
|
||||||
struct config_bucket_t *rte = cert_default_config();
|
struct request_t *request = (struct request_t *)privdata;
|
||||||
struct cert_trapper_t *certCtx = (struct cert_trapper_t *)privdata;
|
|
||||||
|
|
||||||
struct request_t *req = certCtx->req;
|
switch(reply->type){
|
||||||
|
case REDIS_REPLY_STRING:
|
||||||
/* Obtain certificate judgment from redis **/
|
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Sends the certificate information to the requestor");
|
||||||
if(reply->type == REDIS_REPLY_STRING){
|
CA_STORE_ADD(1);
|
||||||
CA_STORE_ADD(1);
|
if (reply->str != NULL){
|
||||||
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Sends the certificate information to the requestor");
|
snprintf(sendbuf, SG_DATA_SIZE * 2, "%s", reply->str);
|
||||||
if (reply->str != NULL){
|
xret = 0;
|
||||||
snprintf(sendbuf, SG_DATA_SIZE * 2, "%s", reply->str);
|
}else{
|
||||||
}
|
evhttp_send_error(request->evh_req, HTTP_BADREQUEST, 0);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
if(reply->type == REDIS_REPLY_NIL){
|
case REDIS_REPLY_NIL:
|
||||||
/* Certificate information modification and Strategy to judge**/
|
/* Certificate information modification and Strategy to judge**/
|
||||||
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Generating certificate information");
|
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Generating certificate information");
|
||||||
|
xret = create_x509(request, c, sendbuf);
|
||||||
openssl_issued_by_rootCA(req->host, certCtx->key, certCtx->root, cert, pubkey);
|
break;
|
||||||
if (cert[0] == '\0' && pubkey[0] == '\0'){
|
default:
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to issue certificate");
|
break;
|
||||||
evhttp_send_error(req->evh_req, HTTP_BADREQUEST, 0);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
CA_SIGN_ADD(1);
|
|
||||||
snprintf(sendbuf, SG_DATA_SIZE * 2, "%s%s", pubkey, cert);
|
|
||||||
|
|
||||||
xret = redisAsyncCommand(c, redis_async_set_callback, req->host, "SETEX %s %d %s",
|
|
||||||
req->host, sizeof_seconds(rte->days), sendbuf);
|
|
||||||
if (xret < 0){
|
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to set information to redis server");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
evhttp_socket_send(req->evh_req, sendbuf);
|
if (xret < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
req->flag = -1;
|
evhttp_socket_send(request->evh_req, sendbuf);
|
||||||
req->valid = 0;
|
|
||||||
memset(req->host, 0, DATALEN);
|
|
||||||
finish:
|
finish:
|
||||||
|
kfree(request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x509_privatekey_init(struct cert_trapper_t *certCtx)
|
int x509_privatekey_init(EVP_PKEY **key, X509 **root)
|
||||||
{
|
{
|
||||||
int xret = -1, len = 0;
|
int xret = -1, len = 0;
|
||||||
FILE *fp; RSA *rsa = NULL;
|
FILE *fp; RSA *rsa = NULL;
|
||||||
@@ -739,8 +774,8 @@ int x509_privatekey_init(struct cert_trapper_t *certCtx)
|
|||||||
snprintf(key_path, sizeof(key_path), "%s/%s", rte->ca_path, DEFAULT_PRIVATEKEY_NAME);
|
snprintf(key_path, sizeof(key_path), "%s/%s", rte->ca_path, DEFAULT_PRIVATEKEY_NAME);
|
||||||
snprintf(cert_path, sizeof(cert_path), "%s/%s", rte->ca_path, DEFAULT_CA_CERTIFICATE);
|
snprintf(cert_path, sizeof(cert_path), "%s/%s", rte->ca_path, DEFAULT_CA_CERTIFICATE);
|
||||||
|
|
||||||
certCtx->key = EVP_PKEY_new();
|
*key = EVP_PKEY_new();
|
||||||
if (NULL == certCtx->key){
|
if (NULL == *key){
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +791,7 @@ int x509_privatekey_init(struct cert_trapper_t *certCtx)
|
|||||||
RSA_free(rsa);
|
RSA_free(rsa);
|
||||||
goto pkey_free;
|
goto pkey_free;
|
||||||
}
|
}
|
||||||
if ( !PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) || !EVP_PKEY_assign_RSA(certCtx->key,rsa))
|
if ( !PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) || !EVP_PKEY_assign_RSA(*key,rsa))
|
||||||
{
|
{
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Private key read failed");
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Private key read failed");
|
||||||
goto pkey_free;
|
goto pkey_free;
|
||||||
@@ -772,8 +807,8 @@ int x509_privatekey_init(struct cert_trapper_t *certCtx)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
certCtx->root = X509_new();
|
*root = X509_new();
|
||||||
if ( d2i_X509(&certCtx->root, (const unsigned char**)&p, len) == NULL )
|
if ( d2i_X509(root, (const unsigned char**)&p, len) == NULL )
|
||||||
{
|
{
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Application for x509 failed");
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Application for x509 failed");
|
||||||
goto pkey_free;
|
goto pkey_free;
|
||||||
@@ -782,7 +817,7 @@ int x509_privatekey_init(struct cert_trapper_t *certCtx)
|
|||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
pkey_free:
|
pkey_free:
|
||||||
EVP_PKEY_free(certCtx->key);
|
EVP_PKEY_free(*key);
|
||||||
finish:
|
finish:
|
||||||
return xret;
|
return xret;
|
||||||
}
|
}
|
||||||
@@ -802,48 +837,9 @@ int cert_session_finish()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct cert_trapper_t * __engine_init_contex ()
|
|
||||||
{
|
|
||||||
struct cert_trapper_t *certCtx = NULL;
|
|
||||||
|
|
||||||
certCtx = (struct cert_trapper_t *)malloc(sizeof(struct cert_trapper_t));
|
|
||||||
if (certCtx != NULL){
|
|
||||||
certCtx->redis = (struct redis_t *)malloc(sizeof(struct redis_t));
|
|
||||||
if (certCtx->redis == NULL){
|
|
||||||
free(certCtx);
|
|
||||||
certCtx = NULL;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
certCtx->req = (struct request_t *)malloc(sizeof(struct request_t));
|
|
||||||
if (certCtx->req == NULL){
|
|
||||||
free(certCtx);
|
|
||||||
certCtx = NULL;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finish:
|
|
||||||
return certCtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __engine_fini_contex(struct cert_trapper_t *certCtx)
|
|
||||||
{
|
|
||||||
if (certCtx){
|
|
||||||
if (certCtx->redis){
|
|
||||||
free(certCtx->redis);
|
|
||||||
certCtx->redis = NULL;
|
|
||||||
}
|
|
||||||
if (certCtx->req){
|
|
||||||
free(certCtx->req);
|
|
||||||
certCtx->req = NULL;
|
|
||||||
}
|
|
||||||
free(certCtx);
|
|
||||||
certCtx = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
libevent_decode_uri(const char *uri, char *host,
|
sample_decode_uri(const char *uri, char *host,
|
||||||
int *flag, int *valid)
|
int *flag, int *valid)
|
||||||
{
|
{
|
||||||
const char *fg = NULL, *vl = NULL;
|
const char *fg = NULL, *vl = NULL;
|
||||||
char *decoded_uri = NULL;
|
char *decoded_uri = NULL;
|
||||||
@@ -874,12 +870,25 @@ void
|
|||||||
pthread_work_proc(struct evhttp_request *evh_req, void *arg)
|
pthread_work_proc(struct evhttp_request *evh_req, void *arg)
|
||||||
{
|
{
|
||||||
int xret = -1;
|
int xret = -1;
|
||||||
struct evhttp_uri *decoded = NULL;
|
|
||||||
const char *uri = evhttp_request_get_uri(evh_req);
|
|
||||||
struct cert_trapper_t *certCtx = (struct cert_trapper_t *)arg;
|
|
||||||
struct request_t *req = certCtx->req;
|
|
||||||
|
|
||||||
const char *cmdtype;
|
const char *cmdtype;
|
||||||
|
struct request_t *request = NULL;
|
||||||
|
struct evhttp_uri *decoded = NULL;
|
||||||
|
|
||||||
|
libevent_thread *thread_info = (libevent_thread *)arg;
|
||||||
|
|
||||||
|
const char *uri = evhttp_request_get_uri(evh_req);
|
||||||
|
/* Decode the URI */
|
||||||
|
decoded = evhttp_uri_parse(uri);
|
||||||
|
if (!decoded) {
|
||||||
|
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "It's not a good URI. Sending BADREQUEST\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
request = (struct request_t *) kmalloc (sizeof(struct request_t), MPF_CLR, -1);
|
||||||
|
if (request != NULL){
|
||||||
|
request->thread_id = thread_info->id;
|
||||||
|
request->evh_req = evh_req;
|
||||||
|
}
|
||||||
|
|
||||||
switch (evhttp_request_get_command(evh_req)) {
|
switch (evhttp_request_get_command(evh_req)) {
|
||||||
case EVHTTP_REQ_GET: cmdtype = "GET"; break;
|
case EVHTTP_REQ_GET: cmdtype = "GET"; break;
|
||||||
case EVHTTP_REQ_POST: cmdtype = "POST"; break;
|
case EVHTTP_REQ_POST: cmdtype = "POST"; break;
|
||||||
@@ -892,74 +901,62 @@ pthread_work_proc(struct evhttp_request *evh_req, void *arg)
|
|||||||
case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break;
|
case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break;
|
||||||
default: cmdtype = "unknown"; break;
|
default: cmdtype = "unknown"; break;
|
||||||
}
|
}
|
||||||
/* Decode the URI */
|
|
||||||
decoded = evhttp_uri_parse(uri);
|
|
||||||
if (!decoded) {
|
|
||||||
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "It's not a good URI. Sending BADREQUEST\n");
|
|
||||||
evhttp_send_error(evh_req, HTTP_BADREQUEST, 0);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
WEB_REQUEST_ADD(1);
|
WEB_REQUEST_ADD(1);
|
||||||
libevent_decode_uri(uri, req->host, &req->flag, &req->valid);
|
sample_decode_uri(uri, request->host, &request->flag, &request->valid);
|
||||||
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "[Thread %d]Received a %s request for %s, host:%s, flag:%d, valid:%d\nHeaders:",
|
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "[Thread %d]Received a %s request for %s, host:%s, flag:%d, valid:%d\nHeaders:",
|
||||||
certCtx->thread_id, cmdtype, uri, req->host,
|
request->thread_id, cmdtype, uri, request->host,
|
||||||
req->flag, req->valid);
|
request->flag, request->valid);
|
||||||
|
|
||||||
if (req->host[0] != '\0'){
|
if (request->host[0] != '\0' && request->evh_req != NULL){
|
||||||
req->evh_req = evh_req;
|
xret = redisAsyncCommand(thread_info->cl_ctx, getCallback, request, "GET %s", request->host);
|
||||||
xret = redisAsyncCommand(certCtx->redis->cl_ctx, redis_async_get_callback, certCtx, "GET %s", req->host);
|
|
||||||
if (xret < 0){
|
if (xret < 0){
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to get information from redis server");
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to get information from redis server");
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
kfree(request);
|
||||||
|
evhttp_uri_free(decoded);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
evhttp_uri_free(decoded);
|
evhttp_uri_free(decoded);
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
error:
|
||||||
|
evhttp_send_error(evh_req, HTTP_BADREQUEST, 0);
|
||||||
finish:
|
finish:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cert_trapper_t *
|
static int
|
||||||
cert_trapper_task_int(struct event_base *base, int id)
|
cert_trapper_task_int(struct event_base *base, libevent_thread *me)
|
||||||
{
|
{
|
||||||
int xret = -1;
|
int xret = -1;
|
||||||
|
|
||||||
struct cert_trapper_t *certCtx = __engine_init_contex();
|
|
||||||
if (!certCtx){
|
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to initialize context data");
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
certCtx->thread_id = id;
|
|
||||||
memset(certCtx->req->host, 0, 64);
|
|
||||||
|
|
||||||
/* Initialize the redis connection*/
|
/* Initialize the redis connection*/
|
||||||
xret = cert_redis_init(base, certCtx->redis);
|
xret = cert_redis_init(base, &me->cl_ctx);
|
||||||
if (xret < 0){
|
if (xret < 0 || !me->cl_ctx){
|
||||||
__engine_fini_contex(certCtx);
|
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Initialize the redis connection is failure\n");
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Initialize the redis connection is failure\n");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
/* Initialize the X509 CA*/
|
/* Initialize the X509 CA*/
|
||||||
xret = x509_privatekey_init(certCtx);
|
xret = x509_privatekey_init(&me->key, &me->root);
|
||||||
if (xret < 0){
|
if (xret < 0 || !me->key || !me->root){
|
||||||
__engine_fini_contex(certCtx);
|
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to initialize the x509 certificate");
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to initialize the x509 certificate");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
finish:
|
finish:
|
||||||
return certCtx;
|
return xret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *pthread_worker_libevent(void *arg)
|
static void *pthread_worker_libevent(void *arg)
|
||||||
{
|
{
|
||||||
libevent_thread *me = (libevent_thread *)arg;
|
int xret = -1;
|
||||||
|
|
||||||
struct cert_trapper_t *certCtx = NULL;
|
|
||||||
evutil_socket_t accetp_fd = me->accept_fd;
|
|
||||||
|
|
||||||
struct evhttp *http = NULL;
|
struct evhttp *http = NULL;
|
||||||
struct event_base *base = NULL;
|
struct event_base *base = NULL;
|
||||||
struct evhttp_bound_socket *bound = NULL;
|
struct evhttp_bound_socket *bound = NULL;
|
||||||
|
|
||||||
|
libevent_thread *thread_info = (libevent_thread *)arg;
|
||||||
|
|
||||||
struct config_bucket_t *rte = cert_default_config();
|
struct config_bucket_t *rte = cert_default_config();
|
||||||
|
|
||||||
base = event_base_new();
|
base = event_base_new();
|
||||||
@@ -967,7 +964,6 @@ static void *pthread_worker_libevent(void *arg)
|
|||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Can't allocate event base\n");
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Can't allocate event base\n");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
http = evhttp_new(base);
|
http = evhttp_new(base);
|
||||||
if (!http) {
|
if (!http) {
|
||||||
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "couldn't create evhttp. Exiting.\n");
|
mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "couldn't create evhttp. Exiting.\n");
|
||||||
@@ -975,17 +971,16 @@ static void *pthread_worker_libevent(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Context initialization */
|
/* Context initialization */
|
||||||
certCtx = cert_trapper_task_int(base, me->id);
|
xret = cert_trapper_task_int(base, thread_info);
|
||||||
if (!certCtx){
|
if (xret < 0){
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
evhttp_set_cb(http, "/ca", pthread_work_proc, certCtx);
|
evhttp_set_cb(http, "/ca", pthread_work_proc, thread_info);
|
||||||
|
|
||||||
bound = evhttp_accept_socket_with_handle(http, accetp_fd);
|
bound = evhttp_accept_socket_with_handle(http, thread_info->accept_fd);
|
||||||
if (bound != NULL) {
|
if (bound != NULL) {
|
||||||
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Bound(%p) to port %d - Awaiting connections ... ", bound, rte->e_port);
|
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Bound(%p) to port %d - Awaiting connections ... ", bound, rte->e_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_base_dispatch(base);
|
event_base_dispatch(base);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@@ -1083,6 +1078,10 @@ int libevent_socket_init()
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* one way to set the necessary OpenSSL locking callbacks if you want to do
|
||||||
|
multi-threaded transfers with HTTPS/FTPS built to use OpenSSL **/
|
||||||
|
thread_setup();
|
||||||
|
|
||||||
threads = calloc(thread_nu, sizeof(libevent_thread));
|
threads = calloc(thread_nu, sizeof(libevent_thread));
|
||||||
if (! threads) {
|
if (! threads) {
|
||||||
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Can't allocate thread descriptors");
|
mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Can't allocate thread descriptors");
|
||||||
@@ -1108,7 +1107,7 @@ int libevent_socket_init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_t perform;
|
rt_pthread perform;
|
||||||
long thread_id = 5;
|
long thread_id = 5;
|
||||||
pthread_create(&perform, NULL, do_perform_monitor, (void *) thread_id);
|
pthread_create(&perform, NULL, do_perform_monitor, (void *) thread_id);
|
||||||
|
|
||||||
@@ -1119,6 +1118,7 @@ int libevent_socket_init()
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_cleanup();
|
||||||
finish:
|
finish:
|
||||||
return xret;
|
return xret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ typedef struct {
|
|||||||
|
|
||||||
rt_pthread_attr *attr;
|
rt_pthread_attr *attr;
|
||||||
|
|
||||||
|
EVP_PKEY *key;
|
||||||
|
|
||||||
|
X509 *root;
|
||||||
|
|
||||||
|
struct redisAsyncContext *cl_ctx;
|
||||||
|
|
||||||
void * (*routine)(void *); /** Executive entry */
|
void * (*routine)(void *); /** Executive entry */
|
||||||
} libevent_thread;
|
} libevent_thread;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user