diff options
author | Ben Magistro <koncept1@gmail.com> | 2022-04-17 09:45:02 -0400 |
---|---|---|
committer | Ben Magistro <koncept1@gmail.com> | 2022-04-20 21:30:13 -0400 |
commit | bf8c01bfcd015d43cfbcb893e48c6a83a95c91ec (patch) | |
tree | d4871f553a40aaed8cf98165f1e4f07584cfb95e /app/nginx/src/event | |
parent | 862937c477a3d90798a5e4c4e84fc7c79aae52fe (diff) |
Drop nginxdev-mitm-proxy
Nginx is not part of the core library being developed and needs to
be moved to its own repository to allow it to be more easily
maintained.
Signed-off-by: Ben Magistro <koncept1@gmail.com>
Change-Id: I5639e84ba0564ccd49ffcffa7ec9fcd57827bd6d
Diffstat (limited to 'app/nginx/src/event')
25 files changed, 0 insertions, 16068 deletions
diff --git a/app/nginx/src/event/modules/ngx_devpoll_module.c b/app/nginx/src/event/modules/ngx_devpoll_module.c deleted file mode 100644 index ee9f854..0000000 --- a/app/nginx/src/event/modules/ngx_devpoll_module.c +++ /dev/null @@ -1,560 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#if (NGX_TEST_BUILD_DEVPOLL) - -/* Solaris declarations */ - -#ifndef POLLREMOVE -#define POLLREMOVE 0x0800 -#endif -#define DP_POLL 0xD001 -#define DP_ISPOLLED 0xD002 - -struct dvpoll { - struct pollfd *dp_fds; - int dp_nfds; - int dp_timeout; -}; - -#endif - - -typedef struct { - ngx_uint_t changes; - ngx_uint_t events; -} ngx_devpoll_conf_t; - - -static ngx_int_t ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static void ngx_devpoll_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_devpoll_process_events(ngx_cycle_t *cycle, - ngx_msec_t timer, ngx_uint_t flags); - -static void *ngx_devpoll_create_conf(ngx_cycle_t *cycle); -static char *ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf); - -static int dp = -1; -static struct pollfd *change_list, *event_list; -static ngx_uint_t nchanges, max_changes, nevents; - -static ngx_event_t **change_index; - - -static ngx_str_t devpoll_name = ngx_string("/dev/poll"); - -static ngx_command_t ngx_devpoll_commands[] = { - - { ngx_string("devpoll_changes"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_devpoll_conf_t, changes), - NULL }, - - { ngx_string("devpoll_events"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_devpoll_conf_t, events), - NULL }, - - ngx_null_command -}; - - -static ngx_event_module_t ngx_devpoll_module_ctx = { - &devpoll_name, - ngx_devpoll_create_conf, /* create configuration */ - ngx_devpoll_init_conf, /* init configuration */ - - { - ngx_devpoll_add_event, /* add an event */ - ngx_devpoll_del_event, /* delete an event */ - ngx_devpoll_add_event, /* enable an event */ - ngx_devpoll_del_event, /* disable an event */ - NULL, /* add an connection */ - NULL, /* delete an connection */ - NULL, /* trigger a notify */ - ngx_devpoll_process_events, /* process the events */ - ngx_devpoll_init, /* init the events */ - ngx_devpoll_done, /* done the events */ - } - -}; - -ngx_module_t ngx_devpoll_module = { - NGX_MODULE_V1, - &ngx_devpoll_module_ctx, /* module context */ - ngx_devpoll_commands, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - size_t n; - ngx_devpoll_conf_t *dpcf; - - dpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_devpoll_module); - - if (dp == -1) { - dp = open("/dev/poll", O_RDWR); - - if (dp == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "open(/dev/poll) failed"); - return NGX_ERROR; - } - } - - if (max_changes < dpcf->changes) { - if (nchanges) { - n = nchanges * sizeof(struct pollfd); - if (write(dp, change_list, n) != (ssize_t) n) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "write(/dev/poll) failed"); - return NGX_ERROR; - } - - nchanges = 0; - } - - if (change_list) { - ngx_free(change_list); - } - - change_list = ngx_alloc(sizeof(struct pollfd) * dpcf->changes, - cycle->log); - if (change_list == NULL) { - return NGX_ERROR; - } - - if (change_index) { - ngx_free(change_index); - } - - change_index = ngx_alloc(sizeof(ngx_event_t *) * dpcf->changes, - cycle->log); - if (change_index == NULL) { - return NGX_ERROR; - } - } - - max_changes = dpcf->changes; - - if (nevents < dpcf->events) { - if (event_list) { - ngx_free(event_list); - } - - event_list = ngx_alloc(sizeof(struct pollfd) * dpcf->events, - cycle->log); - if (event_list == NULL) { - return NGX_ERROR; - } - } - - nevents = dpcf->events; - - ngx_io = ngx_os_io; - - ngx_event_actions = ngx_devpoll_module_ctx.actions; - - ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT; - - return NGX_OK; -} - - -static void -ngx_devpoll_done(ngx_cycle_t *cycle) -{ - if (close(dp) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close(/dev/poll) failed"); - } - - dp = -1; - - ngx_free(change_list); - ngx_free(event_list); - ngx_free(change_index); - - change_list = NULL; - event_list = NULL; - change_index = NULL; - max_changes = 0; - nchanges = 0; - nevents = 0; -} - - -static ngx_int_t -ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ -#if (NGX_DEBUG) - ngx_connection_t *c; -#endif - -#if (NGX_READ_EVENT != POLLIN) - event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT; -#endif - -#if (NGX_DEBUG) - c = ev->data; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "devpoll add event: fd:%d ev:%04Xi", c->fd, event); -#endif - - ev->active = 1; - - return ngx_devpoll_set_event(ev, event, 0); -} - - -static ngx_int_t -ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_event_t *e; - ngx_connection_t *c; - - c = ev->data; - -#if (NGX_READ_EVENT != POLLIN) - event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT; -#endif - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "devpoll del event: fd:%d ev:%04Xi", c->fd, event); - - if (ngx_devpoll_set_event(ev, POLLREMOVE, flags) == NGX_ERROR) { - return NGX_ERROR; - } - - ev->active = 0; - - if (flags & NGX_CLOSE_EVENT) { - e = (event == POLLIN) ? c->write : c->read; - - if (e) { - e->active = 0; - } - - return NGX_OK; - } - - /* restore the pair event if it exists */ - - if (event == POLLIN) { - e = c->write; - event = POLLOUT; - - } else { - e = c->read; - event = POLLIN; - } - - if (e && e->active) { - return ngx_devpoll_set_event(e, event, 0); - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - size_t n; - ngx_connection_t *c; - - c = ev->data; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "devpoll fd:%d ev:%04Xi fl:%04Xi", c->fd, event, flags); - - if (nchanges >= max_changes) { - ngx_log_error(NGX_LOG_WARN, ev->log, 0, - "/dev/pool change list is filled up"); - - n = nchanges * sizeof(struct pollfd); - if (write(dp, change_list, n) != (ssize_t) n) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "write(/dev/poll) failed"); - return NGX_ERROR; - } - - nchanges = 0; - } - - change_list[nchanges].fd = c->fd; - change_list[nchanges].events = (short) event; - change_list[nchanges].revents = 0; - - change_index[nchanges] = ev; - ev->index = nchanges; - - nchanges++; - - if (flags & NGX_CLOSE_EVENT) { - n = nchanges * sizeof(struct pollfd); - if (write(dp, change_list, n) != (ssize_t) n) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "write(/dev/poll) failed"); - return NGX_ERROR; - } - - nchanges = 0; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags) -{ - int events, revents, rc; - size_t n; - ngx_fd_t fd; - ngx_err_t err; - ngx_int_t i; - ngx_uint_t level, instance; - ngx_event_t *rev, *wev; - ngx_queue_t *queue; - ngx_connection_t *c; - struct pollfd pfd; - struct dvpoll dvp; - - /* NGX_TIMER_INFINITE == INFTIM */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "devpoll timer: %M", timer); - - if (nchanges) { - n = nchanges * sizeof(struct pollfd); - if (write(dp, change_list, n) != (ssize_t) n) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "write(/dev/poll) failed"); - return NGX_ERROR; - } - - nchanges = 0; - } - - dvp.dp_fds = event_list; - dvp.dp_nfds = (int) nevents; - dvp.dp_timeout = timer; - events = ioctl(dp, DP_POLL, &dvp); - - err = (events == -1) ? ngx_errno : 0; - - if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { - ngx_time_update(); - } - - if (err) { - if (err == NGX_EINTR) { - - if (ngx_event_timer_alarm) { - ngx_event_timer_alarm = 0; - return NGX_OK; - } - - level = NGX_LOG_INFO; - - } else { - level = NGX_LOG_ALERT; - } - - ngx_log_error(level, cycle->log, err, "ioctl(DP_POLL) failed"); - return NGX_ERROR; - } - - if (events == 0) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "ioctl(DP_POLL) returned no events without timeout"); - return NGX_ERROR; - } - - for (i = 0; i < events; i++) { - - fd = event_list[i].fd; - revents = event_list[i].revents; - - c = ngx_cycle->files[fd]; - - if (c == NULL || c->fd == -1) { - - pfd.fd = fd; - pfd.events = 0; - pfd.revents = 0; - - rc = ioctl(dp, DP_ISPOLLED, &pfd); - - switch (rc) { - - case -1: - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "ioctl(DP_ISPOLLED) failed for socket %d, event %04Xd", - fd, revents); - break; - - case 0: - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "phantom event %04Xd for closed and removed socket %d", - revents, fd); - break; - - default: - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "unexpected event %04Xd for closed and removed socket %d, " - "ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd", - revents, fd, rc, pfd.fd, pfd.revents); - - pfd.fd = fd; - pfd.events = POLLREMOVE; - pfd.revents = 0; - - if (write(dp, &pfd, sizeof(struct pollfd)) - != (ssize_t) sizeof(struct pollfd)) - { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "write(/dev/poll) for %d failed", fd); - } - - if (close(fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close(%d) failed", fd); - } - - break; - } - - continue; - } - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "devpoll: fd:%d, ev:%04Xd, rev:%04Xd", - fd, event_list[i].events, revents); - - if (revents & (POLLERR|POLLHUP|POLLNVAL)) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd", - fd, event_list[i].events, revents); - } - - if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "strange ioctl(DP_POLL) events " - "fd:%d ev:%04Xd rev:%04Xd", - fd, event_list[i].events, revents); - } - - if (revents & (POLLERR|POLLHUP|POLLNVAL)) { - - /* - * if the error events were returned, add POLLIN and POLLOUT - * to handle the events at least in one active handler - */ - - revents |= POLLIN|POLLOUT; - } - - rev = c->read; - - if ((revents & POLLIN) && rev->active) { - rev->ready = 1; - - if (flags & NGX_POST_EVENTS) { - queue = rev->accept ? &ngx_posted_accept_events - : &ngx_posted_events; - - ngx_post_event(rev, queue); - - } else { - instance = rev->instance; - - rev->handler(rev); - - if (c->fd == -1 || rev->instance != instance) { - continue; - } - } - } - - wev = c->write; - - if ((revents & POLLOUT) && wev->active) { - wev->ready = 1; - - if (flags & NGX_POST_EVENTS) { - ngx_post_event(wev, &ngx_posted_events); - - } else { - wev->handler(wev); - } - } - } - - return NGX_OK; -} - - -static void * -ngx_devpoll_create_conf(ngx_cycle_t *cycle) -{ - ngx_devpoll_conf_t *dpcf; - - dpcf = ngx_palloc(cycle->pool, sizeof(ngx_devpoll_conf_t)); - if (dpcf == NULL) { - return NULL; - } - - dpcf->changes = NGX_CONF_UNSET; - dpcf->events = NGX_CONF_UNSET; - - return dpcf; -} - - -static char * -ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_devpoll_conf_t *dpcf = conf; - - ngx_conf_init_uint_value(dpcf->changes, 32); - ngx_conf_init_uint_value(dpcf->events, 32); - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/modules/ngx_epoll_module.c b/app/nginx/src/event/modules/ngx_epoll_module.c deleted file mode 100644 index 76aee08..0000000 --- a/app/nginx/src/event/modules/ngx_epoll_module.c +++ /dev/null @@ -1,1052 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#if (NGX_TEST_BUILD_EPOLL) - -/* epoll declarations */ - -#define EPOLLIN 0x001 -#define EPOLLPRI 0x002 -#define EPOLLOUT 0x004 -#define EPOLLERR 0x008 -#define EPOLLHUP 0x010 -#define EPOLLRDNORM 0x040 -#define EPOLLRDBAND 0x080 -#define EPOLLWRNORM 0x100 -#define EPOLLWRBAND 0x200 -#define EPOLLMSG 0x400 - -#define EPOLLRDHUP 0x2000 - -#define EPOLLEXCLUSIVE 0x10000000 -#define EPOLLONESHOT 0x40000000 -#define EPOLLET 0x80000000 - -#define EPOLL_CTL_ADD 1 -#define EPOLL_CTL_DEL 2 -#define EPOLL_CTL_MOD 3 - -typedef union epoll_data { - void *ptr; - int fd; - uint32_t u32; - uint64_t u64; -} epoll_data_t; - -struct epoll_event { - uint32_t events; - epoll_data_t data; -}; - - -int epoll_create(int size); - -int epoll_create(int size) -{ - return -1; -} - - -int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); - -int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) -{ - return -1; -} - - -int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout); - -int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout) -{ - return -1; -} - -#if (NGX_HAVE_EVENTFD) -#define SYS_eventfd 323 -#endif - -#if (NGX_HAVE_FILE_AIO) - -#define SYS_io_setup 245 -#define SYS_io_destroy 246 -#define SYS_io_getevents 247 - -typedef u_int aio_context_t; - -struct io_event { - uint64_t data; /* the data field from the iocb */ - uint64_t obj; /* what iocb this event came from */ - int64_t res; /* result code for this event */ - int64_t res2; /* secondary result */ -}; - - -#endif -#endif /* NGX_TEST_BUILD_EPOLL */ - - -typedef struct { - ngx_uint_t events; - ngx_uint_t aio_requests; -} ngx_epoll_conf_t; - - -static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer); -#if (NGX_HAVE_EVENTFD) -static ngx_int_t ngx_epoll_notify_init(ngx_log_t *log); -static void ngx_epoll_notify_handler(ngx_event_t *ev); -#endif -#if (NGX_HAVE_EPOLLRDHUP) -static void ngx_epoll_test_rdhup(ngx_cycle_t *cycle); -#endif -static void ngx_epoll_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_epoll_add_connection(ngx_connection_t *c); -static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c, - ngx_uint_t flags); -#if (NGX_HAVE_EVENTFD) -static ngx_int_t ngx_epoll_notify(ngx_event_handler_pt handler); -#endif -static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); - -#if (NGX_HAVE_FILE_AIO) -static void ngx_epoll_eventfd_handler(ngx_event_t *ev); -#endif - -static void *ngx_epoll_create_conf(ngx_cycle_t *cycle); -static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf); - -static int ep = -1; -static struct epoll_event *event_list; -static ngx_uint_t nevents; - -#if (NGX_HAVE_EVENTFD) -static int notify_fd = -1; -static ngx_event_t notify_event; -static ngx_connection_t notify_conn; -#endif - -#if (NGX_HAVE_FILE_AIO) - -int ngx_eventfd = -1; -aio_context_t ngx_aio_ctx = 0; - -static ngx_event_t ngx_eventfd_event; -static ngx_connection_t ngx_eventfd_conn; - -#endif - -#if (NGX_HAVE_EPOLLRDHUP) -ngx_uint_t ngx_use_epoll_rdhup; -#endif - -static ngx_str_t epoll_name = ngx_string("epoll"); - -static ngx_command_t ngx_epoll_commands[] = { - - { ngx_string("epoll_events"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_epoll_conf_t, events), - NULL }, - - { ngx_string("worker_aio_requests"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_epoll_conf_t, aio_requests), - NULL }, - - ngx_null_command -}; - - -static ngx_event_module_t ngx_epoll_module_ctx = { - &epoll_name, - ngx_epoll_create_conf, /* create configuration */ - ngx_epoll_init_conf, /* init configuration */ - - { - ngx_epoll_add_event, /* add an event */ - ngx_epoll_del_event, /* delete an event */ - ngx_epoll_add_event, /* enable an event */ - ngx_epoll_del_event, /* disable an event */ - ngx_epoll_add_connection, /* add an connection */ - ngx_epoll_del_connection, /* delete an connection */ -#if (NGX_HAVE_EVENTFD) - ngx_epoll_notify, /* trigger a notify */ -#else - NULL, /* trigger a notify */ -#endif - ngx_epoll_process_events, /* process the events */ - ngx_epoll_init, /* init the events */ - ngx_epoll_done, /* done the events */ - } -}; - -ngx_module_t ngx_epoll_module = { - NGX_MODULE_V1, - &ngx_epoll_module_ctx, /* module context */ - ngx_epoll_commands, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -#if (NGX_HAVE_FILE_AIO) - -/* - * We call io_setup(), io_destroy() io_submit(), and io_getevents() directly - * as syscalls instead of libaio usage, because the library header file - * supports eventfd() since 0.3.107 version only. - */ - -static int -io_setup(u_int nr_reqs, aio_context_t *ctx) -{ - return syscall(SYS_io_setup, nr_reqs, ctx); -} - - -static int -io_destroy(aio_context_t ctx) -{ - return syscall(SYS_io_destroy, ctx); -} - - -static int -io_getevents(aio_context_t ctx, long min_nr, long nr, struct io_event *events, - struct timespec *tmo) -{ - return syscall(SYS_io_getevents, ctx, min_nr, nr, events, tmo); -} - - -static void -ngx_epoll_aio_init(ngx_cycle_t *cycle, ngx_epoll_conf_t *epcf) -{ - int n; - struct epoll_event ee; - -#if (NGX_HAVE_SYS_EVENTFD_H) - ngx_eventfd = eventfd(0, 0); -#else - ngx_eventfd = syscall(SYS_eventfd, 0); -#endif - - if (ngx_eventfd == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "eventfd() failed"); - ngx_file_aio = 0; - return; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "eventfd: %d", ngx_eventfd); - - n = 1; - - if (ioctl(ngx_eventfd, FIONBIO, &n) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "ioctl(eventfd, FIONBIO) failed"); - goto failed; - } - - if (io_setup(epcf->aio_requests, &ngx_aio_ctx) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "io_setup() failed"); - goto failed; - } - - ngx_eventfd_event.data = &ngx_eventfd_conn; - ngx_eventfd_event.handler = ngx_epoll_eventfd_handler; - ngx_eventfd_event.log = cycle->log; - ngx_eventfd_event.active = 1; - ngx_eventfd_conn.fd = ngx_eventfd; - ngx_eventfd_conn.read = &ngx_eventfd_event; - ngx_eventfd_conn.log = cycle->log; - - ee.events = EPOLLIN|EPOLLET; - ee.data.ptr = &ngx_eventfd_conn; - - if (epoll_ctl(ep, EPOLL_CTL_ADD, ngx_eventfd, &ee) != -1) { - return; - } - - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "epoll_ctl(EPOLL_CTL_ADD, eventfd) failed"); - - if (io_destroy(ngx_aio_ctx) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "io_destroy() failed"); - } - -failed: - - if (close(ngx_eventfd) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "eventfd close() failed"); - } - - ngx_eventfd = -1; - ngx_aio_ctx = 0; - ngx_file_aio = 0; -} - -#endif - - -static ngx_int_t -ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - ngx_epoll_conf_t *epcf; - - epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module); - - if (ep == -1) { - ep = epoll_create(cycle->connection_n / 2); - - if (ep == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "epoll_create() failed"); - return NGX_ERROR; - } - -#if (NGX_HAVE_EVENTFD) - if (ngx_epoll_notify_init(cycle->log) != NGX_OK) { - ngx_epoll_module_ctx.actions.notify = NULL; - } -#endif - -#if (NGX_HAVE_FILE_AIO) - ngx_epoll_aio_init(cycle, epcf); -#endif - -#if (NGX_HAVE_EPOLLRDHUP) - ngx_epoll_test_rdhup(cycle); -#endif - } - - if (nevents < epcf->events) { - if (event_list) { - ngx_free(event_list); - } - - event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events, - cycle->log); - if (event_list == NULL) { - return NGX_ERROR; - } - } - - nevents = epcf->events; - - ngx_io = ngx_os_io; - - ngx_event_actions = ngx_epoll_module_ctx.actions; - -#if (NGX_HAVE_CLEAR_EVENT) - ngx_event_flags = NGX_USE_CLEAR_EVENT -#else - ngx_event_flags = NGX_USE_LEVEL_EVENT -#endif - |NGX_USE_GREEDY_EVENT - |NGX_USE_EPOLL_EVENT; - - return NGX_OK; -} - - -#if (NGX_HAVE_EVENTFD) - -static ngx_int_t -ngx_epoll_notify_init(ngx_log_t *log) -{ - struct epoll_event ee; - -#if (NGX_HAVE_SYS_EVENTFD_H) - notify_fd = eventfd(0, 0); -#else - notify_fd = syscall(SYS_eventfd, 0); -#endif - - if (notify_fd == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "eventfd() failed"); - return NGX_ERROR; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, - "notify eventfd: %d", notify_fd); - - notify_event.handler = ngx_epoll_notify_handler; - notify_event.log = log; - notify_event.active = 1; - - notify_conn.fd = notify_fd; - notify_conn.read = ¬ify_event; - notify_conn.log = log; - - ee.events = EPOLLIN|EPOLLET; - ee.data.ptr = ¬ify_conn; - - if (epoll_ctl(ep, EPOLL_CTL_ADD, notify_fd, &ee) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, - "epoll_ctl(EPOLL_CTL_ADD, eventfd) failed"); - - if (close(notify_fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "eventfd close() failed"); - } - - return NGX_ERROR; - } - - return NGX_OK; -} - - -static void -ngx_epoll_notify_handler(ngx_event_t *ev) -{ - ssize_t n; - uint64_t count; - ngx_err_t err; - ngx_event_handler_pt handler; - - if (++ev->index == NGX_MAX_UINT32_VALUE) { - ev->index = 0; - - n = read(notify_fd, &count, sizeof(uint64_t)); - - err = ngx_errno; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "read() eventfd %d: %z count:%uL", notify_fd, n, count); - - if ((size_t) n != sizeof(uint64_t)) { - ngx_log_error(NGX_LOG_ALERT, ev->log, err, - "read() eventfd %d failed", notify_fd); - } - } - - handler = ev->data; - handler(ev); -} - -#endif - - -#if (NGX_HAVE_EPOLLRDHUP) - -static void -ngx_epoll_test_rdhup(ngx_cycle_t *cycle) -{ - int s[2], events; - struct epoll_event ee; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "socketpair() failed"); - return; - } - - ee.events = EPOLLET|EPOLLIN|EPOLLRDHUP; - - if (epoll_ctl(ep, EPOLL_CTL_ADD, s[0], &ee) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "epoll_ctl() failed"); - goto failed; - } - - if (close(s[1]) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close() failed"); - s[1] = -1; - goto failed; - } - - s[1] = -1; - - events = epoll_wait(ep, &ee, 1, 5000); - - if (events == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "epoll_wait() failed"); - goto failed; - } - - if (events) { - ngx_use_epoll_rdhup = ee.events & EPOLLRDHUP; - - } else { - ngx_log_error(NGX_LOG_ALERT, cycle->log, NGX_ETIMEDOUT, - "epoll_wait() timed out"); - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "testing the EPOLLRDHUP flag: %s", - ngx_use_epoll_rdhup ? "success" : "fail"); - -failed: - - if (s[1] != -1 && close(s[1]) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close() failed"); - } - - if (close(s[0]) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close() failed"); - } -} - -#endif - - -static void -ngx_epoll_done(ngx_cycle_t *cycle) -{ - if (close(ep) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "epoll close() failed"); - } - - ep = -1; - -#if (NGX_HAVE_EVENTFD) - - if (close(notify_fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "eventfd close() failed"); - } - - notify_fd = -1; - -#endif - -#if (NGX_HAVE_FILE_AIO) - - if (ngx_eventfd != -1) { - - if (io_destroy(ngx_aio_ctx) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "io_destroy() failed"); - } - - if (close(ngx_eventfd) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "eventfd close() failed"); - } - - ngx_eventfd = -1; - } - - ngx_aio_ctx = 0; - -#endif - - ngx_free(event_list); - - event_list = NULL; - nevents = 0; -} - - -static ngx_int_t -ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - int op; - uint32_t events, prev; - ngx_event_t *e; - ngx_connection_t *c; - struct epoll_event ee; - - c = ev->data; - - events = (uint32_t) event; - - if (event == NGX_READ_EVENT) { - e = c->write; - prev = EPOLLOUT; -#if (NGX_READ_EVENT != EPOLLIN|EPOLLRDHUP) - events = EPOLLIN|EPOLLRDHUP; -#endif - - } else { - e = c->read; - prev = EPOLLIN|EPOLLRDHUP; -#if (NGX_WRITE_EVENT != EPOLLOUT) - events = EPOLLOUT; -#endif - } - - if (e->active) { - op = EPOLL_CTL_MOD; - events |= prev; - - } else { - op = EPOLL_CTL_ADD; - } - -#if (NGX_HAVE_EPOLLEXCLUSIVE && NGX_HAVE_EPOLLRDHUP) - if (flags & NGX_EXCLUSIVE_EVENT) { - events &= ~EPOLLRDHUP; - } -#endif - - ee.events = events | (uint32_t) flags; - ee.data.ptr = (void *) ((uintptr_t) c | ev->instance); - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "epoll add event: fd:%d op:%d ev:%08XD", - c->fd, op, ee.events); - - if (epoll_ctl(ep, op, c->fd, &ee) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "epoll_ctl(%d, %d) failed", op, c->fd); - return NGX_ERROR; - } - - ev->active = 1; -#if 0 - ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; -#endif - - return NGX_OK; -} - - -static ngx_int_t -ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - int op; - uint32_t prev; - ngx_event_t *e; - ngx_connection_t *c; - struct epoll_event ee; - - /* - * when the file descriptor is closed, the epoll automatically deletes - * it from its queue, so we do not need to delete explicitly the event - * before the closing the file descriptor - */ - - if (flags & NGX_CLOSE_EVENT) { - ev->active = 0; - return NGX_OK; - } - - c = ev->data; - - if (event == NGX_READ_EVENT) { - e = c->write; - prev = EPOLLOUT; - - } else { - e = c->read; - prev = EPOLLIN|EPOLLRDHUP; - } - - if (e->active) { - op = EPOLL_CTL_MOD; - ee.events = prev | (uint32_t) flags; - ee.data.ptr = (void *) ((uintptr_t) c | ev->instance); - - } else { - op = EPOLL_CTL_DEL; - ee.events = 0; - ee.data.ptr = NULL; - } - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "epoll del event: fd:%d op:%d ev:%08XD", - c->fd, op, ee.events); - - if (epoll_ctl(ep, op, c->fd, &ee) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "epoll_ctl(%d, %d) failed", op, c->fd); - return NGX_ERROR; - } - - ev->active = 0; - - return NGX_OK; -} - - -static ngx_int_t -ngx_epoll_add_connection(ngx_connection_t *c) -{ - struct epoll_event ee; - - ee.events = EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP; - ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events); - - if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->fd); - return NGX_ERROR; - } - - c->read->active = 1; - c->write->active = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_epoll_del_connection(ngx_connection_t *c, ngx_uint_t flags) -{ - int op; - struct epoll_event ee; - - /* - * when the file descriptor is closed the epoll automatically deletes - * it from its queue so we do not need to delete explicitly the event - * before the closing the file descriptor - */ - - if (flags & NGX_CLOSE_EVENT) { - c->read->active = 0; - c->write->active = 0; - return NGX_OK; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "epoll del connection: fd:%d", c->fd); - - op = EPOLL_CTL_DEL; - ee.events = 0; - ee.data.ptr = NULL; - - if (epoll_ctl(ep, op, c->fd, &ee) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "epoll_ctl(%d, %d) failed", op, c->fd); - return NGX_ERROR; - } - - c->read->active = 0; - c->write->active = 0; - - return NGX_OK; -} - - -#if (NGX_HAVE_EVENTFD) - -static ngx_int_t -ngx_epoll_notify(ngx_event_handler_pt handler) -{ - static uint64_t inc = 1; - - notify_event.data = handler; - - if ((size_t) write(notify_fd, &inc, sizeof(uint64_t)) != sizeof(uint64_t)) { - ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno, - "write() to eventfd %d failed", notify_fd); - return NGX_ERROR; - } - - return NGX_OK; -} - -#endif - - -static ngx_int_t -ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) -{ - int events; - uint32_t revents; - ngx_int_t instance, i; - ngx_uint_t level; - ngx_err_t err; - ngx_event_t *rev, *wev; - ngx_queue_t *queue; - ngx_connection_t *c; - - /* NGX_TIMER_INFINITE == INFTIM */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "epoll timer: %M", timer); - - events = epoll_wait(ep, event_list, (int) nevents, timer); - - err = (events == -1) ? ngx_errno : 0; - - if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { - ngx_time_update(); - } - - if (err) { - if (err == NGX_EINTR) { - - if (ngx_event_timer_alarm) { - ngx_event_timer_alarm = 0; - return NGX_OK; - } - - level = NGX_LOG_INFO; - - } else { - level = NGX_LOG_ALERT; - } - - ngx_log_error(level, cycle->log, err, "epoll_wait() failed"); - return NGX_ERROR; - } - - if (events == 0) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "epoll_wait() returned no events without timeout"); - return NGX_ERROR; - } - - for (i = 0; i < events; i++) { - c = event_list[i].data.ptr; - - instance = (uintptr_t) c & 1; - c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1); - - rev = c->read; - - if (c->fd == -1 || rev->instance != instance) { - - /* - * the stale event from a file descriptor - * that was just closed in this iteration - */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "epoll: stale event %p", c); - continue; - } - - revents = event_list[i].events; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "epoll: fd:%d ev:%04XD d:%p", - c->fd, revents, event_list[i].data.ptr); - - if (revents & (EPOLLERR|EPOLLHUP)) { - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "epoll_wait() error on fd:%d ev:%04XD", - c->fd, revents); - - /* - * if the error events were returned, add EPOLLIN and EPOLLOUT - * to handle the events at least in one active handler - */ - - revents |= EPOLLIN|EPOLLOUT; - } - -#if 0 - if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "strange epoll_wait() events fd:%d ev:%04XD", - c->fd, revents); - } -#endif - - if ((revents & EPOLLIN) && rev->active) { - -#if (NGX_HAVE_EPOLLRDHUP) - if (revents & EPOLLRDHUP) { - rev->pending_eof = 1; - } - - rev->available = 1; -#endif - - rev->ready = 1; - - if (flags & NGX_POST_EVENTS) { - queue = rev->accept ? &ngx_posted_accept_events - : &ngx_posted_events; - - ngx_post_event(rev, queue); - - } else { - rev->handler(rev); - } - } - - wev = c->write; - - if ((revents & EPOLLOUT) && wev->active) { - - if (c->fd == -1 || wev->instance != instance) { - - /* - * the stale event from a file descriptor - * that was just closed in this iteration - */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "epoll: stale event %p", c); - continue; - } - - wev->ready = 1; -#if (NGX_THREADS) - wev->complete = 1; -#endif - - if (flags & NGX_POST_EVENTS) { - ngx_post_event(wev, &ngx_posted_events); - - } else { - wev->handler(wev); - } - } - } - - return NGX_OK; -} - - -#if (NGX_HAVE_FILE_AIO) - -static void -ngx_epoll_eventfd_handler(ngx_event_t *ev) -{ - int n, events; - long i; - uint64_t ready; - ngx_err_t err; - ngx_event_t *e; - ngx_event_aio_t *aio; - struct io_event event[64]; - struct timespec ts; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd handler"); - - n = read(ngx_eventfd, &ready, 8); - - err = ngx_errno; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd: %d", n); - - if (n != 8) { - if (n == -1) { - if (err == NGX_EAGAIN) { - return; - } - - ngx_log_error(NGX_LOG_ALERT, ev->log, err, "read(eventfd) failed"); - return; - } - - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "read(eventfd) returned only %d bytes", n); - return; - } - - ts.tv_sec = 0; - ts.tv_nsec = 0; - - while (ready) { - - events = io_getevents(ngx_aio_ctx, 1, 64, event, &ts); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "io_getevents: %d", events); - - if (events > 0) { - ready -= events; - - for (i = 0; i < events; i++) { - - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "io_event: %XL %XL %L %L", - event[i].data, event[i].obj, - event[i].res, event[i].res2); - - e = (ngx_event_t *) (uintptr_t) event[i].data; - - e->complete = 1; - e->active = 0; - e->ready = 1; - - aio = e->data; - aio->res = event[i].res; - - ngx_post_event(e, &ngx_posted_events); - } - - continue; - } - - if (events == 0) { - return; - } - - /* events == -1 */ - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "io_getevents() failed"); - return; - } -} - -#endif - - -static void * -ngx_epoll_create_conf(ngx_cycle_t *cycle) -{ - ngx_epoll_conf_t *epcf; - - epcf = ngx_palloc(cycle->pool, sizeof(ngx_epoll_conf_t)); - if (epcf == NULL) { - return NULL; - } - - epcf->events = NGX_CONF_UNSET; - epcf->aio_requests = NGX_CONF_UNSET; - - return epcf; -} - - -static char * -ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_epoll_conf_t *epcf = conf; - - ngx_conf_init_uint_value(epcf->events, 512); - ngx_conf_init_uint_value(epcf->aio_requests, 32); - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/modules/ngx_eventport_module.c b/app/nginx/src/event/modules/ngx_eventport_module.c deleted file mode 100644 index e723f92..0000000 --- a/app/nginx/src/event/modules/ngx_eventport_module.c +++ /dev/null @@ -1,649 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#if (NGX_TEST_BUILD_EVENTPORT) - -#define ushort_t u_short -#define uint_t u_int - -#ifndef CLOCK_REALTIME -#define CLOCK_REALTIME 0 -typedef int clockid_t; -typedef void * timer_t; -#endif - -/* Solaris declarations */ - -#define PORT_SOURCE_AIO 1 -#define PORT_SOURCE_TIMER 2 -#define PORT_SOURCE_USER 3 -#define PORT_SOURCE_FD 4 -#define PORT_SOURCE_ALERT 5 -#define PORT_SOURCE_MQ 6 - -#ifndef ETIME -#define ETIME 64 -#endif - -#define SIGEV_PORT 4 - -typedef struct { - int portev_events; /* event data is source specific */ - ushort_t portev_source; /* event source */ - ushort_t portev_pad; /* port internal use */ - uintptr_t portev_object; /* source specific object */ - void *portev_user; /* user cookie */ -} port_event_t; - -typedef struct port_notify { - int portnfy_port; /* bind request(s) to port */ - void *portnfy_user; /* user defined */ -} port_notify_t; - -#if (__FreeBSD__ && __FreeBSD_version < 700005) || (NGX_DARWIN) - -typedef struct itimerspec { /* definition per POSIX.4 */ - struct timespec it_interval;/* timer period */ - struct timespec it_value; /* timer expiration */ -} itimerspec_t; - -#endif - -int port_create(void); - -int port_create(void) -{ - return -1; -} - - -int port_associate(int port, int source, uintptr_t object, int events, - void *user); - -int port_associate(int port, int source, uintptr_t object, int events, - void *user) -{ - return -1; -} - - -int port_dissociate(int port, int source, uintptr_t object); - -int port_dissociate(int port, int source, uintptr_t object) -{ - return -1; -} - - -int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget, - struct timespec *timeout); - -int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget, - struct timespec *timeout) -{ - return -1; -} - -int port_send(int port, int events, void *user); - -int port_send(int port, int events, void *user) -{ - return -1; -} - - -int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid); - -int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid) -{ - return -1; -} - - -int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, - struct itimerspec *ovalue); - -int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, - struct itimerspec *ovalue) -{ - return -1; -} - - -int timer_delete(timer_t timerid); - -int timer_delete(timer_t timerid) -{ - return -1; -} - -#endif - - -typedef struct { - ngx_uint_t events; -} ngx_eventport_conf_t; - - -static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static void ngx_eventport_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_eventport_notify(ngx_event_handler_pt handler); -static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle, - ngx_msec_t timer, ngx_uint_t flags); - -static void *ngx_eventport_create_conf(ngx_cycle_t *cycle); -static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf); - -static int ep = -1; -static port_event_t *event_list; -static ngx_uint_t nevents; -static timer_t event_timer = (timer_t) -1; -static ngx_event_t notify_event; - -static ngx_str_t eventport_name = ngx_string("eventport"); - - -static ngx_command_t ngx_eventport_commands[] = { - - { ngx_string("eventport_events"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_eventport_conf_t, events), - NULL }, - - ngx_null_command -}; - - -static ngx_event_module_t ngx_eventport_module_ctx = { - &eventport_name, - ngx_eventport_create_conf, /* create configuration */ - ngx_eventport_init_conf, /* init configuration */ - - { - ngx_eventport_add_event, /* add an event */ - ngx_eventport_del_event, /* delete an event */ - ngx_eventport_add_event, /* enable an event */ - ngx_eventport_del_event, /* disable an event */ - NULL, /* add an connection */ - NULL, /* delete an connection */ - ngx_eventport_notify, /* trigger a notify */ - ngx_eventport_process_events, /* process the events */ - ngx_eventport_init, /* init the events */ - ngx_eventport_done, /* done the events */ - } - -}; - -ngx_module_t ngx_eventport_module = { - NGX_MODULE_V1, - &ngx_eventport_module_ctx, /* module context */ - ngx_eventport_commands, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - port_notify_t pn; - struct itimerspec its; - struct sigevent sev; - ngx_eventport_conf_t *epcf; - - epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_eventport_module); - - if (ep == -1) { - ep = port_create(); - - if (ep == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "port_create() failed"); - return NGX_ERROR; - } - - notify_event.active = 1; - notify_event.log = cycle->log; - } - - if (nevents < epcf->events) { - if (event_list) { - ngx_free(event_list); - } - - event_list = ngx_alloc(sizeof(port_event_t) * epcf->events, - cycle->log); - if (event_list == NULL) { - return NGX_ERROR; - } - } - - ngx_event_flags = NGX_USE_EVENTPORT_EVENT; - - if (timer) { - ngx_memzero(&pn, sizeof(port_notify_t)); - pn.portnfy_port = ep; - - ngx_memzero(&sev, sizeof(struct sigevent)); - sev.sigev_notify = SIGEV_PORT; -#if !(NGX_TEST_BUILD_EVENTPORT) - sev.sigev_value.sival_ptr = &pn; -#endif - - if (timer_create(CLOCK_REALTIME, &sev, &event_timer) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "timer_create() failed"); - return NGX_ERROR; - } - - its.it_interval.tv_sec = timer / 1000; - its.it_interval.tv_nsec = (timer % 1000) * 1000000; - its.it_value.tv_sec = timer / 1000; - its.it_value.tv_nsec = (timer % 1000) * 1000000; - - if (timer_settime(event_timer, 0, &its, NULL) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "timer_settime() failed"); - return NGX_ERROR; - } - - ngx_event_flags |= NGX_USE_TIMER_EVENT; - } - - nevents = epcf->events; - - ngx_io = ngx_os_io; - - ngx_event_actions = ngx_eventport_module_ctx.actions; - - return NGX_OK; -} - - -static void -ngx_eventport_done(ngx_cycle_t *cycle) -{ - if (event_timer != (timer_t) -1) { - if (timer_delete(event_timer) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "timer_delete() failed"); - } - - event_timer = (timer_t) -1; - } - - if (close(ep) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close() event port failed"); - } - - ep = -1; - - ngx_free(event_list); - - event_list = NULL; - nevents = 0; -} - - -static ngx_int_t -ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_int_t events, prev; - ngx_event_t *e; - ngx_connection_t *c; - - c = ev->data; - - events = event; - - if (event == NGX_READ_EVENT) { - e = c->write; - prev = POLLOUT; -#if (NGX_READ_EVENT != POLLIN) - events = POLLIN; -#endif - - } else { - e = c->read; - prev = POLLIN; -#if (NGX_WRITE_EVENT != POLLOUT) - events = POLLOUT; -#endif - } - - if (e->oneshot) { - events |= prev; - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "eventport add event: fd:%d ev:%04Xi", c->fd, events); - - if (port_associate(ep, PORT_SOURCE_FD, c->fd, events, - (void *) ((uintptr_t) ev | ev->instance)) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "port_associate() failed"); - return NGX_ERROR; - } - - ev->active = 1; - ev->oneshot = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_event_t *e; - ngx_connection_t *c; - - /* - * when the file descriptor is closed, the event port automatically - * dissociates it from the port, so we do not need to dissociate explicitly - * the event before the closing the file descriptor - */ - - if (flags & NGX_CLOSE_EVENT) { - ev->active = 0; - ev->oneshot = 0; - return NGX_OK; - } - - c = ev->data; - - if (event == NGX_READ_EVENT) { - e = c->write; - event = POLLOUT; - - } else { - e = c->read; - event = POLLIN; - } - - if (e->oneshot) { - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "eventport change event: fd:%d ev:%04Xi", c->fd, event); - - if (port_associate(ep, PORT_SOURCE_FD, c->fd, event, - (void *) ((uintptr_t) ev | ev->instance)) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "port_associate() failed"); - return NGX_ERROR; - } - - } else { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "eventport del event: fd:%d", c->fd); - - if (port_dissociate(ep, PORT_SOURCE_FD, c->fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "port_dissociate() failed"); - return NGX_ERROR; - } - } - - ev->active = 0; - ev->oneshot = 0; - - return NGX_OK; -} - - -static ngx_int_t -ngx_eventport_notify(ngx_event_handler_pt handler) -{ - notify_event.handler = handler; - - if (port_send(ep, 0, ¬ify_event) != 0) { - ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno, - "port_send() failed"); - return NGX_ERROR; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags) -{ - int n, revents; - u_int events; - ngx_err_t err; - ngx_int_t instance; - ngx_uint_t i, level; - ngx_event_t *ev, *rev, *wev; - ngx_queue_t *queue; - ngx_connection_t *c; - struct timespec ts, *tp; - - if (timer == NGX_TIMER_INFINITE) { - tp = NULL; - - } else { - ts.tv_sec = timer / 1000; - ts.tv_nsec = (timer % 1000) * 1000000; - tp = &ts; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "eventport timer: %M", timer); - - events = 1; - - n = port_getn(ep, event_list, (u_int) nevents, &events, tp); - - err = ngx_errno; - - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(); - } - - if (n == -1) { - if (err == ETIME) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "port_getn() returned no events without timeout"); - return NGX_ERROR; - } - - level = (err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT; - ngx_log_error(level, cycle->log, err, "port_getn() failed"); - return NGX_ERROR; - } - - if (events == 0) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "port_getn() returned no events without timeout"); - return NGX_ERROR; - } - - for (i = 0; i < events; i++) { - - if (event_list[i].portev_source == PORT_SOURCE_TIMER) { - ngx_time_update(); - continue; - } - - ev = event_list[i].portev_user; - - switch (event_list[i].portev_source) { - - case PORT_SOURCE_FD: - - instance = (uintptr_t) ev & 1; - ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1); - - if (ev->closed || ev->instance != instance) { - - /* - * the stale event from a file descriptor - * that was just closed in this iteration - */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "eventport: stale event %p", ev); - continue; - } - - revents = event_list[i].portev_events; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "eventport: fd:%d, ev:%04Xd", - (int) event_list[i].portev_object, revents); - - if (revents & (POLLERR|POLLHUP|POLLNVAL)) { - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "port_getn() error fd:%d ev:%04Xd", - (int) event_list[i].portev_object, revents); - } - - if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "strange port_getn() events fd:%d ev:%04Xd", - (int) event_list[i].portev_object, revents); - } - - if (revents & (POLLERR|POLLHUP|POLLNVAL)) { - - /* - * if the error events were returned, add POLLIN and POLLOUT - * to handle the events at least in one active handler - */ - - revents |= POLLIN|POLLOUT; - } - - c = ev->data; - rev = c->read; - wev = c->write; - - rev->active = 0; - wev->active = 0; - - if (revents & POLLIN) { - rev->ready = 1; - - if (flags & NGX_POST_EVENTS) { - queue = rev->accept ? &ngx_posted_accept_events - : &ngx_posted_events; - - ngx_post_event(rev, queue); - - } else { - rev->handler(rev); - - if (ev->closed || ev->instance != instance) { - continue; - } - } - - if (rev->accept) { - if (ngx_use_accept_mutex) { - ngx_accept_events = 1; - continue; - } - - if (port_associate(ep, PORT_SOURCE_FD, c->fd, POLLIN, - (void *) ((uintptr_t) ev | ev->instance)) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, - "port_associate() failed"); - return NGX_ERROR; - } - } - } - - if (revents & POLLOUT) { - wev->ready = 1; - - if (flags & NGX_POST_EVENTS) { - ngx_post_event(wev, &ngx_posted_events); - - } else { - wev->handler(wev); - } - } - - continue; - - case PORT_SOURCE_USER: - - ev->handler(ev); - - continue; - - default: - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "unexpected eventport object %d", - (int) event_list[i].portev_object); - continue; - } - } - - return NGX_OK; -} - - -static void * -ngx_eventport_create_conf(ngx_cycle_t *cycle) -{ - ngx_eventport_conf_t *epcf; - - epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t)); - if (epcf == NULL) { - return NULL; - } - - epcf->events = NGX_CONF_UNSET; - - return epcf; -} - - -static char * -ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_eventport_conf_t *epcf = conf; - - ngx_conf_init_uint_value(epcf->events, 32); - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/modules/ngx_iocp_module.c b/app/nginx/src/event/modules/ngx_iocp_module.c deleted file mode 100644 index b03944b..0000000 --- a/app/nginx/src/event/modules/ngx_iocp_module.c +++ /dev/null @@ -1,380 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> -#include <ngx_iocp_module.h> - - -static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static ngx_thread_value_t __stdcall ngx_iocp_timer(void *data); -static void ngx_iocp_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t key); -static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags); -static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); -static void *ngx_iocp_create_conf(ngx_cycle_t *cycle); -static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf); - - -static ngx_str_t iocp_name = ngx_string("iocp"); - -static ngx_command_t ngx_iocp_commands[] = { - - { ngx_string("iocp_threads"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_iocp_conf_t, threads), - NULL }, - - { ngx_string("post_acceptex"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_iocp_conf_t, post_acceptex), - NULL }, - - { ngx_string("acceptex_read"), - NGX_EVENT_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - 0, - offsetof(ngx_iocp_conf_t, acceptex_read), - NULL }, - - ngx_null_command -}; - - -static ngx_event_module_t ngx_iocp_module_ctx = { - &iocp_name, - ngx_iocp_create_conf, /* create configuration */ - ngx_iocp_init_conf, /* init configuration */ - - { - ngx_iocp_add_event, /* add an event */ - NULL, /* delete an event */ - NULL, /* enable an event */ - NULL, /* disable an event */ - NULL, /* add an connection */ - ngx_iocp_del_connection, /* delete an connection */ - NULL, /* trigger a notify */ - ngx_iocp_process_events, /* process the events */ - ngx_iocp_init, /* init the events */ - ngx_iocp_done /* done the events */ - } - -}; - -ngx_module_t ngx_iocp_module = { - NGX_MODULE_V1, - &ngx_iocp_module_ctx, /* module context */ - ngx_iocp_commands, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -ngx_os_io_t ngx_iocp_io = { - ngx_overlapped_wsarecv, - NULL, - ngx_udp_overlapped_wsarecv, - NULL, - NULL, - NULL, - ngx_overlapped_wsasend_chain, - 0 -}; - - -static HANDLE iocp; -static ngx_tid_t timer_thread; -static ngx_msec_t msec; - - -static ngx_int_t -ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - ngx_iocp_conf_t *cf; - - cf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); - - if (iocp == NULL) { - iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, - cf->threads); - } - - if (iocp == NULL) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "CreateIoCompletionPort() failed"); - return NGX_ERROR; - } - - ngx_io = ngx_iocp_io; - - ngx_event_actions = ngx_iocp_module_ctx.actions; - - ngx_event_flags = NGX_USE_IOCP_EVENT; - - if (timer == 0) { - return NGX_OK; - } - - /* - * The waitable timer could not be used, because - * GetQueuedCompletionStatus() does not set a thread to alertable state - */ - - if (timer_thread == NULL) { - - msec = timer; - - if (ngx_create_thread(&timer_thread, ngx_iocp_timer, &msec, cycle->log) - != 0) - { - return NGX_ERROR; - } - } - - ngx_event_flags |= NGX_USE_TIMER_EVENT; - - return NGX_OK; -} - - -static ngx_thread_value_t __stdcall -ngx_iocp_timer(void *data) -{ - ngx_msec_t timer = *(ngx_msec_t *) data; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, - "THREAD %p %p", &msec, data); - - for ( ;; ) { - Sleep(timer); - - ngx_time_update(); -#if 1 - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer"); -#endif - } - -#if defined(__WATCOMC__) || defined(__GNUC__) - return 0; -#endif -} - - -static void -ngx_iocp_done(ngx_cycle_t *cycle) -{ - if (CloseHandle(iocp) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "iocp CloseHandle() failed"); - } - - iocp = NULL; -} - - -static ngx_int_t -ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t key) -{ - ngx_connection_t *c; - - c = (ngx_connection_t *) ev->data; - - c->read->active = 1; - c->write->active = 1; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "iocp add: fd:%d k:%ui ov:%p", c->fd, key, &ev->ovlp); - - if (CreateIoCompletionPort((HANDLE) c->fd, iocp, key, 0) == NULL) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "CreateIoCompletionPort() failed"); - return NGX_ERROR; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags) -{ -#if 0 - if (flags & NGX_CLOSE_EVENT) { - return NGX_OK; - } - - if (CancelIo((HANDLE) c->fd) == 0) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "CancelIo() failed"); - return NGX_ERROR; - } -#endif - - return NGX_OK; -} - - -static -ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags) -{ - int rc; - u_int key; - u_long bytes; - ngx_err_t err; - ngx_msec_t delta; - ngx_event_t *ev; - ngx_event_ovlp_t *ovlp; - - if (timer == NGX_TIMER_INFINITE) { - timer = INFINITE; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "iocp timer: %M", timer); - - rc = GetQueuedCompletionStatus(iocp, &bytes, (PULONG_PTR) &key, - (LPOVERLAPPED *) &ovlp, (u_long) timer); - - if (rc == 0) { - err = ngx_errno; - } else { - err = 0; - } - - delta = ngx_current_msec; - - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(); - } - - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "iocp: %d b:%d k:%d ov:%p", rc, bytes, key, ovlp); - - if (timer != INFINITE) { - delta = ngx_current_msec - delta; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "iocp timer: %M, delta: %M", timer, delta); - } - - if (err) { - if (ovlp == NULL) { - if (err != WAIT_TIMEOUT) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - "GetQueuedCompletionStatus() failed"); - - return NGX_ERROR; - } - - return NGX_OK; - } - - ovlp->error = err; - } - - if (ovlp == NULL) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "GetQueuedCompletionStatus() returned no operation"); - return NGX_ERROR; - } - - - ev = ovlp->event; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err, "iocp event:%p", ev); - - - if (err == ERROR_NETNAME_DELETED /* the socket was closed */ - || err == ERROR_OPERATION_ABORTED /* the operation was canceled */) - { - - /* - * the WSA_OPERATION_ABORTED completion notification - * for a file descriptor that was closed - */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err, - "iocp: aborted event %p", ev); - - return NGX_OK; - } - - if (err) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - "GetQueuedCompletionStatus() returned operation error"); - } - - switch (key) { - - case NGX_IOCP_ACCEPT: - if (bytes) { - ev->ready = 1; - } - break; - - case NGX_IOCP_IO: - ev->complete = 1; - ev->ready = 1; - break; - - case NGX_IOCP_CONNECT: - ev->ready = 1; - } - - ev->available = bytes; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "iocp event handler: %p", ev->handler); - - ev->handler(ev); - - return NGX_OK; -} - - -static void * -ngx_iocp_create_conf(ngx_cycle_t *cycle) -{ - ngx_iocp_conf_t *cf; - - cf = ngx_palloc(cycle->pool, sizeof(ngx_iocp_conf_t)); - if (cf == NULL) { - return NGX_CONF_ERROR; - } - - cf->threads = NGX_CONF_UNSET; - cf->post_acceptex = NGX_CONF_UNSET; - cf->acceptex_read = NGX_CONF_UNSET; - - return cf; -} - - -static char * -ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_iocp_conf_t *cf = conf; - - ngx_conf_init_value(cf->threads, 0); - ngx_conf_init_value(cf->post_acceptex, 10); - ngx_conf_init_value(cf->acceptex_read, 1); - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/modules/ngx_iocp_module.h b/app/nginx/src/event/modules/ngx_iocp_module.h deleted file mode 100644 index dc73983..0000000 --- a/app/nginx/src/event/modules/ngx_iocp_module.h +++ /dev/null @@ -1,22 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_IOCP_MODULE_H_INCLUDED_ -#define _NGX_IOCP_MODULE_H_INCLUDED_ - - -typedef struct { - int threads; - int post_acceptex; - int acceptex_read; -} ngx_iocp_conf_t; - - -extern ngx_module_t ngx_iocp_module; - - -#endif /* _NGX_IOCP_MODULE_H_INCLUDED_ */ diff --git a/app/nginx/src/event/modules/ngx_kqueue_module.c b/app/nginx/src/event/modules/ngx_kqueue_module.c deleted file mode 100644 index 9c7244c..0000000 --- a/app/nginx/src/event/modules/ngx_kqueue_module.c +++ /dev/null @@ -1,722 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -typedef struct { - ngx_uint_t changes; - ngx_uint_t events; -} ngx_kqueue_conf_t; - - -static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer); -#ifdef EVFILT_USER -static ngx_int_t ngx_kqueue_notify_init(ngx_log_t *log); -#endif -static void ngx_kqueue_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, - ngx_uint_t flags); -#ifdef EVFILT_USER -static ngx_int_t ngx_kqueue_notify(ngx_event_handler_pt handler); -#endif -static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); -static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log, - struct kevent *kev); - -static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle); -static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf); - - -int ngx_kqueue = -1; - -static struct kevent *change_list; -static struct kevent *event_list; -static ngx_uint_t max_changes, nchanges, nevents; - -#ifdef EVFILT_USER -static ngx_event_t notify_event; -static struct kevent notify_kev; -#endif - - -static ngx_str_t kqueue_name = ngx_string("kqueue"); - -static ngx_command_t ngx_kqueue_commands[] = { - - { ngx_string("kqueue_changes"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_kqueue_conf_t, changes), - NULL }, - - { ngx_string("kqueue_events"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_kqueue_conf_t, events), - NULL }, - - ngx_null_command -}; - - -static ngx_event_module_t ngx_kqueue_module_ctx = { - &kqueue_name, - ngx_kqueue_create_conf, /* create configuration */ - ngx_kqueue_init_conf, /* init configuration */ - - { - ngx_kqueue_add_event, /* add an event */ - ngx_kqueue_del_event, /* delete an event */ - ngx_kqueue_add_event, /* enable an event */ - ngx_kqueue_del_event, /* disable an event */ - NULL, /* add an connection */ - NULL, /* delete an connection */ -#ifdef EVFILT_USER - ngx_kqueue_notify, /* trigger a notify */ -#else - NULL, /* trigger a notify */ -#endif - ngx_kqueue_process_events, /* process the events */ - ngx_kqueue_init, /* init the events */ - ngx_kqueue_done /* done the events */ - } - -}; - -ngx_module_t ngx_kqueue_module = { - NGX_MODULE_V1, - &ngx_kqueue_module_ctx, /* module context */ - ngx_kqueue_commands, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - ngx_kqueue_conf_t *kcf; - struct timespec ts; -#if (NGX_HAVE_TIMER_EVENT) - struct kevent kev; -#endif - - kcf = ngx_event_get_conf(cycle->conf_ctx, ngx_kqueue_module); - - if (ngx_kqueue == -1) { - ngx_kqueue = kqueue(); - - if (ngx_kqueue == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "kqueue() failed"); - return NGX_ERROR; - } - -#ifdef EVFILT_USER - if (ngx_kqueue_notify_init(cycle->log) != NGX_OK) { - return NGX_ERROR; - } -#endif - } - - if (max_changes < kcf->changes) { - if (nchanges) { - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "kevent() failed"); - return NGX_ERROR; - } - nchanges = 0; - } - - if (change_list) { - ngx_free(change_list); - } - - change_list = ngx_alloc(kcf->changes * sizeof(struct kevent), - cycle->log); - if (change_list == NULL) { - return NGX_ERROR; - } - } - - max_changes = kcf->changes; - - if (nevents < kcf->events) { - if (event_list) { - ngx_free(event_list); - } - - event_list = ngx_alloc(kcf->events * sizeof(struct kevent), cycle->log); - if (event_list == NULL) { - return NGX_ERROR; - } - } - - ngx_event_flags = NGX_USE_ONESHOT_EVENT - |NGX_USE_KQUEUE_EVENT - |NGX_USE_VNODE_EVENT; - -#if (NGX_HAVE_TIMER_EVENT) - - if (timer) { - kev.ident = 0; - kev.filter = EVFILT_TIMER; - kev.flags = EV_ADD|EV_ENABLE; - kev.fflags = 0; - kev.data = timer; - kev.udata = 0; - - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (kevent(ngx_kqueue, &kev, 1, NULL, 0, &ts) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "kevent(EVFILT_TIMER) failed"); - return NGX_ERROR; - } - - ngx_event_flags |= NGX_USE_TIMER_EVENT; - } - -#endif - -#if (NGX_HAVE_CLEAR_EVENT) - ngx_event_flags |= NGX_USE_CLEAR_EVENT; -#else - ngx_event_flags |= NGX_USE_LEVEL_EVENT; -#endif - -#if (NGX_HAVE_LOWAT_EVENT) - ngx_event_flags |= NGX_USE_LOWAT_EVENT; -#endif - - nevents = kcf->events; - - ngx_io = ngx_os_io; - - ngx_event_actions = ngx_kqueue_module_ctx.actions; - - return NGX_OK; -} - - -#ifdef EVFILT_USER - -static ngx_int_t -ngx_kqueue_notify_init(ngx_log_t *log) -{ - notify_kev.ident = 0; - notify_kev.filter = EVFILT_USER; - notify_kev.data = 0; - notify_kev.flags = EV_ADD|EV_CLEAR; - notify_kev.fflags = 0; - notify_kev.udata = 0; - - if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "kevent(EVFILT_USER, EV_ADD) failed"); - return NGX_ERROR; - } - - notify_event.active = 1; - notify_event.log = log; - - notify_kev.flags = 0; - notify_kev.fflags = NOTE_TRIGGER; - notify_kev.udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ¬ify_event); - - return NGX_OK; -} - -#endif - - -static void -ngx_kqueue_done(ngx_cycle_t *cycle) -{ - if (close(ngx_kqueue) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "kqueue close() failed"); - } - - ngx_kqueue = -1; - - ngx_free(change_list); - ngx_free(event_list); - - change_list = NULL; - event_list = NULL; - max_changes = 0; - nchanges = 0; - nevents = 0; -} - - -static ngx_int_t -ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_int_t rc; -#if 0 - ngx_event_t *e; - ngx_connection_t *c; -#endif - - ev->active = 1; - ev->disabled = 0; - ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; - -#if 0 - - if (ev->index < nchanges - && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1) - == (uintptr_t) ev) - { - if (change_list[ev->index].flags == EV_DISABLE) { - - /* - * if the EV_DISABLE is still not passed to a kernel - * we will not pass it - */ - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "kevent activated: %d: ft:%i", - ngx_event_ident(ev->data), event); - - if (ev->index < --nchanges) { - e = (ngx_event_t *) - ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1); - change_list[ev->index] = change_list[nchanges]; - e->index = ev->index; - } - - return NGX_OK; - } - - c = ev->data; - - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "previous event on #%d were not passed in kernel", c->fd); - - return NGX_ERROR; - } - -#endif - - rc = ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags); - - return rc; -} - - -static ngx_int_t -ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_int_t rc; - ngx_event_t *e; - - ev->active = 0; - ev->disabled = 0; - - if (ev->index < nchanges - && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1) - == (uintptr_t) ev) - { - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "kevent deleted: %d: ft:%i", - ngx_event_ident(ev->data), event); - - /* if the event is still not passed to a kernel we will not pass it */ - - nchanges--; - - if (ev->index < nchanges) { - e = (ngx_event_t *) - ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1); - change_list[ev->index] = change_list[nchanges]; - e->index = ev->index; - } - - return NGX_OK; - } - - /* - * when the file descriptor is closed the kqueue automatically deletes - * its filters so we do not need to delete explicitly the event - * before the closing the file descriptor. - */ - - if (flags & NGX_CLOSE_EVENT) { - return NGX_OK; - } - - if (flags & NGX_DISABLE_EVENT) { - ev->disabled = 1; - - } else { - flags |= EV_DELETE; - } - - rc = ngx_kqueue_set_event(ev, event, flags); - - return rc; -} - - -static ngx_int_t -ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags) -{ - struct kevent *kev; - struct timespec ts; - ngx_connection_t *c; - - c = ev->data; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "kevent set event: %d: ft:%i fl:%04Xi", - c->fd, filter, flags); - - if (nchanges >= max_changes) { - ngx_log_error(NGX_LOG_WARN, ev->log, 0, - "kqueue change list is filled up"); - - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed"); - return NGX_ERROR; - } - - nchanges = 0; - } - - kev = &change_list[nchanges]; - - kev->ident = c->fd; - kev->filter = (short) filter; - kev->flags = (u_short) flags; - kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance); - - if (filter == EVFILT_VNODE) { - kev->fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND - |NOTE_ATTRIB|NOTE_RENAME -#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \ - || __FreeBSD_version >= 500018 - |NOTE_REVOKE -#endif - ; - kev->data = 0; - - } else { -#if (NGX_HAVE_LOWAT_EVENT) - if (flags & NGX_LOWAT_EVENT) { - kev->fflags = NOTE_LOWAT; - kev->data = ev->available; - - } else { - kev->fflags = 0; - kev->data = 0; - } -#else - kev->fflags = 0; - kev->data = 0; -#endif - } - - ev->index = nchanges; - nchanges++; - - if (flags & NGX_FLUSH_EVENT) { - ts.tv_sec = 0; - ts.tv_nsec = 0; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "kevent flush"); - - if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed"); - return NGX_ERROR; - } - - nchanges = 0; - } - - return NGX_OK; -} - - -#ifdef EVFILT_USER - -static ngx_int_t -ngx_kqueue_notify(ngx_event_handler_pt handler) -{ - notify_event.handler = handler; - - if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) { - ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno, - "kevent(EVFILT_USER, NOTE_TRIGGER) failed"); - return NGX_ERROR; - } - - return NGX_OK; -} - -#endif - - -static ngx_int_t -ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags) -{ - int events, n; - ngx_int_t i, instance; - ngx_uint_t level; - ngx_err_t err; - ngx_event_t *ev; - ngx_queue_t *queue; - struct timespec ts, *tp; - - n = (int) nchanges; - nchanges = 0; - - if (timer == NGX_TIMER_INFINITE) { - tp = NULL; - - } else { - - ts.tv_sec = timer / 1000; - ts.tv_nsec = (timer % 1000) * 1000000; - - /* - * 64-bit Darwin kernel has the bug: kernel level ts.tv_nsec is - * the int32_t while user level ts.tv_nsec is the long (64-bit), - * so on the big endian PowerPC all nanoseconds are lost. - */ - -#if (NGX_DARWIN_KEVENT_BUG) - ts.tv_nsec <<= 32; -#endif - - tp = &ts; - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "kevent timer: %M, changes: %d", timer, n); - - events = kevent(ngx_kqueue, change_list, n, event_list, (int) nevents, tp); - - err = (events == -1) ? ngx_errno : 0; - - if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { - ngx_time_update(); - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "kevent events: %d", events); - - if (err) { - if (err == NGX_EINTR) { - - if (ngx_event_timer_alarm) { - ngx_event_timer_alarm = 0; - return NGX_OK; - } - - level = NGX_LOG_INFO; - - } else { - level = NGX_LOG_ALERT; - } - - ngx_log_error(level, cycle->log, err, "kevent() failed"); - return NGX_ERROR; - } - - if (events == 0) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "kevent() returned no events without timeout"); - return NGX_ERROR; - } - - for (i = 0; i < events; i++) { - - ngx_kqueue_dump_event(cycle->log, &event_list[i]); - - if (event_list[i].flags & EV_ERROR) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, event_list[i].data, - "kevent() error on %d filter:%d flags:%04Xd", - (int) event_list[i].ident, event_list[i].filter, - event_list[i].flags); - continue; - } - -#if (NGX_HAVE_TIMER_EVENT) - - if (event_list[i].filter == EVFILT_TIMER) { - ngx_time_update(); - continue; - } - -#endif - - ev = (ngx_event_t *) event_list[i].udata; - - switch (event_list[i].filter) { - - case EVFILT_READ: - case EVFILT_WRITE: - - instance = (uintptr_t) ev & 1; - ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1); - - if (ev->closed || ev->instance != instance) { - - /* - * the stale event from a file descriptor - * that was just closed in this iteration - */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "kevent: stale event %p", ev); - continue; - } - - if (ev->log && (ev->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { - ngx_kqueue_dump_event(ev->log, &event_list[i]); - } - - if (ev->oneshot) { - ev->active = 0; - } - - ev->available = event_list[i].data; - - if (event_list[i].flags & EV_EOF) { - ev->pending_eof = 1; - ev->kq_errno = event_list[i].fflags; - } - - ev->ready = 1; - - break; - - case EVFILT_VNODE: - ev->kq_vnode = 1; - - break; - - case EVFILT_AIO: - ev->complete = 1; - ev->ready = 1; - - break; - -#ifdef EVFILT_USER - case EVFILT_USER: - break; -#endif - - default: - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "unexpected kevent() filter %d", - event_list[i].filter); - continue; - } - - if (flags & NGX_POST_EVENTS) { - queue = ev->accept ? &ngx_posted_accept_events - : &ngx_posted_events; - - ngx_post_event(ev, queue); - - continue; - } - - ev->handler(ev); - } - - return NGX_OK; -} - - -static ngx_inline void -ngx_kqueue_dump_event(ngx_log_t *log, struct kevent *kev) -{ - if (kev->ident > 0x8000000 && kev->ident != (unsigned) -1) { - ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0, - "kevent: %p: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p", - (void *) kev->ident, kev->filter, - kev->flags, kev->fflags, - (int) kev->data, kev->udata); - - } else { - ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0, - "kevent: %d: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p", - (int) kev->ident, kev->filter, - kev->flags, kev->fflags, - (int) kev->data, kev->udata); - } -} - - -static void * -ngx_kqueue_create_conf(ngx_cycle_t *cycle) -{ - ngx_kqueue_conf_t *kcf; - - kcf = ngx_palloc(cycle->pool, sizeof(ngx_kqueue_conf_t)); - if (kcf == NULL) { - return NULL; - } - - kcf->changes = NGX_CONF_UNSET; - kcf->events = NGX_CONF_UNSET; - - return kcf; -} - - -static char * -ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_kqueue_conf_t *kcf = conf; - - ngx_conf_init_uint_value(kcf->changes, 512); - ngx_conf_init_uint_value(kcf->events, 512); - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/modules/ngx_poll_module.c b/app/nginx/src/event/modules/ngx_poll_module.c deleted file mode 100644 index 4e03dab..0000000 --- a/app/nginx/src/event/modules/ngx_poll_module.c +++ /dev/null @@ -1,415 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -static ngx_int_t ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static void ngx_poll_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); -static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf); - - -static struct pollfd *event_list; -static ngx_uint_t nevents; - - -static ngx_str_t poll_name = ngx_string("poll"); - -static ngx_event_module_t ngx_poll_module_ctx = { - &poll_name, - NULL, /* create configuration */ - ngx_poll_init_conf, /* init configuration */ - - { - ngx_poll_add_event, /* add an event */ - ngx_poll_del_event, /* delete an event */ - ngx_poll_add_event, /* enable an event */ - ngx_poll_del_event, /* disable an event */ - NULL, /* add an connection */ - NULL, /* delete an connection */ - NULL, /* trigger a notify */ - ngx_poll_process_events, /* process the events */ - ngx_poll_init, /* init the events */ - ngx_poll_done /* done the events */ - } - -}; - -ngx_module_t ngx_poll_module = { - NGX_MODULE_V1, - &ngx_poll_module_ctx, /* module context */ - NULL, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - - -static ngx_int_t -ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - struct pollfd *list; - - if (event_list == NULL) { - nevents = 0; - } - - if (ngx_process >= NGX_PROCESS_WORKER - || cycle->old_cycle == NULL - || cycle->old_cycle->connection_n < cycle->connection_n) - { - list = ngx_alloc(sizeof(struct pollfd) * cycle->connection_n, - cycle->log); - if (list == NULL) { - return NGX_ERROR; - } - - if (event_list) { - ngx_memcpy(list, event_list, sizeof(ngx_event_t *) * nevents); - ngx_free(event_list); - } - - event_list = list; - } - - ngx_io = ngx_os_io; - - ngx_event_actions = ngx_poll_module_ctx.actions; - - ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT; - - return NGX_OK; -} - - -static void -ngx_poll_done(ngx_cycle_t *cycle) -{ - ngx_free(event_list); - - event_list = NULL; -} - - -static ngx_int_t -ngx_poll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_event_t *e; - ngx_connection_t *c; - - c = ev->data; - - ev->active = 1; - - if (ev->index != NGX_INVALID_INDEX) { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "poll event fd:%d ev:%i is already set", c->fd, event); - return NGX_OK; - } - - if (event == NGX_READ_EVENT) { - e = c->write; -#if (NGX_READ_EVENT != POLLIN) - event = POLLIN; -#endif - - } else { - e = c->read; -#if (NGX_WRITE_EVENT != POLLOUT) - event = POLLOUT; -#endif - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "poll add event: fd:%d ev:%i", c->fd, event); - - if (e == NULL || e->index == NGX_INVALID_INDEX) { - event_list[nevents].fd = c->fd; - event_list[nevents].events = (short) event; - event_list[nevents].revents = 0; - - ev->index = nevents; - nevents++; - - } else { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "poll add index: %i", e->index); - - event_list[e->index].events |= (short) event; - ev->index = e->index; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_event_t *e; - ngx_connection_t *c; - - c = ev->data; - - ev->active = 0; - - if (ev->index == NGX_INVALID_INDEX) { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "poll event fd:%d ev:%i is already deleted", - c->fd, event); - return NGX_OK; - } - - if (event == NGX_READ_EVENT) { - e = c->write; -#if (NGX_READ_EVENT != POLLIN) - event = POLLIN; -#endif - - } else { - e = c->read; -#if (NGX_WRITE_EVENT != POLLOUT) - event = POLLOUT; -#endif - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "poll del event: fd:%d ev:%i", c->fd, event); - - if (e == NULL || e->index == NGX_INVALID_INDEX) { - nevents--; - - if (ev->index < nevents) { - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "index: copy event %ui to %i", nevents, ev->index); - - event_list[ev->index] = event_list[nevents]; - - c = ngx_cycle->files[event_list[nevents].fd]; - - if (c->fd == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "unexpected last event"); - - } else { - if (c->read->index == nevents) { - c->read->index = ev->index; - } - - if (c->write->index == nevents) { - c->write->index = ev->index; - } - } - } - - } else { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "poll del index: %i", e->index); - - event_list[e->index].events &= (short) ~event; - } - - ev->index = NGX_INVALID_INDEX; - - return NGX_OK; -} - - -static ngx_int_t -ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) -{ - int ready, revents; - ngx_err_t err; - ngx_uint_t i, found, level; - ngx_event_t *ev; - ngx_queue_t *queue; - ngx_connection_t *c; - - /* NGX_TIMER_INFINITE == INFTIM */ - -#if (NGX_DEBUG0) - if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { - for (i = 0; i < nevents; i++) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "poll: %ui: fd:%d ev:%04Xd", - i, event_list[i].fd, event_list[i].events); - } - } -#endif - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %M", timer); - - ready = poll(event_list, (u_int) nevents, (int) timer); - - err = (ready == -1) ? ngx_errno : 0; - - if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { - ngx_time_update(); - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "poll ready %d of %ui", ready, nevents); - - if (err) { - if (err == NGX_EINTR) { - - if (ngx_event_timer_alarm) { - ngx_event_timer_alarm = 0; - return NGX_OK; - } - - level = NGX_LOG_INFO; - - } else { - level = NGX_LOG_ALERT; - } - - ngx_log_error(level, cycle->log, err, "poll() failed"); - return NGX_ERROR; - } - - if (ready == 0) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "poll() returned no events without timeout"); - return NGX_ERROR; - } - - for (i = 0; i < nevents && ready; i++) { - - revents = event_list[i].revents; - -#if 1 - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "poll: %ui: fd:%d ev:%04Xd rev:%04Xd", - i, event_list[i].fd, event_list[i].events, revents); -#else - if (revents) { - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "poll: %ui: fd:%d ev:%04Xd rev:%04Xd", - i, event_list[i].fd, event_list[i].events, revents); - } -#endif - - if (revents & POLLNVAL) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "poll() error fd:%d ev:%04Xd rev:%04Xd", - event_list[i].fd, event_list[i].events, revents); - } - - if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "strange poll() events fd:%d ev:%04Xd rev:%04Xd", - event_list[i].fd, event_list[i].events, revents); - } - - if (event_list[i].fd == -1) { - /* - * the disabled event, a workaround for our possible bug, - * see the comment below - */ - continue; - } - - c = ngx_cycle->files[event_list[i].fd]; - - if (c->fd == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event"); - - /* - * it is certainly our fault and it should be investigated, - * in the meantime we disable this event to avoid a CPU spinning - */ - - if (i == nevents - 1) { - nevents--; - } else { - event_list[i].fd = -1; - } - - continue; - } - - if (revents & (POLLERR|POLLHUP|POLLNVAL)) { - - /* - * if the error events were returned, add POLLIN and POLLOUT - * to handle the events at least in one active handler - */ - - revents |= POLLIN|POLLOUT; - } - - found = 0; - - if ((revents & POLLIN) && c->read->active) { - found = 1; - - ev = c->read; - ev->ready = 1; - - queue = ev->accept ? &ngx_posted_accept_events - : &ngx_posted_events; - - ngx_post_event(ev, queue); - } - - if ((revents & POLLOUT) && c->write->active) { - found = 1; - - ev = c->write; - ev->ready = 1; - - ngx_post_event(ev, &ngx_posted_events); - } - - if (found) { - ready--; - continue; - } - } - - if (ready != 0) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events"); - } - - return NGX_OK; -} - - -static char * -ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_event_conf_t *ecf; - - ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); - - if (ecf->use != ngx_poll_module.ctx_index) { - return NGX_CONF_OK; - } - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/modules/ngx_select_module.c b/app/nginx/src/event/modules/ngx_select_module.c deleted file mode 100644 index 0644621..0000000 --- a/app/nginx/src/event/modules/ngx_select_module.c +++ /dev/null @@ -1,423 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static void ngx_select_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); -static void ngx_select_repair_fd_sets(ngx_cycle_t *cycle); -static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf); - - -static fd_set master_read_fd_set; -static fd_set master_write_fd_set; -static fd_set work_read_fd_set; -static fd_set work_write_fd_set; - -static ngx_int_t max_fd; -static ngx_uint_t nevents; - -static ngx_event_t **event_index; - - -static ngx_str_t select_name = ngx_string("select"); - -static ngx_event_module_t ngx_select_module_ctx = { - &select_name, - NULL, /* create configuration */ - ngx_select_init_conf, /* init configuration */ - - { - ngx_select_add_event, /* add an event */ - ngx_select_del_event, /* delete an event */ - ngx_select_add_event, /* enable an event */ - ngx_select_del_event, /* disable an event */ - NULL, /* add an connection */ - NULL, /* delete an connection */ - NULL, /* trigger a notify */ - ngx_select_process_events, /* process the events */ - ngx_select_init, /* init the events */ - ngx_select_done /* done the events */ - } - -}; - -ngx_module_t ngx_select_module = { - NGX_MODULE_V1, - &ngx_select_module_ctx, /* module context */ - NULL, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - ngx_event_t **index; - - if (event_index == NULL) { - FD_ZERO(&master_read_fd_set); - FD_ZERO(&master_write_fd_set); - nevents = 0; - } - - if (ngx_process >= NGX_PROCESS_WORKER - || cycle->old_cycle == NULL - || cycle->old_cycle->connection_n < cycle->connection_n) - { - index = ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n, - cycle->log); - if (index == NULL) { - return NGX_ERROR; - } - - if (event_index) { - ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents); - ngx_free(event_index); - } - - event_index = index; - } - - ngx_io = ngx_os_io; - - ngx_event_actions = ngx_select_module_ctx.actions; - - ngx_event_flags = NGX_USE_LEVEL_EVENT; - - max_fd = -1; - - return NGX_OK; -} - - -static void -ngx_select_done(ngx_cycle_t *cycle) -{ - ngx_free(event_index); - - event_index = NULL; -} - - -static ngx_int_t -ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_connection_t *c; - - c = ev->data; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "select add event fd:%d ev:%i", c->fd, event); - - if (ev->index != NGX_INVALID_INDEX) { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "select event fd:%d ev:%i is already set", c->fd, event); - return NGX_OK; - } - - if ((event == NGX_READ_EVENT && ev->write) - || (event == NGX_WRITE_EVENT && !ev->write)) - { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "invalid select %s event fd:%d ev:%i", - ev->write ? "write" : "read", c->fd, event); - return NGX_ERROR; - } - - if (event == NGX_READ_EVENT) { - FD_SET(c->fd, &master_read_fd_set); - - } else if (event == NGX_WRITE_EVENT) { - FD_SET(c->fd, &master_write_fd_set); - } - - if (max_fd != -1 && max_fd < c->fd) { - max_fd = c->fd; - } - - ev->active = 1; - - event_index[nevents] = ev; - ev->index = nevents; - nevents++; - - return NGX_OK; -} - - -static ngx_int_t -ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_event_t *e; - ngx_connection_t *c; - - c = ev->data; - - ev->active = 0; - - if (ev->index == NGX_INVALID_INDEX) { - return NGX_OK; - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "select del event fd:%d ev:%i", c->fd, event); - - if (event == NGX_READ_EVENT) { - FD_CLR(c->fd, &master_read_fd_set); - - } else if (event == NGX_WRITE_EVENT) { - FD_CLR(c->fd, &master_write_fd_set); - } - - if (max_fd == c->fd) { - max_fd = -1; - } - - if (ev->index < --nevents) { - e = event_index[nevents]; - event_index[ev->index] = e; - e->index = ev->index; - } - - ev->index = NGX_INVALID_INDEX; - - return NGX_OK; -} - - -static ngx_int_t -ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags) -{ - int ready, nready; - ngx_err_t err; - ngx_uint_t i, found; - ngx_event_t *ev; - ngx_queue_t *queue; - struct timeval tv, *tp; - ngx_connection_t *c; - - if (max_fd == -1) { - for (i = 0; i < nevents; i++) { - c = event_index[i]->data; - if (max_fd < c->fd) { - max_fd = c->fd; - } - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "change max_fd: %i", max_fd); - } - -#if (NGX_DEBUG) - if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { - for (i = 0; i < nevents; i++) { - ev = event_index[i]; - c = ev->data; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select event: fd:%d wr:%d", c->fd, ev->write); - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "max_fd: %i", max_fd); - } -#endif - - if (timer == NGX_TIMER_INFINITE) { - tp = NULL; - - } else { - tv.tv_sec = (long) (timer / 1000); - tv.tv_usec = (long) ((timer % 1000) * 1000); - tp = &tv; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select timer: %M", timer); - - work_read_fd_set = master_read_fd_set; - work_write_fd_set = master_write_fd_set; - - ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp); - - err = (ready == -1) ? ngx_errno : 0; - - if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { - ngx_time_update(); - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select ready %d", ready); - - if (err) { - ngx_uint_t level; - - if (err == NGX_EINTR) { - - if (ngx_event_timer_alarm) { - ngx_event_timer_alarm = 0; - return NGX_OK; - } - - level = NGX_LOG_INFO; - - } else { - level = NGX_LOG_ALERT; - } - - ngx_log_error(level, cycle->log, err, "select() failed"); - - if (err == NGX_EBADF) { - ngx_select_repair_fd_sets(cycle); - } - - return NGX_ERROR; - } - - if (ready == 0) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "select() returned no events without timeout"); - return NGX_ERROR; - } - - nready = 0; - - for (i = 0; i < nevents; i++) { - ev = event_index[i]; - c = ev->data; - found = 0; - - if (ev->write) { - if (FD_ISSET(c->fd, &work_write_fd_set)) { - found = 1; - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select write %d", c->fd); - } - - } else { - if (FD_ISSET(c->fd, &work_read_fd_set)) { - found = 1; - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select read %d", c->fd); - } - } - - if (found) { - ev->ready = 1; - - queue = ev->accept ? &ngx_posted_accept_events - : &ngx_posted_events; - - ngx_post_event(ev, queue); - - nready++; - } - } - - if (ready != nready) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "select ready != events: %d:%d", ready, nready); - - ngx_select_repair_fd_sets(cycle); - } - - return NGX_OK; -} - - -static void -ngx_select_repair_fd_sets(ngx_cycle_t *cycle) -{ - int n; - socklen_t len; - ngx_err_t err; - ngx_socket_t s; - - for (s = 0; s <= max_fd; s++) { - - if (FD_ISSET(s, &master_read_fd_set) == 0) { - continue; - } - - len = sizeof(int); - - if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) { - err = ngx_socket_errno; - - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - "invalid descriptor #%d in read fd_set", s); - - FD_CLR(s, &master_read_fd_set); - } - } - - for (s = 0; s <= max_fd; s++) { - - if (FD_ISSET(s, &master_write_fd_set) == 0) { - continue; - } - - len = sizeof(int); - - if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) { - err = ngx_socket_errno; - - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - "invalid descriptor #%d in write fd_set", s); - - FD_CLR(s, &master_write_fd_set); - } - } - - max_fd = -1; -} - - -static char * -ngx_select_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_event_conf_t *ecf; - - ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); - - if (ecf->use != ngx_select_module.ctx_index) { - return NGX_CONF_OK; - } - - /* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */ - - if (cycle->connection_n > FD_SETSIZE) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, - "the maximum number of files " - "supported by select() is %ud", FD_SETSIZE); - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/modules/ngx_win32_select_module.c b/app/nginx/src/event/modules/ngx_win32_select_module.c deleted file mode 100644 index a98a83f..0000000 --- a/app/nginx/src/event/modules/ngx_win32_select_module.c +++ /dev/null @@ -1,398 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static void ngx_select_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); -static void ngx_select_repair_fd_sets(ngx_cycle_t *cycle); -static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf); - - -static fd_set master_read_fd_set; -static fd_set master_write_fd_set; -static fd_set work_read_fd_set; -static fd_set work_write_fd_set; - -static ngx_uint_t max_read; -static ngx_uint_t max_write; -static ngx_uint_t nevents; - -static ngx_event_t **event_index; - - -static ngx_str_t select_name = ngx_string("select"); - -static ngx_event_module_t ngx_select_module_ctx = { - &select_name, - NULL, /* create configuration */ - ngx_select_init_conf, /* init configuration */ - - { - ngx_select_add_event, /* add an event */ - ngx_select_del_event, /* delete an event */ - ngx_select_add_event, /* enable an event */ - ngx_select_del_event, /* disable an event */ - NULL, /* add an connection */ - NULL, /* delete an connection */ - NULL, /* trigger a notify */ - ngx_select_process_events, /* process the events */ - ngx_select_init, /* init the events */ - ngx_select_done /* done the events */ - } - -}; - -ngx_module_t ngx_select_module = { - NGX_MODULE_V1, - &ngx_select_module_ctx, /* module context */ - NULL, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - ngx_event_t **index; - - if (event_index == NULL) { - FD_ZERO(&master_read_fd_set); - FD_ZERO(&master_write_fd_set); - nevents = 0; - } - - if (ngx_process >= NGX_PROCESS_WORKER - || cycle->old_cycle == NULL - || cycle->old_cycle->connection_n < cycle->connection_n) - { - index = ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n, - cycle->log); - if (index == NULL) { - return NGX_ERROR; - } - - if (event_index) { - ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents); - ngx_free(event_index); - } - - event_index = index; - } - - ngx_io = ngx_os_io; - - ngx_event_actions = ngx_select_module_ctx.actions; - - ngx_event_flags = NGX_USE_LEVEL_EVENT; - - max_read = 0; - max_write = 0; - - return NGX_OK; -} - - -static void -ngx_select_done(ngx_cycle_t *cycle) -{ - ngx_free(event_index); - - event_index = NULL; -} - - -static ngx_int_t -ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_connection_t *c; - - c = ev->data; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "select add event fd:%d ev:%i", c->fd, event); - - if (ev->index != NGX_INVALID_INDEX) { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "select event fd:%d ev:%i is already set", c->fd, event); - return NGX_OK; - } - - if ((event == NGX_READ_EVENT && ev->write) - || (event == NGX_WRITE_EVENT && !ev->write)) - { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "invalid select %s event fd:%d ev:%i", - ev->write ? "write" : "read", c->fd, event); - return NGX_ERROR; - } - - if ((event == NGX_READ_EVENT && max_read >= FD_SETSIZE) - || (event == NGX_WRITE_EVENT && max_write >= FD_SETSIZE)) - { - ngx_log_error(NGX_LOG_ERR, ev->log, 0, - "maximum number of descriptors " - "supported by select() is %d", FD_SETSIZE); - return NGX_ERROR; - } - - if (event == NGX_READ_EVENT) { - FD_SET(c->fd, &master_read_fd_set); - max_read++; - - } else if (event == NGX_WRITE_EVENT) { - FD_SET(c->fd, &master_write_fd_set); - max_write++; - } - - ev->active = 1; - - event_index[nevents] = ev; - ev->index = nevents; - nevents++; - - return NGX_OK; -} - - -static ngx_int_t -ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - ngx_event_t *e; - ngx_connection_t *c; - - c = ev->data; - - ev->active = 0; - - if (ev->index == NGX_INVALID_INDEX) { - return NGX_OK; - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "select del event fd:%d ev:%i", c->fd, event); - - if (event == NGX_READ_EVENT) { - FD_CLR(c->fd, &master_read_fd_set); - max_read--; - - } else if (event == NGX_WRITE_EVENT) { - FD_CLR(c->fd, &master_write_fd_set); - max_write--; - } - - if (ev->index < --nevents) { - e = event_index[nevents]; - event_index[ev->index] = e; - e->index = ev->index; - } - - ev->index = NGX_INVALID_INDEX; - - return NGX_OK; -} - - -static ngx_int_t -ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags) -{ - int ready, nready; - ngx_err_t err; - ngx_uint_t i, found; - ngx_event_t *ev; - ngx_queue_t *queue; - struct timeval tv, *tp; - ngx_connection_t *c; - -#if (NGX_DEBUG) - if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { - for (i = 0; i < nevents; i++) { - ev = event_index[i]; - c = ev->data; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select event: fd:%d wr:%d", c->fd, ev->write); - } - } -#endif - - if (timer == NGX_TIMER_INFINITE) { - tp = NULL; - - } else { - tv.tv_sec = (long) (timer / 1000); - tv.tv_usec = (long) ((timer % 1000) * 1000); - tp = &tv; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select timer: %M", timer); - - work_read_fd_set = master_read_fd_set; - work_write_fd_set = master_write_fd_set; - - if (max_read || max_write) { - ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp); - - } else { - - /* - * Winsock select() requires that at least one descriptor set must be - * be non-null, and any non-null descriptor set must contain at least - * one handle to a socket. Otherwise select() returns WSAEINVAL. - */ - - ngx_msleep(timer); - - ready = 0; - } - - err = (ready == -1) ? ngx_socket_errno : 0; - - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(); - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select ready %d", ready); - - if (err) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed"); - - if (err == WSAENOTSOCK) { - ngx_select_repair_fd_sets(cycle); - } - - return NGX_ERROR; - } - - if (ready == 0) { - if (timer != NGX_TIMER_INFINITE) { - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "select() returned no events without timeout"); - return NGX_ERROR; - } - - nready = 0; - - for (i = 0; i < nevents; i++) { - ev = event_index[i]; - c = ev->data; - found = 0; - - if (ev->write) { - if (FD_ISSET(c->fd, &work_write_fd_set)) { - found = 1; - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select write %d", c->fd); - } - - } else { - if (FD_ISSET(c->fd, &work_read_fd_set)) { - found = 1; - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select read %d", c->fd); - } - } - - if (found) { - ev->ready = 1; - - queue = ev->accept ? &ngx_posted_accept_events - : &ngx_posted_events; - - ngx_post_event(ev, queue); - - nready++; - } - } - - if (ready != nready) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "select ready != events: %d:%d", ready, nready); - - ngx_select_repair_fd_sets(cycle); - } - - return NGX_OK; -} - - -static void -ngx_select_repair_fd_sets(ngx_cycle_t *cycle) -{ - int n; - u_int i; - socklen_t len; - ngx_err_t err; - ngx_socket_t s; - - for (i = 0; i < master_read_fd_set.fd_count; i++) { - - s = master_read_fd_set.fd_array[i]; - len = sizeof(int); - - if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) { - err = ngx_socket_errno; - - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - "invalid descriptor #%d in read fd_set", s); - - FD_CLR(s, &master_read_fd_set); - } - } - - for (i = 0; i < master_write_fd_set.fd_count; i++) { - - s = master_write_fd_set.fd_array[i]; - len = sizeof(int); - - if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) { - err = ngx_socket_errno; - - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - "invalid descriptor #%d in write fd_set", s); - - FD_CLR(s, &master_write_fd_set); - } - } -} - - -static char * -ngx_select_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_event_conf_t *ecf; - - ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); - - if (ecf->use != ngx_select_module.ctx_index) { - return NGX_CONF_OK; - } - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/ngx_event.c b/app/nginx/src/event/ngx_event.c deleted file mode 100644 index 57af813..0000000 --- a/app/nginx/src/event/ngx_event.c +++ /dev/null @@ -1,1290 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#define DEFAULT_CONNECTIONS 512 - - -extern ngx_module_t ngx_kqueue_module; -extern ngx_module_t ngx_eventport_module; -extern ngx_module_t ngx_devpoll_module; -extern ngx_module_t ngx_epoll_module; -extern ngx_module_t ngx_select_module; - - -static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf); -static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle); -static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle); -static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); - -static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - -static void *ngx_event_core_create_conf(ngx_cycle_t *cycle); -static char *ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf); - - -static ngx_uint_t ngx_timer_resolution; -sig_atomic_t ngx_event_timer_alarm; - -static ngx_uint_t ngx_event_max_module; - -ngx_uint_t ngx_event_flags; -ngx_event_actions_t ngx_event_actions; - - -static ngx_atomic_t connection_counter = 1; -ngx_atomic_t *ngx_connection_counter = &connection_counter; - - -ngx_atomic_t *ngx_accept_mutex_ptr; -ngx_shmtx_t ngx_accept_mutex; -ngx_uint_t ngx_use_accept_mutex; -ngx_uint_t ngx_accept_events; -ngx_uint_t ngx_accept_mutex_held; -ngx_msec_t ngx_accept_mutex_delay; -ngx_int_t ngx_accept_disabled; - - -#if (NGX_STAT_STUB) - -static ngx_atomic_t ngx_stat_accepted0; -ngx_atomic_t *ngx_stat_accepted = &ngx_stat_accepted0; -static ngx_atomic_t ngx_stat_handled0; -ngx_atomic_t *ngx_stat_handled = &ngx_stat_handled0; -static ngx_atomic_t ngx_stat_requests0; -ngx_atomic_t *ngx_stat_requests = &ngx_stat_requests0; -static ngx_atomic_t ngx_stat_active0; -ngx_atomic_t *ngx_stat_active = &ngx_stat_active0; -static ngx_atomic_t ngx_stat_reading0; -ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0; -static ngx_atomic_t ngx_stat_writing0; -ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0; -static ngx_atomic_t ngx_stat_waiting0; -ngx_atomic_t *ngx_stat_waiting = &ngx_stat_waiting0; - -#endif - - - -static ngx_command_t ngx_events_commands[] = { - - { ngx_string("events"), - NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_events_block, - 0, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_core_module_t ngx_events_module_ctx = { - ngx_string("events"), - NULL, - ngx_event_init_conf -}; - - -ngx_module_t ngx_events_module = { - NGX_MODULE_V1, - &ngx_events_module_ctx, /* module context */ - ngx_events_commands, /* module directives */ - NGX_CORE_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_str_t event_core_name = ngx_string("event_core"); - - -static ngx_command_t ngx_event_core_commands[] = { - - { ngx_string("worker_connections"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_event_connections, - 0, - 0, - NULL }, - - { ngx_string("use"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_event_use, - 0, - 0, - NULL }, - - { ngx_string("multi_accept"), - NGX_EVENT_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - 0, - offsetof(ngx_event_conf_t, multi_accept), - NULL }, - - { ngx_string("accept_mutex"), - NGX_EVENT_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - 0, - offsetof(ngx_event_conf_t, accept_mutex), - NULL }, - - { ngx_string("accept_mutex_delay"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - 0, - offsetof(ngx_event_conf_t, accept_mutex_delay), - NULL }, - - { ngx_string("debug_connection"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_event_debug_connection, - 0, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_event_module_t ngx_event_core_module_ctx = { - &event_core_name, - ngx_event_core_create_conf, /* create configuration */ - ngx_event_core_init_conf, /* init configuration */ - - { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } -}; - - -ngx_module_t ngx_event_core_module = { - NGX_MODULE_V1, - &ngx_event_core_module_ctx, /* module context */ - ngx_event_core_commands, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - ngx_event_module_init, /* init module */ - ngx_event_process_init, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -void -ngx_process_events_and_timers(ngx_cycle_t *cycle) -{ - ngx_uint_t flags; - ngx_msec_t timer, delta; - - if (ngx_timer_resolution) { - timer = NGX_TIMER_INFINITE; - flags = 0; - - } else { - timer = ngx_event_find_timer(); - flags = NGX_UPDATE_TIME; - -#if (NGX_WIN32) - - /* handle signals from master in case of network inactivity */ - - if (timer == NGX_TIMER_INFINITE || timer > 500) { - timer = 500; - } - -#endif - } - - if (ngx_use_accept_mutex) { - if (ngx_accept_disabled > 0) { - ngx_accept_disabled--; - - } else { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return; - } - - if (ngx_accept_mutex_held) { - flags |= NGX_POST_EVENTS; - - } else { - if (timer == NGX_TIMER_INFINITE - || timer > ngx_accept_mutex_delay) - { - timer = ngx_accept_mutex_delay; - } - } - } - } - - delta = ngx_current_msec; - - (void) ngx_process_events(cycle, timer, flags); - - delta = ngx_current_msec - delta; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "timer delta: %M", delta); - - ngx_event_process_posted(cycle, &ngx_posted_accept_events); - - if (ngx_accept_mutex_held) { - ngx_shmtx_unlock(&ngx_accept_mutex); - } - - if (delta) { - ngx_event_expire_timers(); - } - - ngx_event_process_posted(cycle, &ngx_posted_events); -} - - -ngx_int_t -ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags) -{ - if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { - - /* kqueue, epoll */ - - if (!rev->active && !rev->ready) { - if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) - == NGX_ERROR) - { - return NGX_ERROR; - } - } - - return NGX_OK; - - } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { - - /* select, poll, /dev/poll */ - - if (!rev->active && !rev->ready) { - if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) - == NGX_ERROR) - { - return NGX_ERROR; - } - - return NGX_OK; - } - - if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) { - if (ngx_del_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT | flags) - == NGX_ERROR) - { - return NGX_ERROR; - } - - return NGX_OK; - } - - } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) { - - /* event ports */ - - if (!rev->active && !rev->ready) { - if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - - return NGX_OK; - } - - if (rev->oneshot && !rev->ready) { - if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - - return NGX_OK; - } - } - - /* iocp */ - - return NGX_OK; -} - - -ngx_int_t -ngx_handle_write_event(ngx_event_t *wev, size_t lowat) -{ - ngx_connection_t *c; - - if (lowat) { - c = wev->data; - - if (ngx_send_lowat(c, lowat) == NGX_ERROR) { - return NGX_ERROR; - } - } - - if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { - - /* kqueue, epoll */ - - if (!wev->active && !wev->ready) { - if (ngx_add_event(wev, NGX_WRITE_EVENT, - NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0)) - == NGX_ERROR) - { - return NGX_ERROR; - } - } - - return NGX_OK; - - } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { - - /* select, poll, /dev/poll */ - - if (!wev->active && !wev->ready) { - if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT) - == NGX_ERROR) - { - return NGX_ERROR; - } - - return NGX_OK; - } - - if (wev->active && wev->ready) { - if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT) - == NGX_ERROR) - { - return NGX_ERROR; - } - - return NGX_OK; - } - - } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) { - - /* event ports */ - - if (!wev->active && !wev->ready) { - if (ngx_add_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - - return NGX_OK; - } - - if (wev->oneshot && wev->ready) { - if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - - return NGX_OK; - } - } - - /* iocp */ - - return NGX_OK; -} - - -static char * -ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) -{ - if (ngx_get_conf(cycle->conf_ctx, ngx_events_module) == NULL) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, - "no \"events\" section in configuration"); - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} - - -static ngx_int_t -ngx_event_module_init(ngx_cycle_t *cycle) -{ - void ***cf; - u_char *shared; - size_t size, cl; - ngx_shm_t shm; - ngx_time_t *tp; - ngx_core_conf_t *ccf; - ngx_event_conf_t *ecf; - - cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module); - ecf = (*cf)[ngx_event_core_module.ctx_index]; - - if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) { - ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, - "using the \"%s\" event method", ecf->name); - } - - ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); - - ngx_timer_resolution = ccf->timer_resolution; - -#if !(NGX_WIN32) - { - ngx_int_t limit; - struct rlimit rlmt; - - if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "getrlimit(RLIMIT_NOFILE) failed, ignored"); - - } else { - if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur - && (ccf->rlimit_nofile == NGX_CONF_UNSET - || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile)) - { - limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ? - (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile; - - ngx_log_error(NGX_LOG_WARN, cycle->log, 0, - "%ui worker_connections exceed " - "open file resource limit: %i", - ecf->connections, limit); - } - } - } -#endif /* !(NGX_WIN32) */ - - - if (ccf->master == 0) { - return NGX_OK; - } - - if (ngx_accept_mutex_ptr) { - return NGX_OK; - } - - - /* cl should be equal to or greater than cache line size */ - - cl = 128; - - size = cl /* ngx_accept_mutex */ - + cl /* ngx_connection_counter */ - + cl; /* ngx_temp_number */ - -#if (NGX_STAT_STUB) - - size += cl /* ngx_stat_accepted */ - + cl /* ngx_stat_handled */ - + cl /* ngx_stat_requests */ - + cl /* ngx_stat_active */ - + cl /* ngx_stat_reading */ - + cl /* ngx_stat_writing */ - + cl; /* ngx_stat_waiting */ - -#endif - - shm.size = size; - ngx_str_set(&shm.name, "nginx_shared_zone"); - shm.log = cycle->log; - - if (ngx_shm_alloc(&shm) != NGX_OK) { - return NGX_ERROR; - } - - shared = shm.addr; - - ngx_accept_mutex_ptr = (ngx_atomic_t *) shared; - ngx_accept_mutex.spin = (ngx_uint_t) -1; - - if (ngx_shmtx_create(&ngx_accept_mutex, (ngx_shmtx_sh_t *) shared, - cycle->lock_file.data) - != NGX_OK) - { - return NGX_ERROR; - } - - ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl); - - (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "counter: %p, %uA", - ngx_connection_counter, *ngx_connection_counter); - - ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl); - - tp = ngx_timeofday(); - - ngx_random_number = (tp->msec << 16) + ngx_pid; - -#if (NGX_STAT_STUB) - - ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl); - ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl); - ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl); - ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl); - ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl); - ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl); - ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl); - -#endif - - return NGX_OK; -} - - -#if !(NGX_WIN32) - -static void -ngx_timer_signal_handler(int signo) -{ - ngx_event_timer_alarm = 1; - -#if 1 - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal"); -#endif -} - -#endif - - -static ngx_int_t -ngx_event_process_init(ngx_cycle_t *cycle) -{ - ngx_uint_t m, i; - ngx_event_t *rev, *wev; - ngx_listening_t *ls; - ngx_connection_t *c, *next, *old; - ngx_core_conf_t *ccf; - ngx_event_conf_t *ecf; - ngx_event_module_t *module; - - ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); - ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); - - if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) { - ngx_use_accept_mutex = 1; - ngx_accept_mutex_held = 0; - ngx_accept_mutex_delay = ecf->accept_mutex_delay; - - } else { - ngx_use_accept_mutex = 0; - } - -#if (NGX_WIN32) - - /* - * disable accept mutex on win32 as it may cause deadlock if - * grabbed by a process which can't accept connections - */ - - ngx_use_accept_mutex = 0; - -#endif - - ngx_queue_init(&ngx_posted_accept_events); - ngx_queue_init(&ngx_posted_events); - - if (ngx_event_timer_init(cycle->log) == NGX_ERROR) { - return NGX_ERROR; - } - - for (m = 0; cycle->modules[m]; m++) { - if (cycle->modules[m]->type != NGX_EVENT_MODULE) { - continue; - } - - if (cycle->modules[m]->ctx_index != ecf->use) { - continue; - } - - module = cycle->modules[m]->ctx; - - if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) { - /* fatal */ - exit(2); - } - - break; - } - -#if !(NGX_WIN32) - - if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { - struct sigaction sa; - struct itimerval itv; - - ngx_memzero(&sa, sizeof(struct sigaction)); - sa.sa_handler = ngx_timer_signal_handler; - sigemptyset(&sa.sa_mask); - - if (sigaction(SIGALRM, &sa, NULL) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "sigaction(SIGALRM) failed"); - return NGX_ERROR; - } - - itv.it_interval.tv_sec = ngx_timer_resolution / 1000; - itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000; - itv.it_value.tv_sec = ngx_timer_resolution / 1000; - itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000; - - if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "setitimer() failed"); - } - } - - if (ngx_event_flags & NGX_USE_FD_EVENT) { - struct rlimit rlmt; - - if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "getrlimit(RLIMIT_NOFILE) failed"); - return NGX_ERROR; - } - - cycle->files_n = (ngx_uint_t) rlmt.rlim_cur; - - cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n, - cycle->log); - if (cycle->files == NULL) { - return NGX_ERROR; - } - } - -#else - - if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { - ngx_log_error(NGX_LOG_WARN, cycle->log, 0, - "the \"timer_resolution\" directive is not supported " - "with the configured event method, ignored"); - ngx_timer_resolution = 0; - } - -#endif - - cycle->connections = - ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log); - if (cycle->connections == NULL) { - return NGX_ERROR; - } - - c = cycle->connections; - - cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, - cycle->log); - if (cycle->read_events == NULL) { - return NGX_ERROR; - } - - rev = cycle->read_events; - for (i = 0; i < cycle->connection_n; i++) { - rev[i].closed = 1; - rev[i].instance = 1; - } - - cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, - cycle->log); - if (cycle->write_events == NULL) { - return NGX_ERROR; - } - - wev = cycle->write_events; - for (i = 0; i < cycle->connection_n; i++) { - wev[i].closed = 1; - } - - i = cycle->connection_n; - next = NULL; - - do { - i--; - - c[i].data = next; - c[i].read = &cycle->read_events[i]; - c[i].write = &cycle->write_events[i]; - c[i].fd = (ngx_socket_t) -1; - - next = &c[i]; - } while (i); - - cycle->free_connections = next; - cycle->free_connection_n = cycle->connection_n; - - /* for each listening socket */ - - ls = cycle->listening.elts; - for (i = 0; i < cycle->listening.nelts; i++) { - -#if (NGX_HAVE_REUSEPORT) - if (ls[i].reuseport && ls[i].worker != ngx_worker) { - continue; - } -#endif - - c = ngx_get_connection(ls[i].fd, cycle->log); - - if (c == NULL) { - return NGX_ERROR; - } - - c->type = ls[i].type; - c->log = &ls[i].log; - - c->listening = &ls[i]; - ls[i].connection = c; - - rev = c->read; - - rev->log = c->log; - rev->accept = 1; - -#if (NGX_HAVE_DEFERRED_ACCEPT) - rev->deferred_accept = ls[i].deferred_accept; -#endif - - if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { - if (ls[i].previous) { - - /* - * delete the old accept events that were bound to - * the old cycle read events array - */ - - old = ls[i].previous->connection; - - if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT) - == NGX_ERROR) - { - return NGX_ERROR; - } - - old->fd = (ngx_socket_t) -1; - } - } - -#if (NGX_WIN32) - - if (ngx_event_flags & NGX_USE_IOCP_EVENT) { - ngx_iocp_conf_t *iocpcf; - - rev->handler = ngx_event_acceptex; - - if (ngx_use_accept_mutex) { - continue; - } - - if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) { - return NGX_ERROR; - } - - ls[i].log.handler = ngx_acceptex_log_error; - - iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); - if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex) - == NGX_ERROR) - { - return NGX_ERROR; - } - - } else { - rev->handler = ngx_event_accept; - - if (ngx_use_accept_mutex) { - continue; - } - - if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - } - -#else - - rev->handler = (c->type == SOCK_STREAM) ? ngx_event_accept - : ngx_event_recvmsg; - -#if (NGX_HAVE_REUSEPORT) - - if (ls[i].reuseport) { - if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - - continue; - } - -#endif - - if (ngx_use_accept_mutex) { - continue; - } - -#if (NGX_HAVE_EPOLLEXCLUSIVE) - - if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) - && ccf->worker_processes > 1) - { - if (ngx_add_event(rev, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT) - == NGX_ERROR) - { - return NGX_ERROR; - } - - continue; - } - -#endif - - if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - -#endif - - } - - return NGX_OK; -} - - -ngx_int_t -ngx_send_lowat(ngx_connection_t *c, size_t lowat) -{ - int sndlowat; - -#if (NGX_HAVE_LOWAT_EVENT) - - if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { - c->write->available = lowat; - return NGX_OK; - } - -#endif - - if (lowat == 0 || c->sndlowat) { - return NGX_OK; - } - - sndlowat = (int) lowat; - - if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT, - (const void *) &sndlowat, sizeof(int)) - == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(SO_SNDLOWAT) failed"); - return NGX_ERROR; - } - - c->sndlowat = 1; - - return NGX_OK; -} - - -static char * -ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *rv; - void ***ctx; - ngx_uint_t i; - ngx_conf_t pcf; - ngx_event_module_t *m; - - if (*(void **) conf) { - return "is duplicate"; - } - - /* count the number of the event modules and set up their indices */ - - ngx_event_max_module = ngx_count_modules(cf->cycle, NGX_EVENT_MODULE); - - ctx = ngx_pcalloc(cf->pool, sizeof(void *)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *)); - if (*ctx == NULL) { - return NGX_CONF_ERROR; - } - - *(void **) conf = ctx; - - for (i = 0; cf->cycle->modules[i]; i++) { - if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) { - continue; - } - - m = cf->cycle->modules[i]->ctx; - - if (m->create_conf) { - (*ctx)[cf->cycle->modules[i]->ctx_index] = - m->create_conf(cf->cycle); - if ((*ctx)[cf->cycle->modules[i]->ctx_index] == NULL) { - return NGX_CONF_ERROR; - } - } - } - - pcf = *cf; - cf->ctx = ctx; - cf->module_type = NGX_EVENT_MODULE; - cf->cmd_type = NGX_EVENT_CONF; - - rv = ngx_conf_parse(cf, NULL); - - *cf = pcf; - - if (rv != NGX_CONF_OK) { - return rv; - } - - for (i = 0; cf->cycle->modules[i]; i++) { - if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) { - continue; - } - - m = cf->cycle->modules[i]->ctx; - - if (m->init_conf) { - rv = m->init_conf(cf->cycle, - (*ctx)[cf->cycle->modules[i]->ctx_index]); - if (rv != NGX_CONF_OK) { - return rv; - } - } - } - - return NGX_CONF_OK; -} - - -static char * -ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_event_conf_t *ecf = conf; - - ngx_str_t *value; - - if (ecf->connections != NGX_CONF_UNSET_UINT) { - return "is duplicate"; - } - - value = cf->args->elts; - ecf->connections = ngx_atoi(value[1].data, value[1].len); - if (ecf->connections == (ngx_uint_t) NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number \"%V\"", &value[1]); - - return NGX_CONF_ERROR; - } - - cf->cycle->connection_n = ecf->connections; - - return NGX_CONF_OK; -} - - -static char * -ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_event_conf_t *ecf = conf; - - ngx_int_t m; - ngx_str_t *value; - ngx_event_conf_t *old_ecf; - ngx_event_module_t *module; - - if (ecf->use != NGX_CONF_UNSET_UINT) { - return "is duplicate"; - } - - value = cf->args->elts; - - if (cf->cycle->old_cycle->conf_ctx) { - old_ecf = ngx_event_get_conf(cf->cycle->old_cycle->conf_ctx, - ngx_event_core_module); - } else { - old_ecf = NULL; - } - - - for (m = 0; cf->cycle->modules[m]; m++) { - if (cf->cycle->modules[m]->type != NGX_EVENT_MODULE) { - continue; - } - - module = cf->cycle->modules[m]->ctx; - if (module->name->len == value[1].len) { - if (ngx_strcmp(module->name->data, value[1].data) == 0) { - ecf->use = cf->cycle->modules[m]->ctx_index; - ecf->name = module->name->data; - - if (ngx_process == NGX_PROCESS_SINGLE - && old_ecf - && old_ecf->use != ecf->use) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "when the server runs without a master process " - "the \"%V\" event type must be the same as " - "in previous configuration - \"%s\" " - "and it cannot be changed on the fly, " - "to change it you need to stop server " - "and start it again", - &value[1], old_ecf->name); - - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; - } - } - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid event type \"%V\"", &value[1]); - - return NGX_CONF_ERROR; -} - - -static char * -ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ -#if (NGX_DEBUG) - ngx_event_conf_t *ecf = conf; - - ngx_int_t rc; - ngx_str_t *value; - ngx_url_t u; - ngx_cidr_t c, *cidr; - ngx_uint_t i; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif - - value = cf->args->elts; - -#if (NGX_HAVE_UNIX_DOMAIN) - - if (ngx_strcmp(value[1].data, "unix:") == 0) { - cidr = ngx_array_push(&ecf->debug_connection); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - - cidr->family = AF_UNIX; - return NGX_CONF_OK; - } - -#endif - - rc = ngx_ptocidr(&value[1], &c); - - if (rc != NGX_ERROR) { - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", - &value[1]); - } - - cidr = ngx_array_push(&ecf->debug_connection); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - - *cidr = c; - - return NGX_CONF_OK; - } - - ngx_memzero(&u, sizeof(ngx_url_t)); - u.host = value[1]; - - if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { - if (u.err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in debug_connection \"%V\"", - u.err, &u.host); - } - - return NGX_CONF_ERROR; - } - - cidr = ngx_array_push_n(&ecf->debug_connection, u.naddrs); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t)); - - for (i = 0; i < u.naddrs; i++) { - cidr[i].family = u.addrs[i].sockaddr->sa_family; - - switch (cidr[i].family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr; - cidr[i].u.in6.addr = sin6->sin6_addr; - ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16); - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) u.addrs[i].sockaddr; - cidr[i].u.in.addr = sin->sin_addr.s_addr; - cidr[i].u.in.mask = 0xffffffff; - break; - } - } - -#else - - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "\"debug_connection\" is ignored, you need to rebuild " - "nginx using --with-debug option to enable it"); - -#endif - - return NGX_CONF_OK; -} - - -static void * -ngx_event_core_create_conf(ngx_cycle_t *cycle) -{ - ngx_event_conf_t *ecf; - - ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t)); - if (ecf == NULL) { - return NULL; - } - - ecf->connections = NGX_CONF_UNSET_UINT; - ecf->use = NGX_CONF_UNSET_UINT; - ecf->multi_accept = NGX_CONF_UNSET; - ecf->accept_mutex = NGX_CONF_UNSET; - ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC; - ecf->name = (void *) NGX_CONF_UNSET; - -#if (NGX_DEBUG) - - if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4, - sizeof(ngx_cidr_t)) == NGX_ERROR) - { - return NULL; - } - -#endif - - return ecf; -} - - -static char * -ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf) -{ - ngx_event_conf_t *ecf = conf; - -#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL) - int fd; -#endif - ngx_int_t i; - ngx_module_t *module; - ngx_event_module_t *event_module; - - module = NULL; - -#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL) - - fd = epoll_create(100); - - if (fd != -1) { - (void) close(fd); - module = &ngx_epoll_module; - - } else if (ngx_errno != NGX_ENOSYS) { - module = &ngx_epoll_module; - } - -#endif - -#if (NGX_HAVE_DEVPOLL) && !(NGX_TEST_BUILD_DEVPOLL) - - module = &ngx_devpoll_module; - -#endif - -#if (NGX_HAVE_KQUEUE) - - module = &ngx_kqueue_module; - -#endif - -#if (NGX_HAVE_SELECT) - - if (module == NULL) { - module = &ngx_select_module; - } - -#endif - - if (module == NULL) { - for (i = 0; cycle->modules[i]; i++) { - - if (cycle->modules[i]->type != NGX_EVENT_MODULE) { - continue; - } - - event_module = cycle->modules[i]->ctx; - - if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0) - { - continue; - } - - module = cycle->modules[i]; - break; - } - } - - if (module == NULL) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found"); - return NGX_CONF_ERROR; - } - - ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS); - cycle->connection_n = ecf->connections; - - ngx_conf_init_uint_value(ecf->use, module->ctx_index); - - event_module = module->ctx; - ngx_conf_init_ptr_value(ecf->name, event_module->name->data); - - ngx_conf_init_value(ecf->multi_accept, 0); - ngx_conf_init_value(ecf->accept_mutex, 0); - ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500); - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/event/ngx_event.h b/app/nginx/src/event/ngx_event.h deleted file mode 100644 index 053bd16..0000000 --- a/app/nginx/src/event/ngx_event.h +++ /dev/null @@ -1,541 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_EVENT_H_INCLUDED_ -#define _NGX_EVENT_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> - - -#define NGX_INVALID_INDEX 0xd0d0d0d0 - - -#if (NGX_HAVE_IOCP) - -typedef struct { - WSAOVERLAPPED ovlp; - ngx_event_t *event; - int error; -} ngx_event_ovlp_t; - -#endif - - -struct ngx_event_s { - void *data; - - unsigned write:1; - - unsigned accept:1; - - /* used to detect the stale events in kqueue and epoll */ - unsigned instance:1; - - /* - * the event was passed or would be passed to a kernel; - * in aio mode - operation was posted. - */ - unsigned active:1; - - unsigned disabled:1; - - /* the ready event; in aio mode 0 means that no operation can be posted */ - unsigned ready:1; - - unsigned oneshot:1; - - /* aio operation is complete */ - unsigned complete:1; - - unsigned eof:1; - unsigned error:1; - - unsigned timedout:1; - unsigned timer_set:1; - - unsigned delayed:1; - - unsigned deferred_accept:1; - - /* the pending eof reported by kqueue, epoll or in aio chain operation */ - unsigned pending_eof:1; - - unsigned posted:1; - - unsigned closed:1; - - /* to test on worker exit */ - unsigned channel:1; - unsigned resolver:1; - - unsigned cancelable:1; - -#if (NGX_HAVE_KQUEUE) - unsigned kq_vnode:1; - - /* the pending errno reported by kqueue */ - int kq_errno; -#endif - - /* - * kqueue only: - * accept: number of sockets that wait to be accepted - * read: bytes to read when event is ready - * or lowat when event is set with NGX_LOWAT_EVENT flag - * write: available space in buffer when event is ready - * or lowat when event is set with NGX_LOWAT_EVENT flag - * - * epoll with EPOLLRDHUP: - * accept: 1 if accept many, 0 otherwise - * read: 1 if there can be data to read, 0 otherwise - * - * iocp: TODO - * - * otherwise: - * accept: 1 if accept many, 0 otherwise - */ - -#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP) - int available; -#else - unsigned available:1; -#endif - - ngx_event_handler_pt handler; - - -#if (NGX_HAVE_IOCP) - ngx_event_ovlp_t ovlp; -#endif - - ngx_uint_t index; - - ngx_log_t *log; - - ngx_rbtree_node_t timer; - - /* the posted queue */ - ngx_queue_t queue; - -#if 0 - - /* the threads support */ - - /* - * the event thread context, we store it here - * if $(CC) does not understand __thread declaration - * and pthread_getspecific() is too costly - */ - - void *thr_ctx; - -#if (NGX_EVENT_T_PADDING) - - /* event should not cross cache line in SMP */ - - uint32_t padding[NGX_EVENT_T_PADDING]; -#endif -#endif -}; - - -#if (NGX_HAVE_FILE_AIO) - -struct ngx_event_aio_s { - void *data; - ngx_event_handler_pt handler; - ngx_file_t *file; - -#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) - ssize_t (*preload_handler)(ngx_buf_t *file); -#endif - - ngx_fd_t fd; - -#if (NGX_HAVE_EVENTFD) - int64_t res; -#endif - -#if !(NGX_HAVE_EVENTFD) || (NGX_TEST_BUILD_EPOLL) - ngx_err_t err; - size_t nbytes; -#endif - - ngx_aiocb_t aiocb; - ngx_event_t event; -}; - -#endif - - -typedef struct { - ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); - ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); - - ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); - ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); - - ngx_int_t (*add_conn)(ngx_connection_t *c); - ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags); - - ngx_int_t (*notify)(ngx_event_handler_pt handler); - - ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); - - ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer); - void (*done)(ngx_cycle_t *cycle); -} ngx_event_actions_t; - - -extern ngx_event_actions_t ngx_event_actions; -#if (NGX_HAVE_EPOLLRDHUP) -extern ngx_uint_t ngx_use_epoll_rdhup; -#endif - - -/* - * The event filter requires to read/write the whole data: - * select, poll, /dev/poll, kqueue, epoll. - */ -#define NGX_USE_LEVEL_EVENT 0x00000001 - -/* - * The event filter is deleted after a notification without an additional - * syscall: kqueue, epoll. - */ -#define NGX_USE_ONESHOT_EVENT 0x00000002 - -/* - * The event filter notifies only the changes and an initial level: - * kqueue, epoll. - */ -#define NGX_USE_CLEAR_EVENT 0x00000004 - -/* - * The event filter has kqueue features: the eof flag, errno, - * available data, etc. - */ -#define NGX_USE_KQUEUE_EVENT 0x00000008 - -/* - * The event filter supports low water mark: kqueue's NOTE_LOWAT. - * kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag. - */ -#define NGX_USE_LOWAT_EVENT 0x00000010 - -/* - * The event filter requires to do i/o operation until EAGAIN: epoll. - */ -#define NGX_USE_GREEDY_EVENT 0x00000020 - -/* - * The event filter is epoll. - */ -#define NGX_USE_EPOLL_EVENT 0x00000040 - -/* - * Obsolete. - */ -#define NGX_USE_RTSIG_EVENT 0x00000080 - -/* - * Obsolete. - */ -#define NGX_USE_AIO_EVENT 0x00000100 - -/* - * Need to add socket or handle only once: i/o completion port. - */ -#define NGX_USE_IOCP_EVENT 0x00000200 - -/* - * The event filter has no opaque data and requires file descriptors table: - * poll, /dev/poll. - */ -#define NGX_USE_FD_EVENT 0x00000400 - -/* - * The event module handles periodic or absolute timer event by itself: - * kqueue in FreeBSD 4.4, NetBSD 2.0, and MacOSX 10.4, Solaris 10's event ports. - */ -#define NGX_USE_TIMER_EVENT 0x00000800 - -/* - * All event filters on file descriptor are deleted after a notification: - * Solaris 10's event ports. - */ -#define NGX_USE_EVENTPORT_EVENT 0x00001000 - -/* - * The event filter support vnode notifications: kqueue. - */ -#define NGX_USE_VNODE_EVENT 0x00002000 - - -/* - * The event filter is deleted just before the closing file. - * Has no meaning for select and poll. - * kqueue, epoll, eventport: allows to avoid explicit delete, - * because filter automatically is deleted - * on file close, - * - * /dev/poll: we need to flush POLLREMOVE event - * before closing file. - */ -#define NGX_CLOSE_EVENT 1 - -/* - * disable temporarily event filter, this may avoid locks - * in kernel malloc()/free(): kqueue. - */ -#define NGX_DISABLE_EVENT 2 - -/* - * event must be passed to kernel right now, do not wait until batch processing. - */ -#define NGX_FLUSH_EVENT 4 - - -/* these flags have a meaning only for kqueue */ -#define NGX_LOWAT_EVENT 0 -#define NGX_VNODE_EVENT 0 - - -#if (NGX_HAVE_EPOLL) && !(NGX_HAVE_EPOLLRDHUP) -#define EPOLLRDHUP 0 -#endif - - -#if (NGX_HAVE_KQUEUE) - -#define NGX_READ_EVENT EVFILT_READ -#define NGX_WRITE_EVENT EVFILT_WRITE - -#undef NGX_VNODE_EVENT -#define NGX_VNODE_EVENT EVFILT_VNODE - -/* - * NGX_CLOSE_EVENT, NGX_LOWAT_EVENT, and NGX_FLUSH_EVENT are the module flags - * and they must not go into a kernel so we need to choose the value - * that must not interfere with any existent and future kqueue flags. - * kqueue has such values - EV_FLAG1, EV_EOF, and EV_ERROR: - * they are reserved and cleared on a kernel entrance. - */ -#undef NGX_CLOSE_EVENT -#define NGX_CLOSE_EVENT EV_EOF - -#undef NGX_LOWAT_EVENT -#define NGX_LOWAT_EVENT EV_FLAG1 - -#undef NGX_FLUSH_EVENT -#define NGX_FLUSH_EVENT EV_ERROR - -#define NGX_LEVEL_EVENT 0 -#define NGX_ONESHOT_EVENT EV_ONESHOT -#define NGX_CLEAR_EVENT EV_CLEAR - -#undef NGX_DISABLE_EVENT -#define NGX_DISABLE_EVENT EV_DISABLE - - -#elif (NGX_HAVE_DEVPOLL && !(NGX_TEST_BUILD_DEVPOLL)) \ - || (NGX_HAVE_EVENTPORT && !(NGX_TEST_BUILD_EVENTPORT)) - -#define NGX_READ_EVENT POLLIN -#define NGX_WRITE_EVENT POLLOUT - -#define NGX_LEVEL_EVENT 0 -#define NGX_ONESHOT_EVENT 1 - - -#elif (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL) - -#define NGX_READ_EVENT (EPOLLIN|EPOLLRDHUP) -#define NGX_WRITE_EVENT EPOLLOUT - -#define NGX_LEVEL_EVENT 0 -#define NGX_CLEAR_EVENT EPOLLET -#define NGX_ONESHOT_EVENT 0x70000000 -#if 0 -#define NGX_ONESHOT_EVENT EPOLLONESHOT -#endif - -#if (NGX_HAVE_EPOLLEXCLUSIVE) -#define NGX_EXCLUSIVE_EVENT EPOLLEXCLUSIVE -#endif - -#elif (NGX_HAVE_POLL) - -#define NGX_READ_EVENT POLLIN -#define NGX_WRITE_EVENT POLLOUT - -#define NGX_LEVEL_EVENT 0 -#define NGX_ONESHOT_EVENT 1 - - -#else /* select */ - -#define NGX_READ_EVENT 0 -#define NGX_WRITE_EVENT 1 - -#define NGX_LEVEL_EVENT 0 -#define NGX_ONESHOT_EVENT 1 - -#endif /* NGX_HAVE_KQUEUE */ - - -#if (NGX_HAVE_IOCP) -#define NGX_IOCP_ACCEPT 0 -#define NGX_IOCP_IO 1 -#define NGX_IOCP_CONNECT 2 -#endif - - -#if (NGX_TEST_BUILD_EPOLL) -#define NGX_EXCLUSIVE_EVENT 0 -#endif - - -#ifndef NGX_CLEAR_EVENT -#define NGX_CLEAR_EVENT 0 /* dummy declaration */ -#endif - - -#define ngx_process_events ngx_event_actions.process_events -#define ngx_done_events ngx_event_actions.done - -#define ngx_add_event ngx_event_actions.add -#define ngx_del_event ngx_event_actions.del -#define ngx_add_conn ngx_event_actions.add_conn -#define ngx_del_conn ngx_event_actions.del_conn - -#define ngx_notify ngx_event_actions.notify - -#define ngx_add_timer ngx_event_add_timer -#define ngx_del_timer ngx_event_del_timer - - -extern ngx_os_io_t ngx_io; - -#define ngx_recv ngx_io.recv -#define ngx_recv_chain ngx_io.recv_chain -#define ngx_udp_recv ngx_io.udp_recv -#define ngx_send ngx_io.send -#define ngx_send_chain ngx_io.send_chain -#define ngx_udp_send ngx_io.udp_send -#define ngx_udp_send_chain ngx_io.udp_send_chain - - -#define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ -#define NGX_EVENT_CONF 0x02000000 - - -typedef struct { - ngx_uint_t connections; - ngx_uint_t use; - - ngx_flag_t multi_accept; - ngx_flag_t accept_mutex; - - ngx_msec_t accept_mutex_delay; - - u_char *name; - -#if (NGX_DEBUG) - ngx_array_t debug_connection; -#endif -} ngx_event_conf_t; - - -typedef struct { - ngx_str_t *name; - - void *(*create_conf)(ngx_cycle_t *cycle); - char *(*init_conf)(ngx_cycle_t *cycle, void *conf); - - ngx_event_actions_t actions; -} ngx_event_module_t; - - -extern ngx_atomic_t *ngx_connection_counter; - -extern ngx_atomic_t *ngx_accept_mutex_ptr; -extern ngx_shmtx_t ngx_accept_mutex; -extern ngx_uint_t ngx_use_accept_mutex; -extern ngx_uint_t ngx_accept_events; -extern ngx_uint_t ngx_accept_mutex_held; -extern ngx_msec_t ngx_accept_mutex_delay; -extern ngx_int_t ngx_accept_disabled; - - -#if (NGX_STAT_STUB) - -extern ngx_atomic_t *ngx_stat_accepted; -extern ngx_atomic_t *ngx_stat_handled; -extern ngx_atomic_t *ngx_stat_requests; -extern ngx_atomic_t *ngx_stat_active; -extern ngx_atomic_t *ngx_stat_reading; -extern ngx_atomic_t *ngx_stat_writing; -extern ngx_atomic_t *ngx_stat_waiting; - -#endif - - -#define NGX_UPDATE_TIME 1 -#define NGX_POST_EVENTS 2 - - -extern sig_atomic_t ngx_event_timer_alarm; -extern ngx_uint_t ngx_event_flags; -extern ngx_module_t ngx_events_module; -extern ngx_module_t ngx_event_core_module; - - -#define ngx_event_get_conf(conf_ctx, module) \ - (*(ngx_get_conf(conf_ctx, ngx_events_module))) [module.ctx_index]; - - - -void ngx_event_accept(ngx_event_t *ev); -#if !(NGX_WIN32) -void ngx_event_recvmsg(ngx_event_t *ev); -#endif -ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle); -u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len); - - -void ngx_process_events_and_timers(ngx_cycle_t *cycle); -ngx_int_t ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags); -ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat); - - -#if (NGX_WIN32) -void ngx_event_acceptex(ngx_event_t *ev); -ngx_int_t ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n); -u_char *ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len); -#endif - - -ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat); - - -/* used in ngx_log_debugX() */ -#define ngx_event_ident(p) ((ngx_connection_t *) (p))->fd - - -#include <ngx_event_timer.h> -#include <ngx_event_posted.h> - -#if (NGX_WIN32) -#include <ngx_iocp_module.h> -#endif - - -#endif /* _NGX_EVENT_H_INCLUDED_ */ diff --git a/app/nginx/src/event/ngx_event_accept.c b/app/nginx/src/event/ngx_event_accept.c deleted file mode 100644 index 1fce2e8..0000000 --- a/app/nginx/src/event/ngx_event_accept.c +++ /dev/null @@ -1,832 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle); -static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all); -static void ngx_close_accepted_connection(ngx_connection_t *c); -#if (NGX_DEBUG) -static void ngx_debug_accepted_connection(ngx_event_conf_t *ecf, - ngx_connection_t *c); -#endif - - -void -ngx_event_accept(ngx_event_t *ev) -{ - socklen_t socklen; - ngx_err_t err; - ngx_log_t *log; - ngx_uint_t level; - ngx_socket_t s; - ngx_event_t *rev, *wev; - ngx_sockaddr_t sa; - ngx_listening_t *ls; - ngx_connection_t *c, *lc; - ngx_event_conf_t *ecf; -#if (NGX_HAVE_ACCEPT4) - static ngx_uint_t use_accept4 = 1; -#endif - - if (ev->timedout) { - if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) { - return; - } - - ev->timedout = 0; - } - - ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); - - if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) { - ev->available = ecf->multi_accept; - } - - lc = ev->data; - ls = lc->listening; - ev->ready = 0; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "accept on %V, ready: %d", &ls->addr_text, ev->available); - - do { - socklen = sizeof(ngx_sockaddr_t); - -#if (NGX_HAVE_ACCEPT4) - if (use_accept4) { - s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK); - } else { - s = accept(lc->fd, &sa.sockaddr, &socklen); - } -#else - s = accept(lc->fd, &sa.sockaddr, &socklen); -#endif - - if (s == (ngx_socket_t) -1) { - err = ngx_socket_errno; - - if (err == NGX_EAGAIN) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err, - "accept() not ready"); - return; - } - - level = NGX_LOG_ALERT; - - if (err == NGX_ECONNABORTED) { - level = NGX_LOG_ERR; - - } else if (err == NGX_EMFILE || err == NGX_ENFILE) { - level = NGX_LOG_CRIT; - } - -#if (NGX_HAVE_ACCEPT4) - ngx_log_error(level, ev->log, err, - use_accept4 ? "accept4() failed" : "accept() failed"); - - if (use_accept4 && err == NGX_ENOSYS) { - use_accept4 = 0; - ngx_inherited_nonblocking = 0; - continue; - } -#else - ngx_log_error(level, ev->log, err, "accept() failed"); -#endif - - if (err == NGX_ECONNABORTED) { - if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { - ev->available--; - } - - if (ev->available) { - continue; - } - } - - if (err == NGX_EMFILE || err == NGX_ENFILE) { - if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle, 1) - != NGX_OK) - { - return; - } - - if (ngx_use_accept_mutex) { - if (ngx_accept_mutex_held) { - ngx_shmtx_unlock(&ngx_accept_mutex); - ngx_accept_mutex_held = 0; - } - - ngx_accept_disabled = 1; - - } else { - ngx_add_timer(ev, ecf->accept_mutex_delay); - } - } - - return; - } - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1); -#endif - - ngx_accept_disabled = ngx_cycle->connection_n / 8 - - ngx_cycle->free_connection_n; - - c = ngx_get_connection(s, ev->log); - - if (c == NULL) { - if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } - - return; - } - - c->type = SOCK_STREAM; - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_active, 1); -#endif - - c->pool = ngx_create_pool(ls->pool_size, ev->log); - if (c->pool == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->sockaddr = ngx_palloc(c->pool, socklen); - if (c->sockaddr == NULL) { - ngx_close_accepted_connection(c); - return; - } - - ngx_memcpy(c->sockaddr, &sa, socklen); - - log = ngx_palloc(c->pool, sizeof(ngx_log_t)); - if (log == NULL) { - ngx_close_accepted_connection(c); - return; - } - - /* set a blocking mode for iocp and non-blocking mode for others */ - - if (ngx_inherited_nonblocking) { - if (ngx_event_flags & NGX_USE_IOCP_EVENT) { - if (ngx_blocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_blocking_n " failed"); - ngx_close_accepted_connection(c); - return; - } - } - - } else { - if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { - if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_nonblocking_n " failed"); - ngx_close_accepted_connection(c); - return; - } - } - } - - *log = ls->log; - - c->recv = ngx_recv; - c->send = ngx_send; - c->recv_chain = ngx_recv_chain; - c->send_chain = ngx_send_chain; - - c->log = log; - c->pool->log = log; - - c->socklen = socklen; - c->listening = ls; - c->local_sockaddr = ls->sockaddr; - c->local_socklen = ls->socklen; - -#if (NGX_HAVE_UNIX_DOMAIN) - if (c->sockaddr->sa_family == AF_UNIX) { - c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; - c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; -#if (NGX_SOLARIS) - /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ - c->sendfile = 0; -#endif - } -#endif - - rev = c->read; - wev = c->write; - - wev->ready = 1; - - if (ngx_event_flags & NGX_USE_IOCP_EVENT) { - rev->ready = 1; - } - - if (ev->deferred_accept) { - rev->ready = 1; -#if (NGX_HAVE_KQUEUE) - rev->available = 1; -#endif - } - - rev->log = log; - wev->log = log; - - /* - * TODO: MT: - ngx_atomic_fetch_add() - * or protection by critical section or light mutex - * - * TODO: MP: - allocated in a shared memory - * - ngx_atomic_fetch_add() - * or protection by critical section or light mutex - */ - - c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_handled, 1); -#endif - - if (ls->addr_ntop) { - c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len); - if (c->addr_text.data == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen, - c->addr_text.data, - ls->addr_text_max_len, 0); - if (c->addr_text.len == 0) { - ngx_close_accepted_connection(c); - return; - } - } - -#if (NGX_DEBUG) - { - ngx_str_t addr; - u_char text[NGX_SOCKADDR_STRLEN]; - - ngx_debug_accepted_connection(ecf, c); - - if (log->log_level & NGX_LOG_DEBUG_EVENT) { - addr.data = text; - addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text, - NGX_SOCKADDR_STRLEN, 1); - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, - "*%uA accept: %V fd:%d", c->number, &addr, s); - } - - } -#endif - - if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { - if (ngx_add_conn(c) == NGX_ERROR) { - ngx_close_accepted_connection(c); - return; - } - } - - log->data = NULL; - log->handler = NULL; - - ls->handler(c); - - if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { - ev->available--; - } - - } while (ev->available); -} - - -#if !(NGX_WIN32) - -void -ngx_event_recvmsg(ngx_event_t *ev) -{ - ssize_t n; - ngx_log_t *log; - ngx_err_t err; - ngx_event_t *rev, *wev; - struct iovec iov[1]; - struct msghdr msg; - ngx_sockaddr_t sa; - ngx_listening_t *ls; - ngx_event_conf_t *ecf; - ngx_connection_t *c, *lc; - static u_char buffer[65535]; - -#if (NGX_HAVE_MSGHDR_MSG_CONTROL) - -#if (NGX_HAVE_IP_RECVDSTADDR) - u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))]; -#elif (NGX_HAVE_IP_PKTINFO) - u_char msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))]; -#endif - -#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) - u_char msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; -#endif - -#endif - - if (ev->timedout) { - if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) { - return; - } - - ev->timedout = 0; - } - - ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); - - if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) { - ev->available = ecf->multi_accept; - } - - lc = ev->data; - ls = lc->listening; - ev->ready = 0; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "recvmsg on %V, ready: %d", &ls->addr_text, ev->available); - - do { - ngx_memzero(&msg, sizeof(struct msghdr)); - - iov[0].iov_base = (void *) buffer; - iov[0].iov_len = sizeof(buffer); - - msg.msg_name = &sa; - msg.msg_namelen = sizeof(ngx_sockaddr_t); - msg.msg_iov = iov; - msg.msg_iovlen = 1; - -#if (NGX_HAVE_MSGHDR_MSG_CONTROL) - - if (ls->wildcard) { - -#if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO) - if (ls->sockaddr->sa_family == AF_INET) { - msg.msg_control = &msg_control; - msg.msg_controllen = sizeof(msg_control); - } -#endif - -#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) - if (ls->sockaddr->sa_family == AF_INET6) { - msg.msg_control = &msg_control6; - msg.msg_controllen = sizeof(msg_control6); - } -#endif - } - -#endif - - n = recvmsg(lc->fd, &msg, 0); - - if (n == -1) { - err = ngx_socket_errno; - - if (err == NGX_EAGAIN) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err, - "recvmsg() not ready"); - return; - } - - ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed"); - - return; - } - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1); -#endif - -#if (NGX_HAVE_MSGHDR_MSG_CONTROL) - if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "recvmsg() truncated data"); - continue; - } -#endif - - ngx_accept_disabled = ngx_cycle->connection_n / 8 - - ngx_cycle->free_connection_n; - - c = ngx_get_connection(lc->fd, ev->log); - if (c == NULL) { - return; - } - - c->shared = 1; - c->type = SOCK_DGRAM; - c->socklen = msg.msg_namelen; - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_active, 1); -#endif - - c->pool = ngx_create_pool(ls->pool_size, ev->log); - if (c->pool == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->sockaddr = ngx_palloc(c->pool, c->socklen); - if (c->sockaddr == NULL) { - ngx_close_accepted_connection(c); - return; - } - - ngx_memcpy(c->sockaddr, msg.msg_name, c->socklen); - - log = ngx_palloc(c->pool, sizeof(ngx_log_t)); - if (log == NULL) { - ngx_close_accepted_connection(c); - return; - } - - *log = ls->log; - - c->send = ngx_udp_send; - c->send_chain = ngx_udp_send_chain; - - c->log = log; - c->pool->log = log; - - c->listening = ls; - c->local_sockaddr = ls->sockaddr; - c->local_socklen = ls->socklen; - -#if (NGX_HAVE_MSGHDR_MSG_CONTROL) - - if (ls->wildcard) { - struct cmsghdr *cmsg; - struct sockaddr *sockaddr; - - sockaddr = ngx_palloc(c->pool, c->local_socklen); - if (sockaddr == NULL) { - ngx_close_accepted_connection(c); - return; - } - - ngx_memcpy(sockaddr, c->local_sockaddr, c->local_socklen); - c->local_sockaddr = sockaddr; - - for (cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - -#if (NGX_HAVE_IP_RECVDSTADDR) - - if (cmsg->cmsg_level == IPPROTO_IP - && cmsg->cmsg_type == IP_RECVDSTADDR - && sockaddr->sa_family == AF_INET) - { - struct in_addr *addr; - struct sockaddr_in *sin; - - addr = (struct in_addr *) CMSG_DATA(cmsg); - sin = (struct sockaddr_in *) sockaddr; - sin->sin_addr = *addr; - - break; - } - -#elif (NGX_HAVE_IP_PKTINFO) - - if (cmsg->cmsg_level == IPPROTO_IP - && cmsg->cmsg_type == IP_PKTINFO - && sockaddr->sa_family == AF_INET) - { - struct in_pktinfo *pkt; - struct sockaddr_in *sin; - - pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); - sin = (struct sockaddr_in *) sockaddr; - sin->sin_addr = pkt->ipi_addr; - - break; - } - -#endif - -#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) - - if (cmsg->cmsg_level == IPPROTO_IPV6 - && cmsg->cmsg_type == IPV6_PKTINFO - && sockaddr->sa_family == AF_INET6) - { - struct in6_pktinfo *pkt6; - struct sockaddr_in6 *sin6; - - pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); - sin6 = (struct sockaddr_in6 *) sockaddr; - sin6->sin6_addr = pkt6->ipi6_addr; - - break; - } - -#endif - - } - } - -#endif - - c->buffer = ngx_create_temp_buf(c->pool, n); - if (c->buffer == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->buffer->last = ngx_cpymem(c->buffer->last, buffer, n); - - rev = c->read; - wev = c->write; - - wev->ready = 1; - - rev->log = log; - wev->log = log; - - /* - * TODO: MT: - ngx_atomic_fetch_add() - * or protection by critical section or light mutex - * - * TODO: MP: - allocated in a shared memory - * - ngx_atomic_fetch_add() - * or protection by critical section or light mutex - */ - - c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_handled, 1); -#endif - - if (ls->addr_ntop) { - c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len); - if (c->addr_text.data == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen, - c->addr_text.data, - ls->addr_text_max_len, 0); - if (c->addr_text.len == 0) { - ngx_close_accepted_connection(c); - return; - } - } - -#if (NGX_DEBUG) - { - ngx_str_t addr; - u_char text[NGX_SOCKADDR_STRLEN]; - - ngx_debug_accepted_connection(ecf, c); - - if (log->log_level & NGX_LOG_DEBUG_EVENT) { - addr.data = text; - addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text, - NGX_SOCKADDR_STRLEN, 1); - - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0, - "*%uA recvmsg: %V fd:%d n:%z", - c->number, &addr, c->fd, n); - } - - } -#endif - - log->data = NULL; - log->handler = NULL; - - ls->handler(c); - - if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { - ev->available -= n; - } - - } while (ev->available); -} - -#endif - - -ngx_int_t -ngx_trylock_accept_mutex(ngx_cycle_t *cycle) -{ - if (ngx_shmtx_trylock(&ngx_accept_mutex)) { - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "accept mutex locked"); - - if (ngx_accept_mutex_held && ngx_accept_events == 0) { - return NGX_OK; - } - - if (ngx_enable_accept_events(cycle) == NGX_ERROR) { - ngx_shmtx_unlock(&ngx_accept_mutex); - return NGX_ERROR; - } - - ngx_accept_events = 0; - ngx_accept_mutex_held = 1; - - return NGX_OK; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "accept mutex lock failed: %ui", ngx_accept_mutex_held); - - if (ngx_accept_mutex_held) { - if (ngx_disable_accept_events(cycle, 0) == NGX_ERROR) { - return NGX_ERROR; - } - - ngx_accept_mutex_held = 0; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_enable_accept_events(ngx_cycle_t *cycle) -{ - ngx_uint_t i; - ngx_listening_t *ls; - ngx_connection_t *c; - - ls = cycle->listening.elts; - for (i = 0; i < cycle->listening.nelts; i++) { - - c = ls[i].connection; - - if (c == NULL || c->read->active) { - continue; - } - - if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) { - return NGX_ERROR; - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all) -{ - ngx_uint_t i; - ngx_listening_t *ls; - ngx_connection_t *c; - - ls = cycle->listening.elts; - for (i = 0; i < cycle->listening.nelts; i++) { - - c = ls[i].connection; - - if (c == NULL || !c->read->active) { - continue; - } - -#if (NGX_HAVE_REUSEPORT) - - /* - * do not disable accept on worker's own sockets - * when disabling accept events due to accept mutex - */ - - if (ls[i].reuseport && !all) { - continue; - } - -#endif - - if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT) - == NGX_ERROR) - { - return NGX_ERROR; - } - } - - return NGX_OK; -} - - -static void -ngx_close_accepted_connection(ngx_connection_t *c) -{ - ngx_socket_t fd; - - ngx_free_connection(c); - - fd = c->fd; - c->fd = (ngx_socket_t) -1; - - if (!c->shared && ngx_close_socket(fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } - - if (c->pool) { - ngx_destroy_pool(c->pool); - } - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_active, -1); -#endif -} - - -u_char * -ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len) -{ - return ngx_snprintf(buf, len, " while accepting new connection on %V", - log->data); -} - - -#if (NGX_DEBUG) - -static void -ngx_debug_accepted_connection(ngx_event_conf_t *ecf, ngx_connection_t *c) -{ - struct sockaddr_in *sin; - ngx_cidr_t *cidr; - ngx_uint_t i; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; - ngx_uint_t n; -#endif - - cidr = ecf->debug_connection.elts; - for (i = 0; i < ecf->debug_connection.nelts; i++) { - if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) { - goto next; - } - - switch (cidr[i].family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) c->sockaddr; - for (n = 0; n < 16; n++) { - if ((sin6->sin6_addr.s6_addr[n] - & cidr[i].u.in6.mask.s6_addr[n]) - != cidr[i].u.in6.addr.s6_addr[n]) - { - goto next; - } - } - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) c->sockaddr; - if ((sin->sin_addr.s_addr & cidr[i].u.in.mask) - != cidr[i].u.in.addr) - { - goto next; - } - break; - } - - c->log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL; - break; - - next: - continue; - } -} - -#endif diff --git a/app/nginx/src/event/ngx_event_acceptex.c b/app/nginx/src/event/ngx_event_acceptex.c deleted file mode 100644 index 1999faf..0000000 --- a/app/nginx/src/event/ngx_event_acceptex.c +++ /dev/null @@ -1,227 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -static void ngx_close_posted_connection(ngx_connection_t *c); - - -void -ngx_event_acceptex(ngx_event_t *rev) -{ - ngx_listening_t *ls; - ngx_connection_t *c; - - c = rev->data; - ls = c->listening; - - c->log->handler = ngx_accept_log_error; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "AcceptEx: %d", c->fd); - - if (rev->ovlp.error) { - ngx_log_error(NGX_LOG_CRIT, c->log, rev->ovlp.error, - "AcceptEx() %V failed", &ls->addr_text); - return; - } - - /* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */ - - if (setsockopt(c->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, - (char *) &ls->fd, sizeof(ngx_socket_t)) - == -1) - { - ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, - "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %V", - &c->addr_text); - /* TODO: close socket */ - return; - } - - ngx_getacceptexsockaddrs(c->buffer->pos, - ls->post_accept_buffer_size, - ls->socklen + 16, - ls->socklen + 16, - &c->local_sockaddr, &c->local_socklen, - &c->sockaddr, &c->socklen); - - if (ls->post_accept_buffer_size) { - c->buffer->last += rev->available; - c->buffer->end = c->buffer->start + ls->post_accept_buffer_size; - - } else { - c->buffer = NULL; - } - - if (ls->addr_ntop) { - c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len); - if (c->addr_text.data == NULL) { - /* TODO: close socket */ - return; - } - - c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen, - c->addr_text.data, - ls->addr_text_max_len, 0); - if (c->addr_text.len == 0) { - /* TODO: close socket */ - return; - } - } - - ngx_event_post_acceptex(ls, 1); - - c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); - - ls->handler(c); - - return; - -} - - -ngx_int_t -ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n) -{ - u_long rcvd; - ngx_err_t err; - ngx_log_t *log; - ngx_uint_t i; - ngx_event_t *rev, *wev; - ngx_socket_t s; - ngx_connection_t *c; - - for (i = 0; i < n; i++) { - - /* TODO: look up reused sockets */ - - s = ngx_socket(ls->sockaddr->sa_family, ls->type, 0); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &ls->log, 0, - ngx_socket_n " s:%d", s); - - if (s == (ngx_socket_t) -1) { - ngx_log_error(NGX_LOG_ALERT, &ls->log, ngx_socket_errno, - ngx_socket_n " failed"); - - return NGX_ERROR; - } - - c = ngx_get_connection(s, &ls->log); - - if (c == NULL) { - return NGX_ERROR; - } - - c->pool = ngx_create_pool(ls->pool_size, &ls->log); - if (c->pool == NULL) { - ngx_close_posted_connection(c); - return NGX_ERROR; - } - - log = ngx_palloc(c->pool, sizeof(ngx_log_t)); - if (log == NULL) { - ngx_close_posted_connection(c); - return NGX_ERROR; - } - - c->buffer = ngx_create_temp_buf(c->pool, ls->post_accept_buffer_size - + 2 * (ls->socklen + 16)); - if (c->buffer == NULL) { - ngx_close_posted_connection(c); - return NGX_ERROR; - } - - c->local_sockaddr = ngx_palloc(c->pool, ls->socklen); - if (c->local_sockaddr == NULL) { - ngx_close_posted_connection(c); - return NGX_ERROR; - } - - c->sockaddr = ngx_palloc(c->pool, ls->socklen); - if (c->sockaddr == NULL) { - ngx_close_posted_connection(c); - return NGX_ERROR; - } - - *log = ls->log; - c->log = log; - - c->recv = ngx_recv; - c->send = ngx_send; - c->recv_chain = ngx_recv_chain; - c->send_chain = ngx_send_chain; - - c->listening = ls; - - rev = c->read; - wev = c->write; - - rev->ovlp.event = rev; - wev->ovlp.event = wev; - rev->handler = ngx_event_acceptex; - - rev->ready = 1; - wev->ready = 1; - - rev->log = c->log; - wev->log = c->log; - - if (ngx_add_event(rev, 0, NGX_IOCP_IO) == NGX_ERROR) { - ngx_close_posted_connection(c); - return NGX_ERROR; - } - - if (ngx_acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size, - ls->socklen + 16, ls->socklen + 16, - &rcvd, (LPOVERLAPPED) &rev->ovlp) - == 0) - { - err = ngx_socket_errno; - if (err != WSA_IO_PENDING) { - ngx_log_error(NGX_LOG_ALERT, &ls->log, err, - "AcceptEx() %V failed", &ls->addr_text); - - ngx_close_posted_connection(c); - return NGX_ERROR; - } - } - } - - return NGX_OK; -} - - -static void -ngx_close_posted_connection(ngx_connection_t *c) -{ - ngx_socket_t fd; - - ngx_free_connection(c); - - fd = c->fd; - c->fd = (ngx_socket_t) -1; - - if (ngx_close_socket(fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } - - if (c->pool) { - ngx_destroy_pool(c->pool); - } -} - - -u_char * -ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len) -{ - return ngx_snprintf(buf, len, " while posting AcceptEx() on %V", log->data); -} diff --git a/app/nginx/src/event/ngx_event_connect.c b/app/nginx/src/event/ngx_event_connect.c deleted file mode 100644 index c5bb806..0000000 --- a/app/nginx/src/event/ngx_event_connect.c +++ /dev/null @@ -1,410 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> -#include <ngx_event_connect.h> - - -#if (NGX_HAVE_TRANSPARENT_PROXY) -static ngx_int_t ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, - ngx_socket_t s); -#endif - - -ngx_int_t -ngx_event_connect_peer(ngx_peer_connection_t *pc) -{ - int rc, type; -#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX) - in_port_t port; -#endif - ngx_int_t event; - ngx_err_t err; - ngx_uint_t level; - ngx_socket_t s; - ngx_event_t *rev, *wev; - ngx_connection_t *c; - - rc = pc->get(pc, pc->data); - if (rc != NGX_OK) { - return rc; - } - - type = (pc->type ? pc->type : SOCK_STREAM); - - s = ngx_socket(pc->sockaddr->sa_family, type, 0); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d", - (type == SOCK_STREAM) ? "stream" : "dgram", s); - - if (s == (ngx_socket_t) -1) { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - ngx_socket_n " failed"); - return NGX_ERROR; - } - - - c = ngx_get_connection(s, pc->log); - - if (c == NULL) { - if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - ngx_close_socket_n "failed"); - } - - return NGX_ERROR; - } - - c->type = type; - - if (pc->rcvbuf) { - if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, - (const void *) &pc->rcvbuf, sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - "setsockopt(SO_RCVBUF) failed"); - goto failed; - } - } - - if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - ngx_nonblocking_n " failed"); - - goto failed; - } - - if (pc->local) { - -#if (NGX_HAVE_TRANSPARENT_PROXY) - if (pc->transparent) { - if (ngx_event_connect_set_transparent(pc, s) != NGX_OK) { - goto failed; - } - } -#endif - -#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX) - port = ngx_inet_get_port(pc->local->sockaddr); -#endif - -#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT) - - if (pc->sockaddr->sa_family != AF_UNIX && port == 0) { - static int bind_address_no_port = 1; - - if (bind_address_no_port) { - if (setsockopt(s, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, - (const void *) &bind_address_no_port, - sizeof(int)) == -1) - { - err = ngx_socket_errno; - - if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT) { - ngx_log_error(NGX_LOG_ALERT, pc->log, err, - "setsockopt(IP_BIND_ADDRESS_NO_PORT) " - "failed, ignored"); - - } else { - bind_address_no_port = 0; - } - } - } - } - -#endif - -#if (NGX_LINUX) - - if (pc->type == SOCK_DGRAM && port != 0) { - int reuse_addr = 1; - - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &reuse_addr, sizeof(int)) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - "setsockopt(SO_REUSEADDR) failed"); - goto failed; - } - } - -#endif - - if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) { - ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno, - "bind(%V) failed", &pc->local->name); - - goto failed; - } - } - - if (type == SOCK_STREAM) { - c->recv = ngx_recv; - c->send = ngx_send; - c->recv_chain = ngx_recv_chain; - c->send_chain = ngx_send_chain; - - c->sendfile = 1; - - if (pc->sockaddr->sa_family == AF_UNIX) { - c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; - c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; - -#if (NGX_SOLARIS) - /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ - c->sendfile = 0; -#endif - } - - } else { /* type == SOCK_DGRAM */ - c->recv = ngx_udp_recv; - c->send = ngx_send; - c->send_chain = ngx_udp_send_chain; - } - - c->log_error = pc->log_error; - - rev = c->read; - wev = c->write; - - rev->log = pc->log; - wev->log = pc->log; - - pc->connection = c; - - c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); - - if (ngx_add_conn) { - if (ngx_add_conn(c) == NGX_ERROR) { - goto failed; - } - } - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0, - "connect to %V, fd:%d #%uA", pc->name, s, c->number); - - rc = connect(s, pc->sockaddr, pc->socklen); - - if (rc == -1) { - err = ngx_socket_errno; - - - if (err != NGX_EINPROGRESS -#if (NGX_WIN32) - /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */ - && err != NGX_EAGAIN -#endif - ) - { - if (err == NGX_ECONNREFUSED -#if (NGX_LINUX) - /* - * Linux returns EAGAIN instead of ECONNREFUSED - * for unix sockets if listen queue is full - */ - || err == NGX_EAGAIN -#endif - || err == NGX_ECONNRESET - || err == NGX_ENETDOWN - || err == NGX_ENETUNREACH - || err == NGX_EHOSTDOWN - || err == NGX_EHOSTUNREACH) - { - level = NGX_LOG_ERR; - - } else { - level = NGX_LOG_CRIT; - } - - ngx_log_error(level, c->log, err, "connect() to %V failed", - pc->name); - - ngx_close_connection(c); - pc->connection = NULL; - - return NGX_DECLINED; - } - } - - if (ngx_add_conn) { - if (rc == -1) { - - /* NGX_EINPROGRESS */ - - return NGX_AGAIN; - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected"); - - wev->ready = 1; - - return NGX_OK; - } - - if (ngx_event_flags & NGX_USE_IOCP_EVENT) { - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, ngx_socket_errno, - "connect(): %d", rc); - - if (ngx_blocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - ngx_blocking_n " failed"); - goto failed; - } - - /* - * FreeBSD's aio allows to post an operation on non-connected socket. - * NT does not support it. - * - * TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT - */ - - rev->ready = 1; - wev->ready = 1; - - return NGX_OK; - } - - if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { - - /* kqueue */ - - event = NGX_CLEAR_EVENT; - - } else { - - /* select, poll, /dev/poll */ - - event = NGX_LEVEL_EVENT; - } - - if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { - goto failed; - } - - if (rc == -1) { - - /* NGX_EINPROGRESS */ - - if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) { - goto failed; - } - - return NGX_AGAIN; - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected"); - - wev->ready = 1; - - return NGX_OK; - -failed: - - ngx_close_connection(c); - pc->connection = NULL; - - return NGX_ERROR; -} - - -#if (NGX_HAVE_TRANSPARENT_PROXY) - -static ngx_int_t -ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, ngx_socket_t s) -{ - int value; - - value = 1; - -#if defined(SO_BINDANY) - - if (setsockopt(s, SOL_SOCKET, SO_BINDANY, - (const void *) &value, sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - "setsockopt(SO_BINDANY) failed"); - return NGX_ERROR; - } - -#else - - switch (pc->local->sockaddr->sa_family) { - - case AF_INET: - -#if defined(IP_TRANSPARENT) - - if (setsockopt(s, IPPROTO_IP, IP_TRANSPARENT, - (const void *) &value, sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - "setsockopt(IP_TRANSPARENT) failed"); - return NGX_ERROR; - } - -#elif defined(IP_BINDANY) - - if (setsockopt(s, IPPROTO_IP, IP_BINDANY, - (const void *) &value, sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - "setsockopt(IP_BINDANY) failed"); - return NGX_ERROR; - } - -#endif - - break; - -#if (NGX_HAVE_INET6) - - case AF_INET6: - -#if defined(IPV6_TRANSPARENT) - - if (setsockopt(s, IPPROTO_IPV6, IPV6_TRANSPARENT, - (const void *) &value, sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - "setsockopt(IPV6_TRANSPARENT) failed"); - return NGX_ERROR; - } - -#elif defined(IPV6_BINDANY) - - if (setsockopt(s, IPPROTO_IPV6, IPV6_BINDANY, - (const void *) &value, sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, - "setsockopt(IPV6_BINDANY) failed"); - return NGX_ERROR; - } - -#endif - break; - -#endif /* NGX_HAVE_INET6 */ - - } - -#endif /* SO_BINDANY */ - - return NGX_OK; -} - -#endif - - -ngx_int_t -ngx_event_get_peer(ngx_peer_connection_t *pc, void *data) -{ - return NGX_OK; -} diff --git a/app/nginx/src/event/ngx_event_connect.h b/app/nginx/src/event/ngx_event_connect.h deleted file mode 100644 index 72d21d7..0000000 --- a/app/nginx/src/event/ngx_event_connect.h +++ /dev/null @@ -1,78 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_EVENT_CONNECT_H_INCLUDED_ -#define _NGX_EVENT_CONNECT_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#define NGX_PEER_KEEPALIVE 1 -#define NGX_PEER_NEXT 2 -#define NGX_PEER_FAILED 4 - - -typedef struct ngx_peer_connection_s ngx_peer_connection_t; - -typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc, - void *data); -typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data, - ngx_uint_t state); -typedef void (*ngx_event_notify_peer_pt)(ngx_peer_connection_t *pc, - void *data, ngx_uint_t type); -typedef ngx_int_t (*ngx_event_set_peer_session_pt)(ngx_peer_connection_t *pc, - void *data); -typedef void (*ngx_event_save_peer_session_pt)(ngx_peer_connection_t *pc, - void *data); - - -struct ngx_peer_connection_s { - ngx_connection_t *connection; - - struct sockaddr *sockaddr; - socklen_t socklen; - ngx_str_t *name; - - ngx_uint_t tries; - ngx_msec_t start_time; - - ngx_event_get_peer_pt get; - ngx_event_free_peer_pt free; - ngx_event_notify_peer_pt notify; - void *data; - -#if (NGX_SSL || NGX_COMPAT) - ngx_event_set_peer_session_pt set_session; - ngx_event_save_peer_session_pt save_session; -#endif - - ngx_addr_t *local; - - int type; - int rcvbuf; - - ngx_log_t *log; - - unsigned cached:1; - unsigned transparent:1; - - /* ngx_connection_log_error_e */ - unsigned log_error:2; - - NGX_COMPAT_BEGIN(2) - NGX_COMPAT_END -}; - - -ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc); -ngx_int_t ngx_event_get_peer(ngx_peer_connection_t *pc, void *data); - - -#endif /* _NGX_EVENT_CONNECT_H_INCLUDED_ */ diff --git a/app/nginx/src/event/ngx_event_connectex.c b/app/nginx/src/event/ngx_event_connectex.c deleted file mode 100644 index 59ada74..0000000 --- a/app/nginx/src/event/ngx_event_connectex.c +++ /dev/null @@ -1,206 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#define NGX_MAX_PENDING_CONN 10 - - -static CRITICAL_SECTION connect_lock; -static int nconnects; -static ngx_connection_t pending_connects[NGX_MAX_PENDING_CONN]; - -static HANDLE pending_connect_event; - -__declspec(thread) int nevents = 0; -__declspec(thread) WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS + 1]; -__declspec(thread) ngx_connection_t *conn[WSA_MAXIMUM_WAIT_EVENTS + 1]; - - - -int ngx_iocp_wait_connect(ngx_connection_t *c) -{ - for ( ;; ) { - EnterCriticalSection(&connect_lock); - - if (nconnects < NGX_MAX_PENDING_CONN) { - pending_connects[--nconnects] = c; - LeaveCriticalSection(&connect_lock); - - if (SetEvent(pending_connect_event) == 0) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "SetEvent() failed"); - return NGX_ERROR; - - break; - } - - LeaveCriticalSection(&connect_lock); - ngx_log_error(NGX_LOG_NOTICE, c->log, 0, - "max number of pending connect()s is %d", - NGX_MAX_PENDING_CONN); - msleep(100); - } - - if (!started) { - if (ngx_iocp_new_thread(1) == NGX_ERROR) { - return NGX_ERROR; - } - started = 1; - } - - return NGX_OK; -} - - -int ngx_iocp_new_thread(int main) -{ - u_int id; - - if (main) { - pending_connect_event = CreateEvent(NULL, 0, 1, NULL); - if (pending_connect_event == INVALID_HANDLE_VALUE) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "CreateThread() failed"); - return NGX_ERROR; - } - } - - if (CreateThread(NULL, 0, ngx_iocp_wait_events, main, 0, &id) - == INVALID_HANDLE_VALUE) - { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "CreateThread() failed"); - return NGX_ERROR; - } - - SetEvent(event) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "SetEvent() failed"); - return NGX_ERROR; - } - - return NGX_OK; -} - - -int ngx_iocp_new_connect() -{ - EnterCriticalSection(&connect_lock); - c = pending_connects[--nconnects]; - LeaveCriticalSection(&connect_lock); - - conn[nevents] = c; - - events[nevents] = WSACreateEvent(); - if (events[nevents] == INVALID_HANDLE_VALUE) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - "WSACreateEvent() failed"); - return NGX_ERROR; - } - - if (WSAEventSelect(c->fd, events[nevents], FD_CONNECT) == -1) - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - "WSAEventSelect() failed"); - return NGX_ERROR; - } - - nevents++; - - return NGX_OK; -} - - -void ngx_iocp_wait_events(int main) -{ - WSANETWORKEVENTS ne; - - nevents = 1; - events[0] = pending_connect_event; - conn[0] = NULL; - - for ( ;; ) { - offset = (nevents == WSA_MAXIMUM_WAIT_EVENTS + 1) ? 1: 0; - timeout = (nevents == 1 && !first) ? 60000: INFINITE; - - n = WSAWaitForMultipleEvents(nevents - offset, events[offset], - 0, timeout, 0); - if (n == WAIT_FAILED) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, - "WSAWaitForMultipleEvents() failed"); - continue; - } - - if (n == WAIT_TIMEOUT) { - if (nevents == 2 && !main) { - ExitThread(0); - } - - ngx_log_error(NGX_LOG_ALERT, log, 0, - "WSAWaitForMultipleEvents() " - "returned unexpected WAIT_TIMEOUT"); - continue; - } - - n -= WSA_WAIT_EVENT_0; - - if (events[n] == NULL) { - - /* the pending_connect_event */ - - if (nevents == WSA_MAXIMUM_WAIT_EVENTS) { - ngx_iocp_new_thread(0); - } else { - ngx_iocp_new_connect(); - } - - continue; - } - - if (WSAEnumNetworkEvents(c[n].fd, events[n], &ne) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, - "WSAEnumNetworkEvents() failed"); - continue; - } - - if (ne.lNetworkEvents & FD_CONNECT) { - conn[n].write->ovlp.error = ne.iErrorCode[FD_CONNECT_BIT]; - - if (PostQueuedCompletionStatus(iocp, 0, NGX_IOCP_CONNECT, - &conn[n].write->ovlp) == 0) - { - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, - "PostQueuedCompletionStatus() failed"); - continue; - } - - if (n < nevents) { - conn[n] = conn[nevents]; - events[n] = events[nevents]; - } - - nevents--; - continue; - } - - if (ne.lNetworkEvents & FD_ACCEPT) { - - /* CHECK ERROR ??? */ - - ngx_event_post_acceptex(conn[n].listening, 1); - continue; - } - - ngx_log_error(NGX_LOG_ALERT, c[n].log, 0, - "WSAWaitForMultipleEvents() " - "returned unexpected network event %ul", - ne.lNetworkEvents); - } -} diff --git a/app/nginx/src/event/ngx_event_openssl.c b/app/nginx/src/event/ngx_event_openssl.c deleted file mode 100644 index 8c7c677..0000000 --- a/app/nginx/src/event/ngx_event_openssl.c +++ /dev/null @@ -1,4201 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096 - - -typedef struct { - ngx_uint_t engine; /* unsigned engine:1; */ -} ngx_openssl_conf_t; - - -static int ngx_ssl_password_callback(char *buf, int size, int rwflag, - void *userdata); -static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); -static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, - int ret); -static void ngx_ssl_passwords_cleanup(void *data); -static void ngx_ssl_handshake_handler(ngx_event_t *ev); -static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); -static void ngx_ssl_write_handler(ngx_event_t *wev); -static void ngx_ssl_read_handler(ngx_event_t *rev); -static void ngx_ssl_shutdown_handler(ngx_event_t *ev); -static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, - ngx_err_t err, char *text); -static void ngx_ssl_clear_error(ngx_log_t *log); - -static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl, - ngx_str_t *sess_ctx); -ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data); -static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, - ngx_ssl_session_t *sess); -static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, -#if OPENSSL_VERSION_NUMBER >= 0x10100003L - const -#endif - u_char *id, int len, int *copy); -static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); -static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, - ngx_slab_pool_t *shpool, ngx_uint_t n); -static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp, - ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); - -#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB -static int ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, - unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, - HMAC_CTX *hctx, int enc); -#endif - -#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT -static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str); -#endif - -static time_t ngx_ssl_parse_time( -#if OPENSSL_VERSION_NUMBER > 0x10100000L - const -#endif - ASN1_TIME *asn1time); - -static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); -static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static void ngx_openssl_exit(ngx_cycle_t *cycle); - - -static ngx_command_t ngx_openssl_commands[] = { - - { ngx_string("ssl_engine"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, - ngx_openssl_engine, - 0, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_core_module_t ngx_openssl_module_ctx = { - ngx_string("openssl"), - ngx_openssl_create_conf, - NULL -}; - - -ngx_module_t ngx_openssl_module = { - NGX_MODULE_V1, - &ngx_openssl_module_ctx, /* module context */ - ngx_openssl_commands, /* module directives */ - NGX_CORE_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - ngx_openssl_exit, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -int ngx_ssl_connection_index; -int ngx_ssl_server_conf_index; -int ngx_ssl_session_cache_index; -int ngx_ssl_session_ticket_keys_index; -int ngx_ssl_certificate_index; -int ngx_ssl_next_certificate_index; -int ngx_ssl_certificate_name_index; -int ngx_ssl_stapling_index; - - -ngx_int_t -ngx_ssl_init(ngx_log_t *log) -{ -#if OPENSSL_VERSION_NUMBER >= 0x10100003L - - if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) == 0) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, "OPENSSL_init_ssl() failed"); - return NGX_ERROR; - } - - /* - * OPENSSL_init_ssl() may leave errors in the error queue - * while returning success - */ - - ERR_clear_error(); - -#else - - OPENSSL_config(NULL); - - SSL_library_init(); - SSL_load_error_strings(); - - OpenSSL_add_all_algorithms(); - -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL -#ifndef SSL_OP_NO_COMPRESSION - { - /* - * Disable gzip compression in OpenSSL prior to 1.0.0 version, - * this saves about 522K per connection. - */ - int n; - STACK_OF(SSL_COMP) *ssl_comp_methods; - - ssl_comp_methods = SSL_COMP_get_compression_methods(); - n = sk_SSL_COMP_num(ssl_comp_methods); - - while (n--) { - (void) sk_SSL_COMP_pop(ssl_comp_methods); - } - } -#endif -#endif - - ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); - - if (ngx_ssl_connection_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed"); - return NGX_ERROR; - } - - ngx_ssl_server_conf_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, - NULL); - if (ngx_ssl_server_conf_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, - "SSL_CTX_get_ex_new_index() failed"); - return NGX_ERROR; - } - - ngx_ssl_session_cache_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, - NULL); - if (ngx_ssl_session_cache_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, - "SSL_CTX_get_ex_new_index() failed"); - return NGX_ERROR; - } - - ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, - NULL, NULL); - if (ngx_ssl_session_ticket_keys_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, - "SSL_CTX_get_ex_new_index() failed"); - return NGX_ERROR; - } - - ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, - NULL); - if (ngx_ssl_certificate_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, - "SSL_CTX_get_ex_new_index() failed"); - return NGX_ERROR; - } - - ngx_ssl_next_certificate_index = X509_get_ex_new_index(0, NULL, NULL, NULL, - NULL); - if (ngx_ssl_next_certificate_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed"); - return NGX_ERROR; - } - - ngx_ssl_certificate_name_index = X509_get_ex_new_index(0, NULL, NULL, NULL, - NULL); - - if (ngx_ssl_certificate_name_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed"); - return NGX_ERROR; - } - - ngx_ssl_stapling_index = X509_get_ex_new_index(0, NULL, NULL, NULL, NULL); - - if (ngx_ssl_stapling_index == -1) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed"); - return NGX_ERROR; - } - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data) -{ - ssl->ctx = SSL_CTX_new(SSLv23_method()); - - if (ssl->ctx == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed"); - return NGX_ERROR; - } - - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_server_conf_index, data) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_ex_data() failed"); - return NGX_ERROR; - } - - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, NULL) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_ex_data() failed"); - return NGX_ERROR; - } - - ssl->buffer_size = NGX_SSL_BUFSIZE; - - /* client side options */ - -#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG - SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG); -#endif - -#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG - SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG); -#endif - - /* server side options */ - -#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG - SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); -#endif - -#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER - SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); -#endif - -#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING - /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */ - SSL_CTX_set_options(ssl->ctx, SSL_OP_MSIE_SSLV2_RSA_PADDING); -#endif - -#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG - SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG); -#endif - -#ifdef SSL_OP_TLS_D5_BUG - SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG); -#endif - -#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG - SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG); -#endif - -#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS - SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); -#endif - - SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE); - -#ifdef SSL_CTRL_CLEAR_OPTIONS - /* only in 0.9.8m+ */ - SSL_CTX_clear_options(ssl->ctx, - SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1); -#endif - - if (!(protocols & NGX_SSL_SSLv2)) { - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2); - } - if (!(protocols & NGX_SSL_SSLv3)) { - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv3); - } - if (!(protocols & NGX_SSL_TLSv1)) { - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1); - } -#ifdef SSL_OP_NO_TLSv1_1 - SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_1); - if (!(protocols & NGX_SSL_TLSv1_1)) { - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_1); - } -#endif -#ifdef SSL_OP_NO_TLSv1_2 - SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_2); - if (!(protocols & NGX_SSL_TLSv1_2)) { - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_2); - } -#endif - -#ifdef SSL_OP_NO_COMPRESSION - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION); -#endif - -#ifdef SSL_MODE_RELEASE_BUFFERS - SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS); -#endif - -#ifdef SSL_MODE_NO_AUTO_CHAIN - SSL_CTX_set_mode(ssl->ctx, SSL_MODE_NO_AUTO_CHAIN); -#endif - - SSL_CTX_set_read_ahead(ssl->ctx, 1); - - SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, - ngx_array_t *keys, ngx_array_t *passwords) -{ - ngx_str_t *cert, *key; - ngx_uint_t i; - - cert = certs->elts; - key = keys->elts; - - for (i = 0; i < certs->nelts; i++) { - - if (ngx_ssl_certificate(cf, ssl, &cert[i], &key[i], passwords) - != NGX_OK) - { - return NGX_ERROR; - } - } - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, - ngx_str_t *key, ngx_array_t *passwords) -{ - BIO *bio; - X509 *x509; - u_long n; - ngx_str_t *pwd; - ngx_uint_t tries; - - if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { - return NGX_ERROR; - } - - /* - * we can't use SSL_CTX_use_certificate_chain_file() as it doesn't - * allow to access certificate later from SSL_CTX, so we reimplement - * it here - */ - - bio = BIO_new_file((char *) cert->data, "r"); - if (bio == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "BIO_new_file(\"%s\") failed", cert->data); - return NGX_ERROR; - } - - x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL); - if (x509 == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "PEM_read_bio_X509_AUX(\"%s\") failed", cert->data); - BIO_free(bio); - return NGX_ERROR; - } - - if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_use_certificate(\"%s\") failed", cert->data); - X509_free(x509); - BIO_free(bio); - return NGX_ERROR; - } - - if (X509_set_ex_data(x509, ngx_ssl_certificate_name_index, cert->data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_set_ex_data() failed"); - X509_free(x509); - BIO_free(bio); - return NGX_ERROR; - } - - if (X509_set_ex_data(x509, ngx_ssl_next_certificate_index, - SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index)) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_set_ex_data() failed"); - X509_free(x509); - BIO_free(bio); - return NGX_ERROR; - } - - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_ex_data() failed"); - X509_free(x509); - BIO_free(bio); - return NGX_ERROR; - } - - /* read rest of the chain */ - - for ( ;; ) { - - x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); - if (x509 == NULL) { - n = ERR_peek_last_error(); - - if (ERR_GET_LIB(n) == ERR_LIB_PEM - && ERR_GET_REASON(n) == PEM_R_NO_START_LINE) - { - /* end of file */ - ERR_clear_error(); - break; - } - - /* some real error */ - - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "PEM_read_bio_X509(\"%s\") failed", cert->data); - BIO_free(bio); - return NGX_ERROR; - } - -#ifdef SSL_CTRL_CHAIN_CERT - - /* - * SSL_CTX_add0_chain_cert() is needed to add chain to - * a particular certificate when multiple certificates are used; - * only available in OpenSSL 1.0.2+ - */ - - if (SSL_CTX_add0_chain_cert(ssl->ctx, x509) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_add0_chain_cert(\"%s\") failed", - cert->data); - X509_free(x509); - BIO_free(bio); - return NGX_ERROR; - } - -#else - if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_add_extra_chain_cert(\"%s\") failed", - cert->data); - X509_free(x509); - BIO_free(bio); - return NGX_ERROR; - } -#endif - } - - BIO_free(bio); - - if (ngx_strncmp(key->data, "engine:", sizeof("engine:") - 1) == 0) { - -#ifndef OPENSSL_NO_ENGINE - - u_char *p, *last; - ENGINE *engine; - EVP_PKEY *pkey; - - p = key->data + sizeof("engine:") - 1; - last = (u_char *) ngx_strchr(p, ':'); - - if (last == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid syntax in \"%V\"", key); - return NGX_ERROR; - } - - *last = '\0'; - - engine = ENGINE_by_id((char *) p); - - if (engine == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "ENGINE_by_id(\"%s\") failed", p); - return NGX_ERROR; - } - - *last++ = ':'; - - pkey = ENGINE_load_private_key(engine, (char *) last, 0, 0); - - if (pkey == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "ENGINE_load_private_key(\"%s\") failed", last); - ENGINE_free(engine); - return NGX_ERROR; - } - - ENGINE_free(engine); - - if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_use_PrivateKey(\"%s\") failed", last); - EVP_PKEY_free(pkey); - return NGX_ERROR; - } - - EVP_PKEY_free(pkey); - - return NGX_OK; - -#else - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "loading \"engine:...\" certificate keys " - "is not supported"); - return NGX_ERROR; - -#endif - } - - if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) { - return NGX_ERROR; - } - - if (passwords) { - tries = passwords->nelts; - pwd = passwords->elts; - - SSL_CTX_set_default_passwd_cb(ssl->ctx, ngx_ssl_password_callback); - SSL_CTX_set_default_passwd_cb_userdata(ssl->ctx, pwd); - - } else { - tries = 1; -#if (NGX_SUPPRESS_WARN) - pwd = NULL; -#endif - } - - for ( ;; ) { - - if (SSL_CTX_use_PrivateKey_file(ssl->ctx, (char *) key->data, - SSL_FILETYPE_PEM) - != 0) - { - break; - } - - if (--tries) { - ERR_clear_error(); - SSL_CTX_set_default_passwd_cb_userdata(ssl->ctx, ++pwd); - continue; - } - - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key->data); - return NGX_ERROR; - } - - SSL_CTX_set_default_passwd_cb(ssl->ctx, NULL); - - return NGX_OK; -} - - -static int -ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata) -{ - ngx_str_t *pwd = userdata; - - if (rwflag) { - ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, - "ngx_ssl_password_callback() is called for encryption"); - return 0; - } - - if (pwd->len > (size_t) size) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, - "password is truncated to %d bytes", size); - } else { - size = pwd->len; - } - - ngx_memcpy(buf, pwd->data, size); - - return size; -} - - -ngx_int_t -ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, - ngx_uint_t prefer_server_ciphers) -{ - if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - ciphers); - return NGX_ERROR; - } - - if (prefer_server_ciphers) { - SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - /* a temporary 512-bit RSA key is required for export versions of MSIE */ - SSL_CTX_set_tmp_rsa_callback(ssl->ctx, ngx_ssl_rsa512_key_callback); -#endif - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, - ngx_int_t depth) -{ - STACK_OF(X509_NAME) *list; - - SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback); - - SSL_CTX_set_verify_depth(ssl->ctx, depth); - - if (cert->len == 0) { - return NGX_OK; - } - - if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { - return NGX_ERROR; - } - - if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_load_verify_locations(\"%s\") failed", - cert->data); - return NGX_ERROR; - } - - /* - * SSL_CTX_load_verify_locations() may leave errors in the error queue - * while returning success - */ - - ERR_clear_error(); - - list = SSL_load_client_CA_file((char *) cert->data); - - if (list == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_load_client_CA_file(\"%s\") failed", cert->data); - return NGX_ERROR; - } - - /* - * before 0.9.7h and 0.9.8 SSL_load_client_CA_file() - * always leaved an error in the error queue - */ - - ERR_clear_error(); - - SSL_CTX_set_client_CA_list(ssl->ctx, list); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, - ngx_int_t depth) -{ - SSL_CTX_set_verify_depth(ssl->ctx, depth); - - if (cert->len == 0) { - return NGX_OK; - } - - if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { - return NGX_ERROR; - } - - if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_load_verify_locations(\"%s\") failed", - cert->data); - return NGX_ERROR; - } - - /* - * SSL_CTX_load_verify_locations() may leave errors in the error queue - * while returning success - */ - - ERR_clear_error(); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl) -{ - X509_STORE *store; - X509_LOOKUP *lookup; - - if (crl->len == 0) { - return NGX_OK; - } - - if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) { - return NGX_ERROR; - } - - store = SSL_CTX_get_cert_store(ssl->ctx); - - if (store == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_get_cert_store() failed"); - return NGX_ERROR; - } - - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); - - if (lookup == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_STORE_add_lookup() failed"); - return NGX_ERROR; - } - - if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_LOOKUP_load_file(\"%s\") failed", crl->data); - return NGX_ERROR; - } - - X509_STORE_set_flags(store, - X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); - - return NGX_OK; -} - - -static int -ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store) -{ -#if (NGX_DEBUG) - char *subject, *issuer; - int err, depth; - X509 *cert; - X509_NAME *sname, *iname; - ngx_connection_t *c; - ngx_ssl_conn_t *ssl_conn; - - ssl_conn = X509_STORE_CTX_get_ex_data(x509_store, - SSL_get_ex_data_X509_STORE_CTX_idx()); - - c = ngx_ssl_get_connection(ssl_conn); - - cert = X509_STORE_CTX_get_current_cert(x509_store); - err = X509_STORE_CTX_get_error(x509_store); - depth = X509_STORE_CTX_get_error_depth(x509_store); - - sname = X509_get_subject_name(cert); - subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)"; - - iname = X509_get_issuer_name(cert); - issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)"; - - ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0, - "verify:%d, error:%d, depth:%d, " - "subject:\"%s\", issuer:\"%s\"", - ok, err, depth, subject, issuer); - - if (sname) { - OPENSSL_free(subject); - } - - if (iname) { - OPENSSL_free(issuer); - } -#endif - - return 1; -} - - -static void -ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret) -{ - BIO *rbio, *wbio; - ngx_connection_t *c; - - if (where & SSL_CB_HANDSHAKE_START) { - c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); - - if (c->ssl->handshaked) { - c->ssl->renegotiation = 1; - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation"); - } - } - - if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) { - c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); - - if (!c->ssl->handshake_buffer_set) { - /* - * By default OpenSSL uses 4k buffer during a handshake, - * which is too low for long certificate chains and might - * result in extra round-trips. - * - * To adjust a buffer size we detect that buffering was added - * to write side of the connection by comparing rbio and wbio. - * If they are different, we assume that it's due to buffering - * added to wbio, and set buffer size. - */ - - rbio = SSL_get_rbio((ngx_ssl_conn_t *) ssl_conn); - wbio = SSL_get_wbio((ngx_ssl_conn_t *) ssl_conn); - - if (rbio != wbio) { - (void) BIO_set_write_buffer_size(wbio, NGX_SSL_BUFSIZE); - c->ssl->handshake_buffer_set = 1; - } - } - } -} - - -RSA * -ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export, - int key_length) -{ - static RSA *key; - - if (key_length != 512) { - return NULL; - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100003L && !defined OPENSSL_NO_DEPRECATED) - - if (key == NULL) { - key = RSA_generate_key(512, RSA_F4, NULL, NULL); - } - -#endif - - return key; -} - - -ngx_array_t * -ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file) -{ - u_char *p, *last, *end; - size_t len; - ssize_t n; - ngx_fd_t fd; - ngx_str_t *pwd; - ngx_array_t *passwords; - ngx_pool_cleanup_t *cln; - u_char buf[NGX_SSL_PASSWORD_BUFFER_SIZE]; - - if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) { - return NULL; - } - - cln = ngx_pool_cleanup_add(cf->temp_pool, 0); - passwords = ngx_array_create(cf->temp_pool, 4, sizeof(ngx_str_t)); - - if (cln == NULL || passwords == NULL) { - return NULL; - } - - cln->handler = ngx_ssl_passwords_cleanup; - cln->data = passwords; - - fd = ngx_open_file(file->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); - if (fd == NGX_INVALID_FILE) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, - ngx_open_file_n " \"%s\" failed", file->data); - return NULL; - } - - len = 0; - last = buf; - - do { - n = ngx_read_fd(fd, last, NGX_SSL_PASSWORD_BUFFER_SIZE - len); - - if (n == -1) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, - ngx_read_fd_n " \"%s\" failed", file->data); - passwords = NULL; - goto cleanup; - } - - end = last + n; - - if (len && n == 0) { - *end++ = LF; - } - - p = buf; - - for ( ;; ) { - last = ngx_strlchr(last, end, LF); - - if (last == NULL) { - break; - } - - len = last++ - p; - - if (len && p[len - 1] == CR) { - len--; - } - - if (len) { - pwd = ngx_array_push(passwords); - if (pwd == NULL) { - passwords = NULL; - goto cleanup; - } - - pwd->len = len; - pwd->data = ngx_pnalloc(cf->temp_pool, len); - - if (pwd->data == NULL) { - passwords->nelts--; - passwords = NULL; - goto cleanup; - } - - ngx_memcpy(pwd->data, p, len); - } - - p = last; - } - - len = end - p; - - if (len == NGX_SSL_PASSWORD_BUFFER_SIZE) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "too long line in \"%s\"", file->data); - passwords = NULL; - goto cleanup; - } - - ngx_memmove(buf, p, len); - last = buf + len; - - } while (n != 0); - - if (passwords->nelts == 0) { - pwd = ngx_array_push(passwords); - if (pwd == NULL) { - passwords = NULL; - goto cleanup; - } - - ngx_memzero(pwd, sizeof(ngx_str_t)); - } - -cleanup: - - if (ngx_close_file(fd) == NGX_FILE_ERROR) { - ngx_conf_log_error(NGX_LOG_ALERT, cf, ngx_errno, - ngx_close_file_n " \"%s\" failed", file->data); - } - - ngx_memzero(buf, NGX_SSL_PASSWORD_BUFFER_SIZE); - - return passwords; -} - - -static void -ngx_ssl_passwords_cleanup(void *data) -{ - ngx_array_t *passwords = data; - - ngx_str_t *pwd; - ngx_uint_t i; - - pwd = passwords->elts; - - for (i = 0; i < passwords->nelts; i++) { - ngx_memzero(pwd[i].data, pwd[i].len); - } -} - - -ngx_int_t -ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file) -{ - DH *dh; - BIO *bio; - - if (file->len == 0) { - return NGX_OK; - } - - if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) { - return NGX_ERROR; - } - - bio = BIO_new_file((char *) file->data, "r"); - if (bio == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "BIO_new_file(\"%s\") failed", file->data); - return NGX_ERROR; - } - - dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); - if (dh == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "PEM_read_bio_DHparams(\"%s\") failed", file->data); - BIO_free(bio); - return NGX_ERROR; - } - - SSL_CTX_set_tmp_dh(ssl->ctx, dh); - - DH_free(dh); - BIO_free(bio); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name) -{ -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL -#ifndef OPENSSL_NO_ECDH - - /* - * Elliptic-Curve Diffie-Hellman parameters are either "named curves" - * from RFC 4492 section 5.1.1, or explicitly described curves over - * binary fields. OpenSSL only supports the "named curves", which provide - * maximum interoperability. - */ - -#ifdef SSL_CTRL_SET_CURVES_LIST - - /* - * OpenSSL 1.0.2+ allows configuring a curve list instead of a single - * curve previously supported. By default an internal list is used, - * with prime256v1 being preferred by server in OpenSSL 1.0.2b+ - * and X25519 in OpenSSL 1.1.0+. - * - * By default a curve preferred by the client will be used for - * key exchange. The SSL_OP_CIPHER_SERVER_PREFERENCE option can - * be used to prefer server curves instead, similar to what it - * does for ciphers. - */ - - SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE); - -#if SSL_CTRL_SET_ECDH_AUTO - /* not needed in OpenSSL 1.1.0+ */ - SSL_CTX_set_ecdh_auto(ssl->ctx, 1); -#endif - - if (ngx_strcmp(name->data, "auto") == 0) { - return NGX_OK; - } - - if (SSL_CTX_set1_curves_list(ssl->ctx, (char *) name->data) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set1_curves_list(\"%s\") failed", name->data); - return NGX_ERROR; - } - -#else - - int nid; - char *curve; - EC_KEY *ecdh; - - if (ngx_strcmp(name->data, "auto") == 0) { - curve = "prime256v1"; - - } else { - curve = (char *) name->data; - } - - nid = OBJ_sn2nid(curve); - if (nid == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "OBJ_sn2nid(\"%s\") failed: unknown curve", curve); - return NGX_ERROR; - } - - ecdh = EC_KEY_new_by_curve_name(nid); - if (ecdh == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EC_KEY_new_by_curve_name(\"%s\") failed", curve); - return NGX_ERROR; - } - - SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE); - - SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh); - - EC_KEY_free(ecdh); -#endif -#endif -#endif - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags) -{ - ngx_ssl_connection_t *sc; - - sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t)); - if (sc == NULL) { - return NGX_ERROR; - } - - sc->buffer = ((flags & NGX_SSL_BUFFER) != 0); - sc->buffer_size = ssl->buffer_size; - - sc->session_ctx = ssl->ctx; - - sc->connection = SSL_new(ssl->ctx); - - if (sc->connection == NULL) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); - return NGX_ERROR; - } - - if (SSL_set_fd(sc->connection, c->fd) == 0) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed"); - return NGX_ERROR; - } - - if (flags & NGX_SSL_CLIENT) { - SSL_set_connect_state(sc->connection); - - } else { - SSL_set_accept_state(sc->connection); - } - - if (SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) == 0) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed"); - return NGX_ERROR; - } - - c->ssl = sc; - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session) -{ - if (session) { - if (SSL_set_session(c->ssl->connection, session) == 0) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_session() failed"); - return NGX_ERROR; - } - } - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_handshake(ngx_connection_t *c) -{ - int n, sslerr; - ngx_err_t err; - - ngx_ssl_clear_error(c->log); - - n = SSL_do_handshake(c->ssl->connection); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); - - if (n == 1) { - - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - return NGX_ERROR; - } - - if (ngx_handle_write_event(c->write, 0) != NGX_OK) { - return NGX_ERROR; - } - -#if (NGX_DEBUG) - { - char buf[129], *s, *d; -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - const -#endif - SSL_CIPHER *cipher; - - cipher = SSL_get_current_cipher(c->ssl->connection); - - if (cipher) { - SSL_CIPHER_description(cipher, &buf[1], 128); - - for (s = &buf[1], d = buf; *s; s++) { - if (*s == ' ' && *d == ' ') { - continue; - } - - if (*s == LF || *s == CR) { - continue; - } - - *++d = *s; - } - - if (*d != ' ') { - d++; - } - - *d = '\0'; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL: %s, cipher: \"%s\"", - SSL_get_version(c->ssl->connection), &buf[1]); - - if (SSL_session_reused(c->ssl->connection)) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL reused session"); - } - - } else { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL no shared ciphers"); - } - } -#endif - - c->ssl->handshaked = 1; - - c->recv = ngx_ssl_recv; - c->send = ngx_ssl_write; - c->recv_chain = ngx_ssl_recv_chain; - c->send_chain = ngx_ssl_send_chain; - -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS - - /* initial handshake done, disable renegotiation (CVE-2009-3555) */ - if (c->ssl->connection->s3) { - c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; - } - -#endif -#endif - - return NGX_OK; - } - - sslerr = SSL_get_error(c->ssl->connection, n); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); - - if (sslerr == SSL_ERROR_WANT_READ) { - c->read->ready = 0; - c->read->handler = ngx_ssl_handshake_handler; - c->write->handler = ngx_ssl_handshake_handler; - - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - return NGX_ERROR; - } - - if (ngx_handle_write_event(c->write, 0) != NGX_OK) { - return NGX_ERROR; - } - - return NGX_AGAIN; - } - - if (sslerr == SSL_ERROR_WANT_WRITE) { - c->write->ready = 0; - c->read->handler = ngx_ssl_handshake_handler; - c->write->handler = ngx_ssl_handshake_handler; - - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - return NGX_ERROR; - } - - if (ngx_handle_write_event(c->write, 0) != NGX_OK) { - return NGX_ERROR; - } - - return NGX_AGAIN; - } - - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - c->ssl->no_wait_shutdown = 1; - c->ssl->no_send_shutdown = 1; - c->read->eof = 1; - - if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { - ngx_connection_error(c, err, - "peer closed connection in SSL handshake"); - - return NGX_ERROR; - } - - c->read->error = 1; - - ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed"); - - return NGX_ERROR; -} - - -static void -ngx_ssl_handshake_handler(ngx_event_t *ev) -{ - ngx_connection_t *c; - - c = ev->data; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL handshake handler: %d", ev->write); - - if (ev->timedout) { - c->ssl->handler(c); - return; - } - - if (ngx_ssl_handshake(c) == NGX_AGAIN) { - return; - } - - c->ssl->handler(c); -} - - -ssize_t -ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl, off_t limit) -{ - u_char *last; - ssize_t n, bytes, size; - ngx_buf_t *b; - - bytes = 0; - - b = cl->buf; - last = b->last; - - for ( ;; ) { - size = b->end - last; - - if (limit) { - if (bytes >= limit) { - return bytes; - } - - if (bytes + size > limit) { - size = (ssize_t) (limit - bytes); - } - } - - n = ngx_ssl_recv(c, last, size); - - if (n > 0) { - last += n; - bytes += n; - - if (last == b->end) { - cl = cl->next; - - if (cl == NULL) { - return bytes; - } - - b = cl->buf; - last = b->last; - } - - continue; - } - - if (bytes) { - - if (n == 0 || n == NGX_ERROR) { - c->read->ready = 1; - } - - return bytes; - } - - return n; - } -} - - -ssize_t -ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) -{ - int n, bytes; - - if (c->ssl->last == NGX_ERROR) { - c->read->error = 1; - return NGX_ERROR; - } - - if (c->ssl->last == NGX_DONE) { - c->read->ready = 0; - c->read->eof = 1; - return 0; - } - - bytes = 0; - - ngx_ssl_clear_error(c->log); - - /* - * SSL_read() may return data in parts, so try to read - * until SSL_read() would return no data - */ - - for ( ;; ) { - - n = SSL_read(c->ssl->connection, buf, size); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); - - if (n > 0) { - bytes += n; - } - - c->ssl->last = ngx_ssl_handle_recv(c, n); - - if (c->ssl->last == NGX_OK) { - - size -= n; - - if (size == 0) { - c->read->ready = 1; - return bytes; - } - - buf += n; - - continue; - } - - if (bytes) { - if (c->ssl->last != NGX_AGAIN) { - c->read->ready = 1; - } - - return bytes; - } - - switch (c->ssl->last) { - - case NGX_DONE: - c->read->ready = 0; - c->read->eof = 1; - return 0; - - case NGX_ERROR: - c->read->error = 1; - - /* fall through */ - - case NGX_AGAIN: - return c->ssl->last; - } - } -} - - -static ngx_int_t -ngx_ssl_handle_recv(ngx_connection_t *c, int n) -{ - int sslerr; - ngx_err_t err; - - if (c->ssl->renegotiation) { - /* - * disable renegotiation (CVE-2009-3555): - * OpenSSL (at least up to 0.9.8l) does not handle disabled - * renegotiation gracefully, so drop connection here - */ - - ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled"); - - while (ERR_peek_error()) { - ngx_ssl_error(NGX_LOG_DEBUG, c->log, 0, - "ignoring stale global SSL error"); - } - - ERR_clear_error(); - - c->ssl->no_wait_shutdown = 1; - c->ssl->no_send_shutdown = 1; - - return NGX_ERROR; - } - - if (n > 0) { - - if (c->ssl->saved_write_handler) { - - c->write->handler = c->ssl->saved_write_handler; - c->ssl->saved_write_handler = NULL; - c->write->ready = 1; - - if (ngx_handle_write_event(c->write, 0) != NGX_OK) { - return NGX_ERROR; - } - - ngx_post_event(c->write, &ngx_posted_events); - } - - return NGX_OK; - } - - sslerr = SSL_get_error(c->ssl->connection, n); - - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); - - if (sslerr == SSL_ERROR_WANT_READ) { - c->read->ready = 0; - return NGX_AGAIN; - } - - if (sslerr == SSL_ERROR_WANT_WRITE) { - - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "peer started SSL renegotiation"); - - c->write->ready = 0; - - if (ngx_handle_write_event(c->write, 0) != NGX_OK) { - return NGX_ERROR; - } - - /* - * we do not set the timer because there is already the read event timer - */ - - if (c->ssl->saved_write_handler == NULL) { - c->ssl->saved_write_handler = c->write->handler; - c->write->handler = ngx_ssl_write_handler; - } - - return NGX_AGAIN; - } - - c->ssl->no_wait_shutdown = 1; - c->ssl->no_send_shutdown = 1; - - if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "peer shutdown SSL cleanly"); - return NGX_DONE; - } - - ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed"); - - return NGX_ERROR; -} - - -static void -ngx_ssl_write_handler(ngx_event_t *wev) -{ - ngx_connection_t *c; - - c = wev->data; - - c->read->handler(c->read); -} - - -/* - * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer - * before the SSL_write() call to decrease a SSL overhead. - * - * Besides for protocols such as HTTP it is possible to always buffer - * the output to decrease a SSL overhead some more. - */ - -ngx_chain_t * -ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) -{ - int n; - ngx_uint_t flush; - ssize_t send, size; - ngx_buf_t *buf; - - if (!c->ssl->buffer) { - - while (in) { - if (ngx_buf_special(in->buf)) { - in = in->next; - continue; - } - - n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos); - - if (n == NGX_ERROR) { - return NGX_CHAIN_ERROR; - } - - if (n == NGX_AGAIN) { - return in; - } - - in->buf->pos += n; - - if (in->buf->pos == in->buf->last) { - in = in->next; - } - } - - return in; - } - - - /* the maximum limit size is the maximum int32_t value - the page size */ - - if (limit == 0 || limit > (off_t) (NGX_MAX_INT32_VALUE - ngx_pagesize)) { - limit = NGX_MAX_INT32_VALUE - ngx_pagesize; - } - - buf = c->ssl->buf; - - if (buf == NULL) { - buf = ngx_create_temp_buf(c->pool, c->ssl->buffer_size); - if (buf == NULL) { - return NGX_CHAIN_ERROR; - } - - c->ssl->buf = buf; - } - - if (buf->start == NULL) { - buf->start = ngx_palloc(c->pool, c->ssl->buffer_size); - if (buf->start == NULL) { - return NGX_CHAIN_ERROR; - } - - buf->pos = buf->start; - buf->last = buf->start; - buf->end = buf->start + c->ssl->buffer_size; - } - - send = buf->last - buf->pos; - flush = (in == NULL) ? 1 : buf->flush; - - for ( ;; ) { - - while (in && buf->last < buf->end && send < limit) { - if (in->buf->last_buf || in->buf->flush) { - flush = 1; - } - - if (ngx_buf_special(in->buf)) { - in = in->next; - continue; - } - - size = in->buf->last - in->buf->pos; - - if (size > buf->end - buf->last) { - size = buf->end - buf->last; - } - - if (send + size > limit) { - size = (ssize_t) (limit - send); - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL buf copy: %z", size); - - ngx_memcpy(buf->last, in->buf->pos, size); - - buf->last += size; - in->buf->pos += size; - send += size; - - if (in->buf->pos == in->buf->last) { - in = in->next; - } - } - - if (!flush && send < limit && buf->last < buf->end) { - break; - } - - size = buf->last - buf->pos; - - if (size == 0) { - buf->flush = 0; - c->buffered &= ~NGX_SSL_BUFFERED; - return in; - } - - n = ngx_ssl_write(c, buf->pos, size); - - if (n == NGX_ERROR) { - return NGX_CHAIN_ERROR; - } - - if (n == NGX_AGAIN) { - break; - } - - buf->pos += n; - - if (n < size) { - break; - } - - flush = 0; - - buf->pos = buf->start; - buf->last = buf->start; - - if (in == NULL || send == limit) { - break; - } - } - - buf->flush = flush; - - if (buf->pos < buf->last) { - c->buffered |= NGX_SSL_BUFFERED; - - } else { - c->buffered &= ~NGX_SSL_BUFFERED; - } - - return in; -} - - -ssize_t -ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) -{ - int n, sslerr; - ngx_err_t err; - - ngx_ssl_clear_error(c->log); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size); - - n = SSL_write(c->ssl->connection, data, size); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); - - if (n > 0) { - - if (c->ssl->saved_read_handler) { - - c->read->handler = c->ssl->saved_read_handler; - c->ssl->saved_read_handler = NULL; - c->read->ready = 1; - - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - return NGX_ERROR; - } - - ngx_post_event(c->read, &ngx_posted_events); - } - - c->sent += n; - - return n; - } - - sslerr = SSL_get_error(c->ssl->connection, n); - - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); - - if (sslerr == SSL_ERROR_WANT_WRITE) { - c->write->ready = 0; - return NGX_AGAIN; - } - - if (sslerr == SSL_ERROR_WANT_READ) { - - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "peer started SSL renegotiation"); - - c->read->ready = 0; - - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - return NGX_ERROR; - } - - /* - * we do not set the timer because there is already - * the write event timer - */ - - if (c->ssl->saved_read_handler == NULL) { - c->ssl->saved_read_handler = c->read->handler; - c->read->handler = ngx_ssl_read_handler; - } - - return NGX_AGAIN; - } - - c->ssl->no_wait_shutdown = 1; - c->ssl->no_send_shutdown = 1; - c->write->error = 1; - - ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed"); - - return NGX_ERROR; -} - - -static void -ngx_ssl_read_handler(ngx_event_t *rev) -{ - ngx_connection_t *c; - - c = rev->data; - - c->write->handler(c->write); -} - - -void -ngx_ssl_free_buffer(ngx_connection_t *c) -{ - if (c->ssl->buf && c->ssl->buf->start) { - if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) { - c->ssl->buf->start = NULL; - } - } -} - - -ngx_int_t -ngx_ssl_shutdown(ngx_connection_t *c) -{ - int n, sslerr, mode; - ngx_err_t err; - - if (SSL_in_init(c->ssl->connection)) { - /* - * OpenSSL 1.0.2f complains if SSL_shutdown() is called during - * an SSL handshake, while previous versions always return 0. - * Avoid calling SSL_shutdown() if handshake wasn't completed. - */ - - SSL_free(c->ssl->connection); - c->ssl = NULL; - - return NGX_OK; - } - - if (c->timedout) { - mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; - SSL_set_quiet_shutdown(c->ssl->connection, 1); - - } else { - mode = SSL_get_shutdown(c->ssl->connection); - - if (c->ssl->no_wait_shutdown) { - mode |= SSL_RECEIVED_SHUTDOWN; - } - - if (c->ssl->no_send_shutdown) { - mode |= SSL_SENT_SHUTDOWN; - } - - if (c->ssl->no_wait_shutdown && c->ssl->no_send_shutdown) { - SSL_set_quiet_shutdown(c->ssl->connection, 1); - } - } - - SSL_set_shutdown(c->ssl->connection, mode); - - ngx_ssl_clear_error(c->log); - - n = SSL_shutdown(c->ssl->connection); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); - - sslerr = 0; - - /* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */ - - if (n != 1 && ERR_peek_error()) { - sslerr = SSL_get_error(c->ssl->connection, n); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL_get_error: %d", sslerr); - } - - if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) { - SSL_free(c->ssl->connection); - c->ssl = NULL; - - return NGX_OK; - } - - if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) { - c->read->handler = ngx_ssl_shutdown_handler; - c->write->handler = ngx_ssl_shutdown_handler; - - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - return NGX_ERROR; - } - - if (ngx_handle_write_event(c->write, 0) != NGX_OK) { - return NGX_ERROR; - } - - if (sslerr == SSL_ERROR_WANT_READ) { - ngx_add_timer(c->read, 30000); - } - - return NGX_AGAIN; - } - - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed"); - - SSL_free(c->ssl->connection); - c->ssl = NULL; - - return NGX_ERROR; -} - - -static void -ngx_ssl_shutdown_handler(ngx_event_t *ev) -{ - ngx_connection_t *c; - ngx_connection_handler_pt handler; - - c = ev->data; - handler = c->ssl->handler; - - if (ev->timedout) { - c->timedout = 1; - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "SSL shutdown handler"); - - if (ngx_ssl_shutdown(c) == NGX_AGAIN) { - return; - } - - handler(c); -} - - -static void -ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, - char *text) -{ - int n; - ngx_uint_t level; - - level = NGX_LOG_CRIT; - - if (sslerr == SSL_ERROR_SYSCALL) { - - if (err == NGX_ECONNRESET - || err == NGX_EPIPE - || err == NGX_ENOTCONN - || err == NGX_ETIMEDOUT - || err == NGX_ECONNREFUSED - || err == NGX_ENETDOWN - || err == NGX_ENETUNREACH - || err == NGX_EHOSTDOWN - || err == NGX_EHOSTUNREACH) - { - switch (c->log_error) { - - case NGX_ERROR_IGNORE_ECONNRESET: - case NGX_ERROR_INFO: - level = NGX_LOG_INFO; - break; - - case NGX_ERROR_ERR: - level = NGX_LOG_ERR; - break; - - default: - break; - } - } - - } else if (sslerr == SSL_ERROR_SSL) { - - n = ERR_GET_REASON(ERR_peek_error()); - - /* handshake failures */ - if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */ - || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */ - || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ - || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */ - || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */ - || n == SSL_R_LENGTH_MISMATCH /* 159 */ -#ifdef SSL_R_NO_CIPHERS_PASSED - || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ -#endif - || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ - || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */ - || n == SSL_R_NO_SHARED_CIPHER /* 193 */ - || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ -#ifdef SSL_R_PARSE_TLSEXT - || n == SSL_R_PARSE_TLSEXT /* 227 */ -#endif - || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */ - || n == SSL_R_UNEXPECTED_RECORD /* 245 */ - || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */ - || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */ - || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */ - || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */ -#ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG - || n == SSL_R_RENEGOTIATE_EXT_TOO_LONG /* 335 */ - || n == SSL_R_RENEGOTIATION_ENCODING_ERR /* 336 */ - || n == SSL_R_RENEGOTIATION_MISMATCH /* 337 */ -#endif -#ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED - || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED /* 338 */ -#endif -#ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING - || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING /* 345 */ -#endif -#ifdef SSL_R_INAPPROPRIATE_FALLBACK - || n == SSL_R_INAPPROPRIATE_FALLBACK /* 373 */ -#endif - || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ -#ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE - || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */ - || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */ - || n == SSL_R_TLSV1_ALERT_DECRYPTION_FAILED /* 1021 */ - || n == SSL_R_TLSV1_ALERT_RECORD_OVERFLOW /* 1022 */ - || n == SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE /* 1030 */ - || n == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE /* 1040 */ - || n == SSL_R_SSLV3_ALERT_NO_CERTIFICATE /* 1041 */ - || n == SSL_R_SSLV3_ALERT_BAD_CERTIFICATE /* 1042 */ - || n == SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE /* 1043 */ - || n == SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED /* 1044 */ - || n == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED /* 1045 */ - || n == SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN /* 1046 */ - || n == SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER /* 1047 */ - || n == SSL_R_TLSV1_ALERT_UNKNOWN_CA /* 1048 */ - || n == SSL_R_TLSV1_ALERT_ACCESS_DENIED /* 1049 */ - || n == SSL_R_TLSV1_ALERT_DECODE_ERROR /* 1050 */ - || n == SSL_R_TLSV1_ALERT_DECRYPT_ERROR /* 1051 */ - || n == SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION /* 1060 */ - || n == SSL_R_TLSV1_ALERT_PROTOCOL_VERSION /* 1070 */ - || n == SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY /* 1071 */ - || n == SSL_R_TLSV1_ALERT_INTERNAL_ERROR /* 1080 */ - || n == SSL_R_TLSV1_ALERT_USER_CANCELLED /* 1090 */ - || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION /* 1100 */ -#endif - ) - { - switch (c->log_error) { - - case NGX_ERROR_IGNORE_ECONNRESET: - case NGX_ERROR_INFO: - level = NGX_LOG_INFO; - break; - - case NGX_ERROR_ERR: - level = NGX_LOG_ERR; - break; - - default: - break; - } - } - } - - ngx_ssl_error(level, c->log, err, text); -} - - -static void -ngx_ssl_clear_error(ngx_log_t *log) -{ - while (ERR_peek_error()) { - ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error"); - } - - ERR_clear_error(); -} - - -void ngx_cdecl -ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) -{ - int flags; - u_long n; - va_list args; - u_char *p, *last; - u_char errstr[NGX_MAX_CONF_ERRSTR]; - const char *data; - - last = errstr + NGX_MAX_CONF_ERRSTR; - - va_start(args, fmt); - p = ngx_vslprintf(errstr, last - 1, fmt, args); - va_end(args); - - p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p); - - for ( ;; ) { - - n = ERR_peek_error_line_data(NULL, NULL, &data, &flags); - - if (n == 0) { - break; - } - - /* ERR_error_string_n() requires at least one byte */ - - if (p >= last - 1) { - goto next; - } - - *p++ = ' '; - - ERR_error_string_n(n, (char *) p, last - p); - - while (p < last && *p) { - p++; - } - - if (p < last && *data && (flags & ERR_TXT_STRING)) { - *p++ = ':'; - p = ngx_cpystrn(p, (u_char *) data, last - p); - } - - next: - - (void) ERR_get_error(); - } - - ngx_log_error(level, log, err, "%*s)", p - errstr, errstr); -} - - -ngx_int_t -ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, - ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout) -{ - long cache_mode; - - SSL_CTX_set_timeout(ssl->ctx, (long) timeout); - - if (ngx_ssl_session_id_context(ssl, sess_ctx) != NGX_OK) { - return NGX_ERROR; - } - - if (builtin_session_cache == NGX_SSL_NO_SCACHE) { - SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF); - return NGX_OK; - } - - if (builtin_session_cache == NGX_SSL_NONE_SCACHE) { - - /* - * If the server explicitly says that it does not support - * session reuse (see SSL_SESS_CACHE_OFF above), then - * Outlook Express fails to upload a sent email to - * the Sent Items folder on the IMAP server via a separate IMAP - * connection in the background. Therefore we have a special - * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE) - * where the server pretends that it supports session reuse, - * but it does not actually store any session. - */ - - SSL_CTX_set_session_cache_mode(ssl->ctx, - SSL_SESS_CACHE_SERVER - |SSL_SESS_CACHE_NO_AUTO_CLEAR - |SSL_SESS_CACHE_NO_INTERNAL_STORE); - - SSL_CTX_sess_set_cache_size(ssl->ctx, 1); - - return NGX_OK; - } - - cache_mode = SSL_SESS_CACHE_SERVER; - - if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) { - cache_mode |= SSL_SESS_CACHE_NO_INTERNAL; - } - - SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode); - - if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) { - - if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) { - SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache); - } - } - - if (shm_zone) { - SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session); - SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session); - SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session); - - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_ex_data() failed"); - return NGX_ERROR; - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx) -{ - int n, i; - X509 *cert; - X509_NAME *name; - EVP_MD_CTX *md; - unsigned int len; - STACK_OF(X509_NAME) *list; - u_char buf[EVP_MAX_MD_SIZE]; - - /* - * Session ID context is set based on the string provided, - * the server certificates, and the client CA list. - */ - - md = EVP_MD_CTX_create(); - if (md == NULL) { - return NGX_ERROR; - } - - if (EVP_DigestInit_ex(md, EVP_sha1(), NULL) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EVP_DigestInit_ex() failed"); - goto failed; - } - - if (EVP_DigestUpdate(md, sess_ctx->data, sess_ctx->len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EVP_DigestUpdate() failed"); - goto failed; - } - - for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); - cert; - cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index)) - { - if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_digest() failed"); - goto failed; - } - - if (EVP_DigestUpdate(md, buf, len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EVP_DigestUpdate() failed"); - goto failed; - } - } - - list = SSL_CTX_get_client_CA_list(ssl->ctx); - - if (list != NULL) { - n = sk_X509_NAME_num(list); - - for (i = 0; i < n; i++) { - name = sk_X509_NAME_value(list, i); - - if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_NAME_digest() failed"); - goto failed; - } - - if (EVP_DigestUpdate(md, buf, len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EVP_DigestUpdate() failed"); - goto failed; - } - } - } - - if (EVP_DigestFinal_ex(md, buf, &len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EVP_DigestUpdate() failed"); - goto failed; - } - - EVP_MD_CTX_destroy(md); - - if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_session_id_context() failed"); - return NGX_ERROR; - } - - return NGX_OK; - -failed: - - EVP_MD_CTX_destroy(md); - - return NGX_ERROR; -} - - -ngx_int_t -ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data) -{ - size_t len; - ngx_slab_pool_t *shpool; - ngx_ssl_session_cache_t *cache; - - if (data) { - shm_zone->data = data; - return NGX_OK; - } - - shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - - if (shm_zone->shm.exists) { - shm_zone->data = shpool->data; - return NGX_OK; - } - - cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); - if (cache == NULL) { - return NGX_ERROR; - } - - shpool->data = cache; - shm_zone->data = cache; - - ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel, - ngx_ssl_session_rbtree_insert_value); - - ngx_queue_init(&cache->expire_queue); - - len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len; - - shpool->log_ctx = ngx_slab_alloc(shpool, len); - if (shpool->log_ctx == NULL) { - return NGX_ERROR; - } - - ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z", - &shm_zone->shm.name); - - shpool->log_nomem = 0; - - return NGX_OK; -} - - -/* - * The length of the session id is 16 bytes for SSLv2 sessions and - * between 1 and 32 bytes for SSLv3/TLSv1, typically 32 bytes. - * It seems that the typical length of the external ASN1 representation - * of a session is 118 or 119 bytes for SSLv3/TSLv1. - * - * Thus on 32-bit platforms we allocate separately an rbtree node, - * a session id, and an ASN1 representation, they take accordingly - * 64, 32, and 128 bytes. - * - * On 64-bit platforms we allocate separately an rbtree node + session_id, - * and an ASN1 representation, they take accordingly 128 and 128 bytes. - * - * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow, - * so they are outside the code locked by shared pool mutex - */ - -static int -ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess) -{ - int len; - u_char *p, *id, *cached_sess, *session_id; - uint32_t hash; - SSL_CTX *ssl_ctx; - unsigned int session_id_length; - ngx_shm_zone_t *shm_zone; - ngx_connection_t *c; - ngx_slab_pool_t *shpool; - ngx_ssl_sess_id_t *sess_id; - ngx_ssl_session_cache_t *cache; - u_char buf[NGX_SSL_MAX_SESSION_SIZE]; - - len = i2d_SSL_SESSION(sess, NULL); - - /* do not cache too big session */ - - if (len > (int) NGX_SSL_MAX_SESSION_SIZE) { - return 0; - } - - p = buf; - i2d_SSL_SESSION(sess, &p); - - c = ngx_ssl_get_connection(ssl_conn); - - ssl_ctx = c->ssl->session_ctx; - shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index); - - cache = shm_zone->data; - shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - - ngx_shmtx_lock(&shpool->mutex); - - /* drop one or two expired sessions */ - ngx_ssl_expire_sessions(cache, shpool, 1); - - cached_sess = ngx_slab_alloc_locked(shpool, len); - - if (cached_sess == NULL) { - - /* drop the oldest non-expired session and try once more */ - - ngx_ssl_expire_sessions(cache, shpool, 0); - - cached_sess = ngx_slab_alloc_locked(shpool, len); - - if (cached_sess == NULL) { - sess_id = NULL; - goto failed; - } - } - - sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t)); - - if (sess_id == NULL) { - - /* drop the oldest non-expired session and try once more */ - - ngx_ssl_expire_sessions(cache, shpool, 0); - - sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t)); - - if (sess_id == NULL) { - goto failed; - } - } - -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL - - session_id = (u_char *) SSL_SESSION_get_id(sess, &session_id_length); - -#else - - session_id = sess->session_id; - session_id_length = sess->session_id_length; - -#endif - -#if (NGX_PTR_SIZE == 8) - - id = sess_id->sess_id; - -#else - - id = ngx_slab_alloc_locked(shpool, session_id_length); - - if (id == NULL) { - - /* drop the oldest non-expired session and try once more */ - - ngx_ssl_expire_sessions(cache, shpool, 0); - - id = ngx_slab_alloc_locked(shpool, session_id_length); - - if (id == NULL) { - goto failed; - } - } - -#endif - - ngx_memcpy(cached_sess, buf, len); - - ngx_memcpy(id, session_id, session_id_length); - - hash = ngx_crc32_short(session_id, session_id_length); - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl new session: %08XD:%ud:%d", - hash, session_id_length, len); - - sess_id->node.key = hash; - sess_id->node.data = (u_char) session_id_length; - sess_id->id = id; - sess_id->len = len; - sess_id->session = cached_sess; - - sess_id->expire = ngx_time() + SSL_CTX_get_timeout(ssl_ctx); - - ngx_queue_insert_head(&cache->expire_queue, &sess_id->queue); - - ngx_rbtree_insert(&cache->session_rbtree, &sess_id->node); - - ngx_shmtx_unlock(&shpool->mutex); - - return 0; - -failed: - - if (cached_sess) { - ngx_slab_free_locked(shpool, cached_sess); - } - - if (sess_id) { - ngx_slab_free_locked(shpool, sess_id); - } - - ngx_shmtx_unlock(&shpool->mutex); - - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "could not allocate new session%s", shpool->log_ctx); - - return 0; -} - - -static ngx_ssl_session_t * -ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, -#if OPENSSL_VERSION_NUMBER >= 0x10100003L - const -#endif - u_char *id, int len, int *copy) -{ -#if OPENSSL_VERSION_NUMBER >= 0x0090707fL - const -#endif - u_char *p; - uint32_t hash; - ngx_int_t rc; - ngx_shm_zone_t *shm_zone; - ngx_slab_pool_t *shpool; - ngx_rbtree_node_t *node, *sentinel; - ngx_ssl_session_t *sess; - ngx_ssl_sess_id_t *sess_id; - ngx_ssl_session_cache_t *cache; - u_char buf[NGX_SSL_MAX_SESSION_SIZE]; - ngx_connection_t *c; - - hash = ngx_crc32_short((u_char *) (uintptr_t) id, (size_t) len); - *copy = 0; - - c = ngx_ssl_get_connection(ssl_conn); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl get session: %08XD:%d", hash, len); - - shm_zone = SSL_CTX_get_ex_data(c->ssl->session_ctx, - ngx_ssl_session_cache_index); - - cache = shm_zone->data; - - sess = NULL; - - shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - - ngx_shmtx_lock(&shpool->mutex); - - node = cache->session_rbtree.root; - sentinel = cache->session_rbtree.sentinel; - - while (node != sentinel) { - - if (hash < node->key) { - node = node->left; - continue; - } - - if (hash > node->key) { - node = node->right; - continue; - } - - /* hash == node->key */ - - sess_id = (ngx_ssl_sess_id_t *) node; - - rc = ngx_memn2cmp((u_char *) (uintptr_t) id, sess_id->id, - (size_t) len, (size_t) node->data); - - if (rc == 0) { - - if (sess_id->expire > ngx_time()) { - ngx_memcpy(buf, sess_id->session, sess_id->len); - - ngx_shmtx_unlock(&shpool->mutex); - - p = buf; - sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); - - return sess; - } - - ngx_queue_remove(&sess_id->queue); - - ngx_rbtree_delete(&cache->session_rbtree, node); - - ngx_slab_free_locked(shpool, sess_id->session); -#if (NGX_PTR_SIZE == 4) - ngx_slab_free_locked(shpool, sess_id->id); -#endif - ngx_slab_free_locked(shpool, sess_id); - - sess = NULL; - - goto done; - } - - node = (rc < 0) ? node->left : node->right; - } - -done: - - ngx_shmtx_unlock(&shpool->mutex); - - return sess; -} - - -void -ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) -{ - SSL_CTX_remove_session(ssl, sess); - - ngx_ssl_remove_session(ssl, sess); -} - - -static void -ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) -{ - u_char *id; - uint32_t hash; - ngx_int_t rc; - unsigned int len; - ngx_shm_zone_t *shm_zone; - ngx_slab_pool_t *shpool; - ngx_rbtree_node_t *node, *sentinel; - ngx_ssl_sess_id_t *sess_id; - ngx_ssl_session_cache_t *cache; - - shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index); - - if (shm_zone == NULL) { - return; - } - - cache = shm_zone->data; - -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL - - id = (u_char *) SSL_SESSION_get_id(sess, &len); - -#else - - id = sess->session_id; - len = sess->session_id_length; - -#endif - - hash = ngx_crc32_short(id, len); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, - "ssl remove session: %08XD:%ud", hash, len); - - shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - - ngx_shmtx_lock(&shpool->mutex); - - node = cache->session_rbtree.root; - sentinel = cache->session_rbtree.sentinel; - - while (node != sentinel) { - - if (hash < node->key) { - node = node->left; - continue; - } - - if (hash > node->key) { - node = node->right; - continue; - } - - /* hash == node->key */ - - sess_id = (ngx_ssl_sess_id_t *) node; - - rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data); - - if (rc == 0) { - - ngx_queue_remove(&sess_id->queue); - - ngx_rbtree_delete(&cache->session_rbtree, node); - - ngx_slab_free_locked(shpool, sess_id->session); -#if (NGX_PTR_SIZE == 4) - ngx_slab_free_locked(shpool, sess_id->id); -#endif - ngx_slab_free_locked(shpool, sess_id); - - goto done; - } - - node = (rc < 0) ? node->left : node->right; - } - -done: - - ngx_shmtx_unlock(&shpool->mutex); -} - - -static void -ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, - ngx_slab_pool_t *shpool, ngx_uint_t n) -{ - time_t now; - ngx_queue_t *q; - ngx_ssl_sess_id_t *sess_id; - - now = ngx_time(); - - while (n < 3) { - - if (ngx_queue_empty(&cache->expire_queue)) { - return; - } - - q = ngx_queue_last(&cache->expire_queue); - - sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue); - - if (n++ != 0 && sess_id->expire > now) { - return; - } - - ngx_queue_remove(q); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, - "expire session: %08Xi", sess_id->node.key); - - ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node); - - ngx_slab_free_locked(shpool, sess_id->session); -#if (NGX_PTR_SIZE == 4) - ngx_slab_free_locked(shpool, sess_id->id); -#endif - ngx_slab_free_locked(shpool, sess_id); - } -} - - -static void -ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp, - ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) -{ - ngx_rbtree_node_t **p; - ngx_ssl_sess_id_t *sess_id, *sess_id_temp; - - for ( ;; ) { - - if (node->key < temp->key) { - - p = &temp->left; - - } else if (node->key > temp->key) { - - p = &temp->right; - - } else { /* node->key == temp->key */ - - sess_id = (ngx_ssl_sess_id_t *) node; - sess_id_temp = (ngx_ssl_sess_id_t *) temp; - - p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id, - (size_t) node->data, (size_t) temp->data) - < 0) ? &temp->left : &temp->right; - } - - if (*p == sentinel) { - break; - } - - temp = *p; - } - - *p = node; - node->parent = temp; - node->left = sentinel; - node->right = sentinel; - ngx_rbt_red(node); -} - - -#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB - -ngx_int_t -ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths) -{ - u_char buf[80]; - size_t size; - ssize_t n; - ngx_str_t *path; - ngx_file_t file; - ngx_uint_t i; - ngx_array_t *keys; - ngx_file_info_t fi; - ngx_ssl_session_ticket_key_t *key; - - if (paths == NULL) { - return NGX_OK; - } - - keys = ngx_array_create(cf->pool, paths->nelts, - sizeof(ngx_ssl_session_ticket_key_t)); - if (keys == NULL) { - return NGX_ERROR; - } - - path = paths->elts; - for (i = 0; i < paths->nelts; i++) { - - if (ngx_conf_full_name(cf->cycle, &path[i], 1) != NGX_OK) { - return NGX_ERROR; - } - - ngx_memzero(&file, sizeof(ngx_file_t)); - file.name = path[i]; - file.log = cf->log; - - file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, 0, 0); - if (file.fd == NGX_INVALID_FILE) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, - ngx_open_file_n " \"%V\" failed", &file.name); - return NGX_ERROR; - } - - if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, - ngx_fd_info_n " \"%V\" failed", &file.name); - goto failed; - } - - size = ngx_file_size(&fi); - - if (size != 48 && size != 80) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" must be 48 or 80 bytes", &file.name); - goto failed; - } - - n = ngx_read_file(&file, buf, size, 0); - - if (n == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, - ngx_read_file_n " \"%V\" failed", &file.name); - goto failed; - } - - if ((size_t) n != size) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, 0, - ngx_read_file_n " \"%V\" returned only " - "%z bytes instead of %uz", &file.name, n, size); - goto failed; - } - - key = ngx_array_push(keys); - if (key == NULL) { - goto failed; - } - - if (size == 48) { - key->size = 48; - ngx_memcpy(key->name, buf, 16); - ngx_memcpy(key->aes_key, buf + 16, 16); - ngx_memcpy(key->hmac_key, buf + 32, 16); - - } else { - key->size = 80; - ngx_memcpy(key->name, buf, 16); - ngx_memcpy(key->hmac_key, buf + 16, 32); - ngx_memcpy(key->aes_key, buf + 48, 32); - } - - if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, - ngx_close_file_n " \"%V\" failed", &file.name); - } - } - - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_ticket_keys_index, keys) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_ex_data() failed"); - return NGX_ERROR; - } - - if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx, - ngx_ssl_session_ticket_key_callback) - == 0) - { - ngx_log_error(NGX_LOG_WARN, cf->log, 0, - "nginx was built with Session Tickets support, however, " - "now it is linked dynamically to an OpenSSL library " - "which has no tlsext support, therefore Session Tickets " - "are not available"); - } - - return NGX_OK; - -failed: - - if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, - ngx_close_file_n " \"%V\" failed", &file.name); - } - - return NGX_ERROR; -} - - -static int -ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, - unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, - HMAC_CTX *hctx, int enc) -{ - size_t size; - SSL_CTX *ssl_ctx; - ngx_uint_t i; - ngx_array_t *keys; - ngx_connection_t *c; - ngx_ssl_session_ticket_key_t *key; - const EVP_MD *digest; - const EVP_CIPHER *cipher; -#if (NGX_DEBUG) - u_char buf[32]; -#endif - - c = ngx_ssl_get_connection(ssl_conn); - ssl_ctx = c->ssl->session_ctx; - -#ifdef OPENSSL_NO_SHA256 - digest = EVP_sha1(); -#else - digest = EVP_sha256(); -#endif - - keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index); - if (keys == NULL) { - return -1; - } - - key = keys->elts; - - if (enc == 1) { - /* encrypt session ticket */ - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl session ticket encrypt, key: \"%*s\" (%s session)", - ngx_hex_dump(buf, key[0].name, 16) - buf, buf, - SSL_session_reused(ssl_conn) ? "reused" : "new"); - - if (key[0].size == 48) { - cipher = EVP_aes_128_cbc(); - size = 16; - - } else { - cipher = EVP_aes_256_cbc(); - size = 32; - } - - if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed"); - return -1; - } - - if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, - "EVP_EncryptInit_ex() failed"); - return -1; - } - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); - return -1; - } -#else - HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL); -#endif - - ngx_memcpy(name, key[0].name, 16); - - return 1; - - } else { - /* decrypt session ticket */ - - for (i = 0; i < keys->nelts; i++) { - if (ngx_memcmp(name, key[i].name, 16) == 0) { - goto found; - } - } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl session ticket decrypt, key: \"%*s\" not found", - ngx_hex_dump(buf, name, 16) - buf, buf); - - return 0; - - found: - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl session ticket decrypt, key: \"%*s\"%s", - ngx_hex_dump(buf, key[i].name, 16) - buf, buf, - (i == 0) ? " (default)" : ""); - - if (key[i].size == 48) { - cipher = EVP_aes_128_cbc(); - size = 16; - - } else { - cipher = EVP_aes_256_cbc(); - size = 32; - } - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); - return -1; - } -#else - HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL); -#endif - - if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, - "EVP_DecryptInit_ex() failed"); - return -1; - } - - return (i == 0) ? 1 : 2 /* renew */; - } -} - -#else - -ngx_int_t -ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths) -{ - if (paths) { - ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_session_ticket_keys\" ignored, not supported"); - } - - return NGX_OK; -} - -#endif - - -void -ngx_ssl_cleanup_ctx(void *data) -{ - ngx_ssl_t *ssl = data; - - X509 *cert, *next; - - cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); - - while (cert) { - next = X509_get_ex_data(cert, ngx_ssl_next_certificate_index); - X509_free(cert); - cert = next; - } - - SSL_CTX_free(ssl->ctx); -} - - -ngx_int_t -ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name) -{ - X509 *cert; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_ERROR; - } - -#ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT - - /* X509_check_host() is only available in OpenSSL 1.0.2+ */ - - if (name->len == 0) { - goto failed; - } - - if (X509_check_host(cert, (char *) name->data, name->len, 0, NULL) != 1) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "X509_check_host(): no match"); - goto failed; - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "X509_check_host(): match"); - - goto found; - -#else - { - int n, i; - X509_NAME *sname; - ASN1_STRING *str; - X509_NAME_ENTRY *entry; - GENERAL_NAME *altname; - STACK_OF(GENERAL_NAME) *altnames; - - /* - * As per RFC6125 and RFC2818, we check subjectAltName extension, - * and if it's not present - commonName in Subject is checked. - */ - - altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); - - if (altnames) { - n = sk_GENERAL_NAME_num(altnames); - - for (i = 0; i < n; i++) { - altname = sk_GENERAL_NAME_value(altnames, i); - - if (altname->type != GEN_DNS) { - continue; - } - - str = altname->d.dNSName; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL subjectAltName: \"%*s\"", - ASN1_STRING_length(str), ASN1_STRING_data(str)); - - if (ngx_ssl_check_name(name, str) == NGX_OK) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL subjectAltName: match"); - GENERAL_NAMES_free(altnames); - goto found; - } - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL subjectAltName: no match"); - - GENERAL_NAMES_free(altnames); - goto failed; - } - - /* - * If there is no subjectAltName extension, check commonName - * in Subject. While RFC2818 requires to only check "most specific" - * CN, both Apache and OpenSSL check all CNs, and so do we. - */ - - sname = X509_get_subject_name(cert); - - if (sname == NULL) { - goto failed; - } - - i = -1; - for ( ;; ) { - i = X509_NAME_get_index_by_NID(sname, NID_commonName, i); - - if (i < 0) { - break; - } - - entry = X509_NAME_get_entry(sname, i); - str = X509_NAME_ENTRY_get_data(entry); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL commonName: \"%*s\"", - ASN1_STRING_length(str), ASN1_STRING_data(str)); - - if (ngx_ssl_check_name(name, str) == NGX_OK) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL commonName: match"); - goto found; - } - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL commonName: no match"); - } -#endif - -failed: - - X509_free(cert); - return NGX_ERROR; - -found: - - X509_free(cert); - return NGX_OK; -} - - -#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT - -static ngx_int_t -ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern) -{ - u_char *s, *p, *end; - size_t slen, plen; - - s = name->data; - slen = name->len; - - p = ASN1_STRING_data(pattern); - plen = ASN1_STRING_length(pattern); - - if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) { - return NGX_OK; - } - - if (plen > 2 && p[0] == '*' && p[1] == '.') { - plen -= 1; - p += 1; - - end = s + slen; - s = ngx_strlchr(s, end, '.'); - - if (s == NULL) { - return NGX_ERROR; - } - - slen = end - s; - - if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) { - return NGX_OK; - } - } - - return NGX_ERROR; -} - -#endif - - -ngx_int_t -ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - s->data = (u_char *) SSL_get_version(c->ssl->connection); - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection); - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ -#ifdef SSL_CTRL_GET_RAW_CIPHERLIST - - int n, i, bytes; - size_t len; - u_char *ciphers, *p; - const SSL_CIPHER *cipher; - - bytes = SSL_get0_raw_cipherlist(c->ssl->connection, NULL); - n = SSL_get0_raw_cipherlist(c->ssl->connection, &ciphers); - - if (n <= 0) { - s->len = 0; - return NGX_OK; - } - - len = 0; - n /= bytes; - - for (i = 0; i < n; i++) { - cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); - - if (cipher) { - len += ngx_strlen(SSL_CIPHER_get_name(cipher)); - - } else { - len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1); - } - - len += sizeof(":") - 1; - } - - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - return NGX_ERROR; - } - - p = s->data; - - for (i = 0; i < n; i++) { - cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); - - if (cipher) { - p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher)); - - } else { - p = ngx_sprintf(p, "0x"); - p = ngx_hex_dump(p, ciphers + i * bytes, bytes); - } - - *p++ = ':'; - } - - p--; - - s->len = p - s->data; - -#else - - u_char buf[4096]; - - if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096) - == NULL) - { - s->len = 0; - return NGX_OK; - } - - s->len = ngx_strlen(buf); - s->data = ngx_pnalloc(pool, s->len); - if (s->data == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(s->data, buf, s->len); - -#endif - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ -#ifdef SSL_CTRL_GET_CURVES - - int *curves, n, i, nid; - u_char *p; - size_t len; - - n = SSL_get1_curves(c->ssl->connection, NULL); - - if (n <= 0) { - s->len = 0; - return NGX_OK; - } - - curves = ngx_palloc(pool, n * sizeof(int)); - - n = SSL_get1_curves(c->ssl->connection, curves); - len = 0; - - for (i = 0; i < n; i++) { - nid = curves[i]; - - if (nid & TLSEXT_nid_unknown) { - len += sizeof("0x0000") - 1; - - } else { - len += ngx_strlen(OBJ_nid2sn(nid)); - } - - len += sizeof(":") - 1; - } - - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - return NGX_ERROR; - } - - p = s->data; - - for (i = 0; i < n; i++) { - nid = curves[i]; - - if (nid & TLSEXT_nid_unknown) { - p = ngx_sprintf(p, "0x%04xd", nid & 0xffff); - - } else { - p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid)); - } - - *p++ = ':'; - } - - p--; - - s->len = p - s->data; - -#else - - s->len = 0; - -#endif - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - u_char *buf; - SSL_SESSION *sess; - unsigned int len; - - sess = SSL_get0_session(c->ssl->connection); - if (sess == NULL) { - s->len = 0; - return NGX_OK; - } - -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL - - buf = (u_char *) SSL_SESSION_get_id(sess, &len); - -#else - - buf = sess->session_id; - len = sess->session_id_length; - -#endif - - s->len = 2 * len; - s->data = ngx_pnalloc(pool, 2 * len); - if (s->data == NULL) { - return NGX_ERROR; - } - - ngx_hex_dump(s->data, buf, len); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - if (SSL_session_reused(c->ssl->connection)) { - ngx_str_set(s, "r"); - - } else { - ngx_str_set(s, "."); - } - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - - const char *servername; - - servername = SSL_get_servername(c->ssl->connection, - TLSEXT_NAMETYPE_host_name); - if (servername) { - s->data = (u_char *) servername; - s->len = ngx_strlen(servername); - return NGX_OK; - } - -#endif - - s->len = 0; - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - size_t len; - BIO *bio; - X509 *cert; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed"); - X509_free(cert); - return NGX_ERROR; - } - - if (PEM_write_bio_X509(bio, cert) == 0) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed"); - goto failed; - } - - len = BIO_pending(bio); - s->len = len; - - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - goto failed; - } - - BIO_read(bio, s->data, len); - - BIO_free(bio); - X509_free(cert); - - return NGX_OK; - -failed: - - BIO_free(bio); - X509_free(cert); - - return NGX_ERROR; -} - - -ngx_int_t -ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - u_char *p; - size_t len; - ngx_uint_t i; - ngx_str_t cert; - - if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) { - return NGX_ERROR; - } - - if (cert.len == 0) { - s->len = 0; - return NGX_OK; - } - - len = cert.len - 1; - - for (i = 0; i < cert.len - 1; i++) { - if (cert.data[i] == LF) { - len++; - } - } - - s->len = len; - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - return NGX_ERROR; - } - - p = s->data; - - for (i = 0; i < cert.len - 1; i++) { - *p++ = cert.data[i]; - if (cert.data[i] == LF) { - *p++ = '\t'; - } - } - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - BIO *bio; - X509 *cert; - X509_NAME *name; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - name = X509_get_subject_name(cert); - if (name == NULL) { - return NGX_ERROR; - } - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - X509_free(cert); - return NGX_ERROR; - } - - if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) { - goto failed; - } - - s->len = BIO_pending(bio); - s->data = ngx_pnalloc(pool, s->len); - if (s->data == NULL) { - goto failed; - } - - BIO_read(bio, s->data, s->len); - - BIO_free(bio); - X509_free(cert); - - return NGX_OK; - -failed: - - BIO_free(bio); - X509_free(cert); - - return NGX_ERROR; -} - - -ngx_int_t -ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - BIO *bio; - X509 *cert; - X509_NAME *name; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - name = X509_get_issuer_name(cert); - if (name == NULL) { - return NGX_ERROR; - } - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - X509_free(cert); - return NGX_ERROR; - } - - if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) { - goto failed; - } - - s->len = BIO_pending(bio); - s->data = ngx_pnalloc(pool, s->len); - if (s->data == NULL) { - goto failed; - } - - BIO_read(bio, s->data, s->len); - - BIO_free(bio); - X509_free(cert); - - return NGX_OK; - -failed: - - BIO_free(bio); - X509_free(cert); - - return NGX_ERROR; -} - - -ngx_int_t -ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s) -{ - char *p; - size_t len; - X509 *cert; - X509_NAME *name; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - name = X509_get_subject_name(cert); - if (name == NULL) { - X509_free(cert); - return NGX_ERROR; - } - - p = X509_NAME_oneline(name, NULL, 0); - - for (len = 0; p[len]; len++) { /* void */ } - - s->len = len; - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - OPENSSL_free(p); - X509_free(cert); - return NGX_ERROR; - } - - ngx_memcpy(s->data, p, len); - - OPENSSL_free(p); - X509_free(cert); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s) -{ - char *p; - size_t len; - X509 *cert; - X509_NAME *name; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - name = X509_get_issuer_name(cert); - if (name == NULL) { - X509_free(cert); - return NGX_ERROR; - } - - p = X509_NAME_oneline(name, NULL, 0); - - for (len = 0; p[len]; len++) { /* void */ } - - s->len = len; - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - OPENSSL_free(p); - X509_free(cert); - return NGX_ERROR; - } - - ngx_memcpy(s->data, p, len); - - OPENSSL_free(p); - X509_free(cert); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - size_t len; - X509 *cert; - BIO *bio; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - X509_free(cert); - return NGX_ERROR; - } - - i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert)); - len = BIO_pending(bio); - - s->len = len; - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - BIO_free(bio); - X509_free(cert); - return NGX_ERROR; - } - - BIO_read(bio, s->data, len); - BIO_free(bio); - X509_free(cert); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - X509 *cert; - unsigned int len; - u_char buf[EVP_MAX_MD_SIZE]; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - if (!X509_digest(cert, EVP_sha1(), buf, &len)) { - X509_free(cert); - return NGX_ERROR; - } - - s->len = 2 * len; - s->data = ngx_pnalloc(pool, 2 * len); - if (s->data == NULL) { - X509_free(cert); - return NGX_ERROR; - } - - ngx_hex_dump(s->data, buf, len); - - X509_free(cert); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - X509 *cert; - long rc; - const char *str; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - ngx_str_set(s, "NONE"); - return NGX_OK; - } - - X509_free(cert); - - rc = SSL_get_verify_result(c->ssl->connection); - - if (rc == X509_V_OK) { - ngx_str_set(s, "SUCCESS"); - return NGX_OK; - } - - str = X509_verify_cert_error_string(rc); - - s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str)); - if (s->data == NULL) { - return NGX_ERROR; - } - - s->len = ngx_sprintf(s->data, "FAILED:%s", str) - s->data; - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - BIO *bio; - X509 *cert; - size_t len; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - X509_free(cert); - return NGX_ERROR; - } - -#if OPENSSL_VERSION_NUMBER > 0x10100000L - ASN1_TIME_print(bio, X509_get0_notBefore(cert)); -#else - ASN1_TIME_print(bio, X509_get_notBefore(cert)); -#endif - - len = BIO_pending(bio); - - s->len = len; - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - BIO_free(bio); - X509_free(cert); - return NGX_ERROR; - } - - BIO_read(bio, s->data, len); - BIO_free(bio); - X509_free(cert); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - BIO *bio; - X509 *cert; - size_t len; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - X509_free(cert); - return NGX_ERROR; - } - -#if OPENSSL_VERSION_NUMBER > 0x10100000L - ASN1_TIME_print(bio, X509_get0_notAfter(cert)); -#else - ASN1_TIME_print(bio, X509_get_notAfter(cert)); -#endif - - len = BIO_pending(bio); - - s->len = len; - s->data = ngx_pnalloc(pool, len); - if (s->data == NULL) { - BIO_free(bio); - X509_free(cert); - return NGX_ERROR; - } - - BIO_read(bio, s->data, len); - BIO_free(bio); - X509_free(cert); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) -{ - X509 *cert; - time_t now, end; - - s->len = 0; - - cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - return NGX_OK; - } - -#if OPENSSL_VERSION_NUMBER > 0x10100000L - end = ngx_ssl_parse_time(X509_get0_notAfter(cert)); -#else - end = ngx_ssl_parse_time(X509_get_notAfter(cert)); -#endif - - if (end == (time_t) NGX_ERROR) { - X509_free(cert); - return NGX_OK; - } - - now = ngx_time(); - - if (end < now + 86400) { - ngx_str_set(s, "0"); - X509_free(cert); - return NGX_OK; - } - - s->data = ngx_pnalloc(pool, NGX_TIME_T_LEN); - if (s->data == NULL) { - X509_free(cert); - return NGX_ERROR; - } - - s->len = ngx_sprintf(s->data, "%T", (end - now) / 86400) - s->data; - - X509_free(cert); - - return NGX_OK; -} - - -static time_t -ngx_ssl_parse_time( -#if OPENSSL_VERSION_NUMBER > 0x10100000L - const -#endif - ASN1_TIME *asn1time) -{ - BIO *bio; - char *value; - size_t len; - time_t time; - - /* - * OpenSSL doesn't provide a way to convert ASN1_TIME - * into time_t. To do this, we use ASN1_TIME_print(), - * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g., - * "Feb 3 00:55:52 2015 GMT"), and parse the result. - */ - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - return NGX_ERROR; - } - - /* fake weekday prepended to match C asctime() format */ - - BIO_write(bio, "Tue ", sizeof("Tue ") - 1); - ASN1_TIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, &value); - - time = ngx_parse_http_time((u_char *) value, len); - - BIO_free(bio); - - return time; -} - - -static void * -ngx_openssl_create_conf(ngx_cycle_t *cycle) -{ - ngx_openssl_conf_t *oscf; - - oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t)); - if (oscf == NULL) { - return NULL; - } - - /* - * set by ngx_pcalloc(): - * - * oscf->engine = 0; - */ - - return oscf; -} - - -static char * -ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ -#ifndef OPENSSL_NO_ENGINE - - ngx_openssl_conf_t *oscf = conf; - - ENGINE *engine; - ngx_str_t *value; - - if (oscf->engine) { - return "is duplicate"; - } - - oscf->engine = 1; - - value = cf->args->elts; - - engine = ENGINE_by_id((char *) value[1].data); - - if (engine == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "ENGINE_by_id(\"%V\") failed", &value[1]); - return NGX_CONF_ERROR; - } - - if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed", - &value[1]); - - ENGINE_free(engine); - - return NGX_CONF_ERROR; - } - - ENGINE_free(engine); - - return NGX_CONF_OK; - -#else - - return "is not supported"; - -#endif -} - - -static void -ngx_openssl_exit(ngx_cycle_t *cycle) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100003L - - EVP_cleanup(); -#ifndef OPENSSL_NO_ENGINE - ENGINE_cleanup(); -#endif - -#endif -} diff --git a/app/nginx/src/event/ngx_event_openssl.h b/app/nginx/src/event/ngx_event_openssl.h deleted file mode 100644 index e093e10..0000000 --- a/app/nginx/src/event/ngx_event_openssl.h +++ /dev/null @@ -1,254 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_EVENT_OPENSSL_H_INCLUDED_ -#define _NGX_EVENT_OPENSSL_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> - -#include <openssl/ssl.h> -#include <openssl/err.h> -#include <openssl/bn.h> -#include <openssl/conf.h> -#include <openssl/crypto.h> -#include <openssl/dh.h> -#ifndef OPENSSL_NO_ENGINE -#include <openssl/engine.h> -#endif -#include <openssl/evp.h> -#ifndef OPENSSL_NO_OCSP -#include <openssl/ocsp.h> -#endif -#include <openssl/rand.h> -#include <openssl/rsa.h> -#include <openssl/x509.h> -#include <openssl/x509v3.h> - -#define NGX_SSL_NAME "OpenSSL" - - -#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) -#undef OPENSSL_VERSION_NUMBER -#define OPENSSL_VERSION_NUMBER 0x1000107fL -#endif - - -#if (OPENSSL_VERSION_NUMBER >= 0x10100001L) - -#define ngx_ssl_version() OpenSSL_version(OPENSSL_VERSION) - -#else - -#define ngx_ssl_version() SSLeay_version(SSLEAY_VERSION) - -#endif - - -#define ngx_ssl_session_t SSL_SESSION -#define ngx_ssl_conn_t SSL - - -struct ngx_ssl_s { - SSL_CTX *ctx; - ngx_log_t *log; - size_t buffer_size; -}; - - -struct ngx_ssl_connection_s { - ngx_ssl_conn_t *connection; - SSL_CTX *session_ctx; - - ngx_int_t last; - ngx_buf_t *buf; - size_t buffer_size; - - ngx_connection_handler_pt handler; - - ngx_event_handler_pt saved_read_handler; - ngx_event_handler_pt saved_write_handler; - - unsigned handshaked:1; - unsigned renegotiation:1; - unsigned buffer:1; - unsigned no_wait_shutdown:1; - unsigned no_send_shutdown:1; - unsigned handshake_buffer_set:1; -}; - - -#define NGX_SSL_NO_SCACHE -2 -#define NGX_SSL_NONE_SCACHE -3 -#define NGX_SSL_NO_BUILTIN_SCACHE -4 -#define NGX_SSL_DFLT_BUILTIN_SCACHE -5 - - -#define NGX_SSL_MAX_SESSION_SIZE 4096 - -typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t; - -struct ngx_ssl_sess_id_s { - ngx_rbtree_node_t node; - u_char *id; - size_t len; - u_char *session; - ngx_queue_t queue; - time_t expire; -#if (NGX_PTR_SIZE == 8) - void *stub; - u_char sess_id[32]; -#endif -}; - - -typedef struct { - ngx_rbtree_t session_rbtree; - ngx_rbtree_node_t sentinel; - ngx_queue_t expire_queue; -} ngx_ssl_session_cache_t; - - -#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB - -typedef struct { - size_t size; - u_char name[16]; - u_char hmac_key[32]; - u_char aes_key[32]; -} ngx_ssl_session_ticket_key_t; - -#endif - - -#define NGX_SSL_SSLv2 0x0002 -#define NGX_SSL_SSLv3 0x0004 -#define NGX_SSL_TLSv1 0x0008 -#define NGX_SSL_TLSv1_1 0x0010 -#define NGX_SSL_TLSv1_2 0x0020 - - -#define NGX_SSL_BUFFER 1 -#define NGX_SSL_CLIENT 2 - -#define NGX_SSL_BUFSIZE 16384 - - -ngx_int_t ngx_ssl_init(ngx_log_t *log); -ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); -ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); -ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); -ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, - ngx_uint_t prefer_server_ciphers); -ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *cert, ngx_int_t depth); -ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *cert, ngx_int_t depth); -ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); -ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); -ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_resolver_t *resolver, ngx_msec_t resolver_timeout); -RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export, - int key_length); -ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file); -ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file); -ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name); -ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, - ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout); -ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_array_t *paths); -ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data); -ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, - ngx_uint_t flags); - -void ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); -ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session); -#define ngx_ssl_get_session(c) SSL_get1_session(c->ssl->connection) -#define ngx_ssl_free_session SSL_SESSION_free -#define ngx_ssl_get_connection(ssl_conn) \ - SSL_get_ex_data(ssl_conn, ngx_ssl_connection_index) -#define ngx_ssl_get_server_conf(ssl_ctx) \ - SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_server_conf_index) - -#define ngx_ssl_verify_error_optional(n) \ - (n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT \ - || n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN \ - || n == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY \ - || n == X509_V_ERR_CERT_UNTRUSTED \ - || n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) - -ngx_int_t ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name); - - -ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); -ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, - ngx_str_t *s); - - -ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); -ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size); -ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size); -ssize_t ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl, off_t limit); -ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, - off_t limit); -void ngx_ssl_free_buffer(ngx_connection_t *c); -ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c); -void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, - char *fmt, ...); -void ngx_ssl_cleanup_ctx(void *data); - - -extern int ngx_ssl_connection_index; -extern int ngx_ssl_server_conf_index; -extern int ngx_ssl_session_cache_index; -extern int ngx_ssl_session_ticket_keys_index; -extern int ngx_ssl_certificate_index; -extern int ngx_ssl_next_certificate_index; -extern int ngx_ssl_certificate_name_index; -extern int ngx_ssl_stapling_index; - - -#endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */ diff --git a/app/nginx/src/event/ngx_event_openssl_stapling.c b/app/nginx/src/event/ngx_event_openssl_stapling.c deleted file mode 100644 index d332c11..0000000 --- a/app/nginx/src/event/ngx_event_openssl_stapling.c +++ /dev/null @@ -1,1892 +0,0 @@ - -/* - * Copyright (C) Maxim Dounin - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> -#include <ngx_event_connect.h> - - -#if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) - - -typedef struct { - ngx_str_t staple; - ngx_msec_t timeout; - - ngx_resolver_t *resolver; - ngx_msec_t resolver_timeout; - - ngx_addr_t *addrs; - ngx_str_t host; - ngx_str_t uri; - in_port_t port; - - SSL_CTX *ssl_ctx; - - X509 *cert; - X509 *issuer; - - u_char *name; - - time_t valid; - time_t refresh; - - unsigned verify:1; - unsigned loading:1; -} ngx_ssl_stapling_t; - - -typedef struct ngx_ssl_ocsp_ctx_s ngx_ssl_ocsp_ctx_t; - -struct ngx_ssl_ocsp_ctx_s { - X509 *cert; - X509 *issuer; - - u_char *name; - - ngx_uint_t naddrs; - - ngx_addr_t *addrs; - ngx_str_t host; - ngx_str_t uri; - in_port_t port; - - ngx_resolver_t *resolver; - ngx_msec_t resolver_timeout; - - ngx_msec_t timeout; - - void (*handler)(ngx_ssl_ocsp_ctx_t *ctx); - void *data; - - ngx_buf_t *request; - ngx_buf_t *response; - ngx_peer_connection_t peer; - - ngx_int_t (*process)(ngx_ssl_ocsp_ctx_t *ctx); - - ngx_uint_t state; - - ngx_uint_t code; - ngx_uint_t count; - - ngx_uint_t done; - - u_char *header_name_start; - u_char *header_name_end; - u_char *header_start; - u_char *header_end; - - ngx_pool_t *pool; - ngx_log_t *log; -}; - - -static ngx_int_t ngx_ssl_stapling_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, - X509 *cert, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); -static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_ssl_stapling_t *staple, ngx_str_t *file); -static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_ssl_stapling_t *staple); -static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_ssl_stapling_t *staple, ngx_str_t *responder); - -static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, - void *data); -static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple); -static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx); - -static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time); - -static void ngx_ssl_stapling_cleanup(void *data); - -static ngx_ssl_ocsp_ctx_t *ngx_ssl_ocsp_start(void); -static void ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx); -static void ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx); -static void ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve); -static void ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx); -static void ngx_ssl_ocsp_write_handler(ngx_event_t *wev); -static void ngx_ssl_ocsp_read_handler(ngx_event_t *rev); -static void ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev); - -static ngx_int_t ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx); -static ngx_int_t ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx); -static ngx_int_t ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx); -static ngx_int_t ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx); -static ngx_int_t ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx); -static ngx_int_t ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx); - -static u_char *ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len); - - -ngx_int_t -ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, - ngx_str_t *responder, ngx_uint_t verify) -{ - X509 *cert; - - for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); - cert; - cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index)) - { - if (ngx_ssl_stapling_certificate(cf, ssl, cert, file, responder, verify) - != NGX_OK) - { - return NGX_ERROR; - } - } - - SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback); - - return NGX_OK; -} - - -static ngx_int_t -ngx_ssl_stapling_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, X509 *cert, - ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify) -{ - ngx_int_t rc; - ngx_pool_cleanup_t *cln; - ngx_ssl_stapling_t *staple; - - staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t)); - if (staple == NULL) { - return NGX_ERROR; - } - - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NGX_ERROR; - } - - cln->handler = ngx_ssl_stapling_cleanup; - cln->data = staple; - - if (X509_set_ex_data(cert, ngx_ssl_stapling_index, staple) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_set_ex_data() failed"); - return NGX_ERROR; - } - - staple->ssl_ctx = ssl->ctx; - staple->timeout = 60000; - staple->verify = verify; - staple->cert = cert; - staple->name = X509_get_ex_data(staple->cert, - ngx_ssl_certificate_name_index); - - if (file->len) { - /* use OCSP response from the file */ - - if (ngx_ssl_stapling_file(cf, ssl, staple, file) != NGX_OK) { - return NGX_ERROR; - } - - return NGX_OK; - } - - rc = ngx_ssl_stapling_issuer(cf, ssl, staple); - - if (rc == NGX_DECLINED) { - return NGX_OK; - } - - if (rc != NGX_OK) { - return NGX_ERROR; - } - - rc = ngx_ssl_stapling_responder(cf, ssl, staple, responder); - - if (rc == NGX_DECLINED) { - return NGX_OK; - } - - if (rc != NGX_OK) { - return NGX_ERROR; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_ssl_stapling_t *staple, ngx_str_t *file) -{ - BIO *bio; - int len; - u_char *p, *buf; - OCSP_RESPONSE *response; - - if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) { - return NGX_ERROR; - } - - bio = BIO_new_file((char *) file->data, "r"); - if (bio == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "BIO_new_file(\"%s\") failed", file->data); - return NGX_ERROR; - } - - response = d2i_OCSP_RESPONSE_bio(bio, NULL); - if (response == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "d2i_OCSP_RESPONSE_bio(\"%s\") failed", file->data); - BIO_free(bio); - return NGX_ERROR; - } - - len = i2d_OCSP_RESPONSE(response, NULL); - if (len <= 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "i2d_OCSP_RESPONSE(\"%s\") failed", file->data); - goto failed; - } - - buf = ngx_alloc(len, ssl->log); - if (buf == NULL) { - goto failed; - } - - p = buf; - len = i2d_OCSP_RESPONSE(response, &p); - if (len <= 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "i2d_OCSP_RESPONSE(\"%s\") failed", file->data); - ngx_free(buf); - goto failed; - } - - OCSP_RESPONSE_free(response); - BIO_free(bio); - - staple->staple.data = buf; - staple->staple.len = len; - staple->valid = NGX_MAX_TIME_T_VALUE; - - return NGX_OK; - -failed: - - OCSP_RESPONSE_free(response); - BIO_free(bio); - - return NGX_ERROR; -} - - -static ngx_int_t -ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_ssl_stapling_t *staple) -{ - int i, n, rc; - X509 *cert, *issuer; - X509_STORE *store; - X509_STORE_CTX *store_ctx; - STACK_OF(X509) *chain; - - cert = staple->cert; - -#ifdef SSL_CTRL_SELECT_CURRENT_CERT - /* OpenSSL 1.0.2+ */ - SSL_CTX_select_current_cert(ssl->ctx, cert); -#endif - -#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS - /* OpenSSL 1.0.1+ */ - SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain); -#else - chain = ssl->ctx->extra_certs; -#endif - - n = sk_X509_num(chain); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, - "SSL get issuer: %d extra certs", n); - - for (i = 0; i < n; i++) { - issuer = sk_X509_value(chain, i); - if (X509_check_issued(issuer, cert) == X509_V_OK) { -#if OPENSSL_VERSION_NUMBER >= 0x10100001L - X509_up_ref(issuer); -#else - CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509); -#endif - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, - "SSL get issuer: found %p in extra certs", issuer); - - staple->issuer = issuer; - - return NGX_OK; - } - } - - store = SSL_CTX_get_cert_store(ssl->ctx); - if (store == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_get_cert_store() failed"); - return NGX_ERROR; - } - - store_ctx = X509_STORE_CTX_new(); - if (store_ctx == NULL) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_STORE_CTX_new() failed"); - return NGX_ERROR; - } - - if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_STORE_CTX_init() failed"); - X509_STORE_CTX_free(store_ctx); - return NGX_ERROR; - } - - rc = X509_STORE_CTX_get1_issuer(&issuer, store_ctx, cert); - - if (rc == -1) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_STORE_CTX_get1_issuer() failed"); - X509_STORE_CTX_free(store_ctx); - return NGX_ERROR; - } - - if (rc == 0) { - ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_stapling\" ignored, " - "issuer certificate not found for certificate \"%s\"", - staple->name); - X509_STORE_CTX_free(store_ctx); - return NGX_DECLINED; - } - - X509_STORE_CTX_free(store_ctx); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, - "SSL get issuer: found %p in cert store", issuer); - - staple->issuer = issuer; - - return NGX_OK; -} - - -static ngx_int_t -ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_ssl_stapling_t *staple, ngx_str_t *responder) -{ - char *s; - ngx_str_t rsp; - ngx_url_t u; - STACK_OF(OPENSSL_STRING) *aia; - - if (responder->len == 0) { - - /* extract OCSP responder URL from certificate */ - - aia = X509_get1_ocsp(staple->cert); - if (aia == NULL) { - ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_stapling\" ignored, " - "no OCSP responder URL in the certificate \"%s\"", - staple->name); - return NGX_DECLINED; - } - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - s = sk_OPENSSL_STRING_value(aia, 0); -#else - s = sk_value(aia, 0); -#endif - if (s == NULL) { - ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_stapling\" ignored, " - "no OCSP responder URL in the certificate \"%s\"", - staple->name); - X509_email_free(aia); - return NGX_DECLINED; - } - - responder = &rsp; - - responder->len = ngx_strlen(s); - responder->data = ngx_palloc(cf->pool, responder->len); - if (responder->data == NULL) { - X509_email_free(aia); - return NGX_ERROR; - } - - ngx_memcpy(responder->data, s, responder->len); - X509_email_free(aia); - } - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = *responder; - u.default_port = 80; - u.uri_part = 1; - - if (u.url.len > 7 - && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0) - { - u.url.len -= 7; - u.url.data += 7; - - } else { - ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_stapling\" ignored, " - "invalid URL prefix in OCSP responder \"%V\" " - "in the certificate \"%s\"", - &u.url, staple->name); - return NGX_DECLINED; - } - - if (ngx_parse_url(cf->pool, &u) != NGX_OK) { - if (u.err) { - ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_stapling\" ignored, " - "%s in OCSP responder \"%V\" " - "in the certificate \"%s\"", - u.err, &u.url, staple->name); - return NGX_DECLINED; - } - - return NGX_ERROR; - } - - staple->addrs = u.addrs; - staple->host = u.host; - staple->uri = u.uri; - staple->port = u.port; - - if (staple->uri.len == 0) { - ngx_str_set(&staple->uri, "/"); - } - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_resolver_t *resolver, ngx_msec_t resolver_timeout) -{ - X509 *cert; - ngx_ssl_stapling_t *staple; - - for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); - cert; - cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index)) - { - staple = X509_get_ex_data(cert, ngx_ssl_stapling_index); - staple->resolver = resolver; - staple->resolver_timeout = resolver_timeout; - } - - return NGX_OK; -} - - -static int -ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data) -{ - int rc; - X509 *cert; - u_char *p; - ngx_connection_t *c; - ngx_ssl_stapling_t *staple; - - c = ngx_ssl_get_connection(ssl_conn); - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL certificate status callback"); - - rc = SSL_TLSEXT_ERR_NOACK; - - cert = SSL_get_certificate(ssl_conn); - staple = X509_get_ex_data(cert, ngx_ssl_stapling_index); - - if (staple == NULL) { - return rc; - } - - if (staple->staple.len - && staple->valid >= ngx_time()) - { - /* we have to copy ocsp response as OpenSSL will free it by itself */ - - p = OPENSSL_malloc(staple->staple.len); - if (p == NULL) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "OPENSSL_malloc() failed"); - return SSL_TLSEXT_ERR_NOACK; - } - - ngx_memcpy(p, staple->staple.data, staple->staple.len); - - SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, staple->staple.len); - - rc = SSL_TLSEXT_ERR_OK; - } - - ngx_ssl_stapling_update(staple); - - return rc; -} - - -static void -ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple) -{ - ngx_ssl_ocsp_ctx_t *ctx; - - if (staple->host.len == 0 - || staple->loading || staple->refresh >= ngx_time()) - { - return; - } - - staple->loading = 1; - - ctx = ngx_ssl_ocsp_start(); - if (ctx == NULL) { - return; - } - - ctx->cert = staple->cert; - ctx->issuer = staple->issuer; - ctx->name = staple->name; - - ctx->addrs = staple->addrs; - ctx->host = staple->host; - ctx->uri = staple->uri; - ctx->port = staple->port; - ctx->timeout = staple->timeout; - - ctx->resolver = staple->resolver; - ctx->resolver_timeout = staple->resolver_timeout; - - ctx->handler = ngx_ssl_stapling_ocsp_handler; - ctx->data = staple; - - ngx_ssl_ocsp_request(ctx); - - return; -} - - -static void -ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx) -{ -#if OPENSSL_VERSION_NUMBER >= 0x0090707fL - const -#endif - u_char *p; - int n; - size_t len; - time_t now, valid; - ngx_str_t response; - X509_STORE *store; - STACK_OF(X509) *chain; - OCSP_CERTID *id; - OCSP_RESPONSE *ocsp; - OCSP_BASICRESP *basic; - ngx_ssl_stapling_t *staple; - ASN1_GENERALIZEDTIME *thisupdate, *nextupdate; - - staple = ctx->data; - now = ngx_time(); - ocsp = NULL; - basic = NULL; - id = NULL; - - if (ctx->code != 200) { - goto error; - } - - /* check the response */ - - len = ctx->response->last - ctx->response->pos; - p = ctx->response->pos; - - ocsp = d2i_OCSP_RESPONSE(NULL, &p, len); - if (ocsp == NULL) { - ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, - "d2i_OCSP_RESPONSE() failed"); - goto error; - } - - n = OCSP_response_status(ocsp); - - if (n != OCSP_RESPONSE_STATUS_SUCCESSFUL) { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP response not successful (%d: %s)", - n, OCSP_response_status_str(n)); - goto error; - } - - basic = OCSP_response_get1_basic(ocsp); - if (basic == NULL) { - ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP_response_get1_basic() failed"); - goto error; - } - - store = SSL_CTX_get_cert_store(staple->ssl_ctx); - if (store == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "SSL_CTX_get_cert_store() failed"); - goto error; - } - -#ifdef SSL_CTRL_SELECT_CURRENT_CERT - /* OpenSSL 1.0.2+ */ - SSL_CTX_select_current_cert(staple->ssl_ctx, ctx->cert); -#endif - -#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS - /* OpenSSL 1.0.1+ */ - SSL_CTX_get_extra_chain_certs(staple->ssl_ctx, &chain); -#else - chain = staple->ssl_ctx->extra_certs; -#endif - - if (OCSP_basic_verify(basic, chain, store, - staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY) - != 1) - { - ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP_basic_verify() failed"); - goto error; - } - - id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer); - if (id == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_cert_to_id() failed"); - goto error; - } - - if (OCSP_resp_find_status(basic, id, &n, NULL, NULL, - &thisupdate, &nextupdate) - != 1) - { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "certificate status not found in the OCSP response"); - goto error; - } - - if (n != V_OCSP_CERTSTATUS_GOOD) { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "certificate status \"%s\" in the OCSP response", - OCSP_cert_status_str(n)); - goto error; - } - - if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) { - ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP_check_validity() failed"); - goto error; - } - - if (nextupdate) { - valid = ngx_ssl_stapling_time(nextupdate); - if (valid == (time_t) NGX_ERROR) { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "invalid nextUpdate time in certificate status"); - goto error; - } - - } else { - valid = NGX_MAX_TIME_T_VALUE; - } - - OCSP_CERTID_free(id); - OCSP_BASICRESP_free(basic); - OCSP_RESPONSE_free(ocsp); - - id = NULL; - basic = NULL; - ocsp = NULL; - - /* copy the response to memory not in ctx->pool */ - - response.len = len; - response.data = ngx_alloc(response.len, ctx->log); - - if (response.data == NULL) { - goto error; - } - - ngx_memcpy(response.data, ctx->response->pos, response.len); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp response, %s, %uz", - OCSP_cert_status_str(n), response.len); - - if (staple->staple.data) { - ngx_free(staple->staple.data); - } - - staple->staple = response; - staple->valid = valid; - - /* - * refresh before the response expires, - * but not earlier than in 5 minutes, and at least in an hour - */ - - staple->loading = 0; - staple->refresh = ngx_max(ngx_min(valid - 300, now + 3600), now + 300); - - ngx_ssl_ocsp_done(ctx); - return; - -error: - - staple->loading = 0; - staple->refresh = now + 300; - - if (id) { - OCSP_CERTID_free(id); - } - - if (basic) { - OCSP_BASICRESP_free(basic); - } - - if (ocsp) { - OCSP_RESPONSE_free(ocsp); - } - - ngx_ssl_ocsp_done(ctx); -} - - -static time_t -ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time) -{ - BIO *bio; - char *value; - size_t len; - time_t time; - - /* - * OpenSSL doesn't provide a way to convert ASN1_GENERALIZEDTIME - * into time_t. To do this, we use ASN1_GENERALIZEDTIME_print(), - * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g., - * "Feb 3 00:55:52 2015 GMT"), and parse the result. - */ - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - return NGX_ERROR; - } - - /* fake weekday prepended to match C asctime() format */ - - BIO_write(bio, "Tue ", sizeof("Tue ") - 1); - ASN1_GENERALIZEDTIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, &value); - - time = ngx_parse_http_time((u_char *) value, len); - - BIO_free(bio); - - return time; -} - - -static void -ngx_ssl_stapling_cleanup(void *data) -{ - ngx_ssl_stapling_t *staple = data; - - if (staple->issuer) { - X509_free(staple->issuer); - } - - if (staple->staple.data) { - ngx_free(staple->staple.data); - } -} - - -static ngx_ssl_ocsp_ctx_t * -ngx_ssl_ocsp_start(void) -{ - ngx_log_t *log; - ngx_pool_t *pool; - ngx_ssl_ocsp_ctx_t *ctx; - - pool = ngx_create_pool(2048, ngx_cycle->log); - if (pool == NULL) { - return NULL; - } - - ctx = ngx_pcalloc(pool, sizeof(ngx_ssl_ocsp_ctx_t)); - if (ctx == NULL) { - ngx_destroy_pool(pool); - return NULL; - } - - log = ngx_palloc(pool, sizeof(ngx_log_t)); - if (log == NULL) { - ngx_destroy_pool(pool); - return NULL; - } - - ctx->pool = pool; - - *log = *ctx->pool->log; - - ctx->pool->log = log; - ctx->log = log; - - log->handler = ngx_ssl_ocsp_log_error; - log->data = ctx; - log->action = "requesting certificate status"; - - return ctx; -} - - -static void -ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx) -{ - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp done"); - - if (ctx->peer.connection) { - ngx_close_connection(ctx->peer.connection); - } - - ngx_destroy_pool(ctx->pool); -} - - -static void -ngx_ssl_ocsp_error(ngx_ssl_ocsp_ctx_t *ctx) -{ - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp error"); - - ctx->code = 0; - ctx->handler(ctx); -} - - -static void -ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx) -{ - ngx_resolver_ctx_t *resolve, temp; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp request"); - - if (ngx_ssl_ocsp_create_request(ctx) != NGX_OK) { - ngx_ssl_ocsp_error(ctx); - return; - } - - if (ctx->resolver) { - /* resolve OCSP responder hostname */ - - temp.name = ctx->host; - - resolve = ngx_resolve_start(ctx->resolver, &temp); - if (resolve == NULL) { - ngx_ssl_ocsp_error(ctx); - return; - } - - if (resolve == NGX_NO_RESOLVER) { - ngx_log_error(NGX_LOG_WARN, ctx->log, 0, - "no resolver defined to resolve %V", &ctx->host); - goto connect; - } - - resolve->name = ctx->host; - resolve->handler = ngx_ssl_ocsp_resolve_handler; - resolve->data = ctx; - resolve->timeout = ctx->resolver_timeout; - - if (ngx_resolve_name(resolve) != NGX_OK) { - ngx_ssl_ocsp_error(ctx); - return; - } - - return; - } - -connect: - - ngx_ssl_ocsp_connect(ctx); -} - - -static void -ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve) -{ - ngx_ssl_ocsp_ctx_t *ctx = resolve->data; - - u_char *p; - size_t len; - socklen_t socklen; - ngx_uint_t i; - struct sockaddr *sockaddr; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp resolve handler"); - - if (resolve->state) { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "%V could not be resolved (%i: %s)", - &resolve->name, resolve->state, - ngx_resolver_strerror(resolve->state)); - goto failed; - } - -#if (NGX_DEBUG) - { - u_char text[NGX_SOCKADDR_STRLEN]; - ngx_str_t addr; - - addr.data = text; - - for (i = 0; i < resolve->naddrs; i++) { - addr.len = ngx_sock_ntop(resolve->addrs[i].sockaddr, - resolve->addrs[i].socklen, - text, NGX_SOCKADDR_STRLEN, 0); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "name was resolved to %V", &addr); - - } - } -#endif - - ctx->naddrs = resolve->naddrs; - ctx->addrs = ngx_pcalloc(ctx->pool, ctx->naddrs * sizeof(ngx_addr_t)); - - if (ctx->addrs == NULL) { - goto failed; - } - - for (i = 0; i < resolve->naddrs; i++) { - - socklen = resolve->addrs[i].socklen; - - sockaddr = ngx_palloc(ctx->pool, socklen); - if (sockaddr == NULL) { - goto failed; - } - - ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen); - ngx_inet_set_port(sockaddr, ctx->port); - - ctx->addrs[i].sockaddr = sockaddr; - ctx->addrs[i].socklen = socklen; - - p = ngx_pnalloc(ctx->pool, NGX_SOCKADDR_STRLEN); - if (p == NULL) { - goto failed; - } - - len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); - - ctx->addrs[i].name.len = len; - ctx->addrs[i].name.data = p; - } - - ngx_resolve_name_done(resolve); - - ngx_ssl_ocsp_connect(ctx); - return; - -failed: - - ngx_resolve_name_done(resolve); - ngx_ssl_ocsp_error(ctx); -} - - -static void -ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx) -{ - ngx_int_t rc; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp connect"); - - /* TODO: use all ip addresses */ - - ctx->peer.sockaddr = ctx->addrs[0].sockaddr; - ctx->peer.socklen = ctx->addrs[0].socklen; - ctx->peer.name = &ctx->addrs[0].name; - ctx->peer.get = ngx_event_get_peer; - ctx->peer.log = ctx->log; - ctx->peer.log_error = NGX_ERROR_ERR; - - rc = ngx_event_connect_peer(&ctx->peer); - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp connect peer done"); - - if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) { - ngx_ssl_ocsp_error(ctx); - return; - } - - ctx->peer.connection->data = ctx; - ctx->peer.connection->pool = ctx->pool; - - ctx->peer.connection->read->handler = ngx_ssl_ocsp_read_handler; - ctx->peer.connection->write->handler = ngx_ssl_ocsp_write_handler; - - ctx->process = ngx_ssl_ocsp_process_status_line; - - ngx_add_timer(ctx->peer.connection->read, ctx->timeout); - ngx_add_timer(ctx->peer.connection->write, ctx->timeout); - - if (rc == NGX_OK) { - ngx_ssl_ocsp_write_handler(ctx->peer.connection->write); - return; - } -} - - -static void -ngx_ssl_ocsp_write_handler(ngx_event_t *wev) -{ - ssize_t n, size; - ngx_connection_t *c; - ngx_ssl_ocsp_ctx_t *ctx; - - c = wev->data; - ctx = c->data; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, wev->log, 0, - "ssl ocsp write handler"); - - if (wev->timedout) { - ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT, - "OCSP responder timed out"); - ngx_ssl_ocsp_error(ctx); - return; - } - - size = ctx->request->last - ctx->request->pos; - - n = ngx_send(c, ctx->request->pos, size); - - if (n == NGX_ERROR) { - ngx_ssl_ocsp_error(ctx); - return; - } - - if (n > 0) { - ctx->request->pos += n; - - if (n == size) { - wev->handler = ngx_ssl_ocsp_dummy_handler; - - if (wev->timer_set) { - ngx_del_timer(wev); - } - - if (ngx_handle_write_event(wev, 0) != NGX_OK) { - ngx_ssl_ocsp_error(ctx); - } - - return; - } - } - - if (!wev->timer_set) { - ngx_add_timer(wev, ctx->timeout); - } -} - - -static void -ngx_ssl_ocsp_read_handler(ngx_event_t *rev) -{ - ssize_t n, size; - ngx_int_t rc; - ngx_connection_t *c; - ngx_ssl_ocsp_ctx_t *ctx; - - c = rev->data; - ctx = c->data; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0, - "ssl ocsp read handler"); - - if (rev->timedout) { - ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, - "OCSP responder timed out"); - ngx_ssl_ocsp_error(ctx); - return; - } - - if (ctx->response == NULL) { - ctx->response = ngx_create_temp_buf(ctx->pool, 16384); - if (ctx->response == NULL) { - ngx_ssl_ocsp_error(ctx); - return; - } - } - - for ( ;; ) { - - size = ctx->response->end - ctx->response->last; - - n = ngx_recv(c, ctx->response->last, size); - - if (n > 0) { - ctx->response->last += n; - - rc = ctx->process(ctx); - - if (rc == NGX_ERROR) { - ngx_ssl_ocsp_error(ctx); - return; - } - - continue; - } - - if (n == NGX_AGAIN) { - - if (ngx_handle_read_event(rev, 0) != NGX_OK) { - ngx_ssl_ocsp_error(ctx); - } - - return; - } - - break; - } - - ctx->done = 1; - - rc = ctx->process(ctx); - - if (rc == NGX_DONE) { - /* ctx->handler() was called */ - return; - } - - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP responder prematurely closed connection"); - - ngx_ssl_ocsp_error(ctx); -} - - -static void -ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev) -{ - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "ssl ocsp dummy handler"); -} - - -static ngx_int_t -ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx) -{ - int len; - u_char *p; - uintptr_t escape; - ngx_str_t binary, base64; - ngx_buf_t *b; - OCSP_CERTID *id; - OCSP_REQUEST *ocsp; - - ocsp = OCSP_REQUEST_new(); - if (ocsp == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_REQUEST_new() failed"); - return NGX_ERROR; - } - - id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer); - if (id == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_cert_to_id() failed"); - goto failed; - } - - if (OCSP_request_add0_id(ocsp, id) == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_request_add0_id() failed"); - OCSP_CERTID_free(id); - goto failed; - } - - len = i2d_OCSP_REQUEST(ocsp, NULL); - if (len <= 0) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "i2d_OCSP_REQUEST() failed"); - goto failed; - } - - binary.len = len; - binary.data = ngx_palloc(ctx->pool, len); - if (binary.data == NULL) { - goto failed; - } - - p = binary.data; - len = i2d_OCSP_REQUEST(ocsp, &p); - if (len <= 0) { - ngx_ssl_error(NGX_LOG_EMERG, ctx->log, 0, - "i2d_OCSP_REQUEST() failed"); - goto failed; - } - - base64.len = ngx_base64_encoded_length(binary.len); - base64.data = ngx_palloc(ctx->pool, base64.len); - if (base64.data == NULL) { - goto failed; - } - - ngx_encode_base64(&base64, &binary); - - escape = ngx_escape_uri(NULL, base64.data, base64.len, - NGX_ESCAPE_URI_COMPONENT); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp request length %z, escape %d", - base64.len, (int) escape); - - len = sizeof("GET ") - 1 + ctx->uri.len + sizeof("/") - 1 - + base64.len + 2 * escape + sizeof(" HTTP/1.0" CRLF) - 1 - + sizeof("Host: ") - 1 + ctx->host.len + sizeof(CRLF) - 1 - + sizeof(CRLF) - 1; - - b = ngx_create_temp_buf(ctx->pool, len); - if (b == NULL) { - goto failed; - } - - p = b->last; - - p = ngx_cpymem(p, "GET ", sizeof("GET ") - 1); - p = ngx_cpymem(p, ctx->uri.data, ctx->uri.len); - - if (ctx->uri.data[ctx->uri.len - 1] != '/') { - *p++ = '/'; - } - - if (escape == 0) { - p = ngx_cpymem(p, base64.data, base64.len); - - } else { - p = (u_char *) ngx_escape_uri(p, base64.data, base64.len, - NGX_ESCAPE_URI_COMPONENT); - } - - p = ngx_cpymem(p, " HTTP/1.0" CRLF, sizeof(" HTTP/1.0" CRLF) - 1); - p = ngx_cpymem(p, "Host: ", sizeof("Host: ") - 1); - p = ngx_cpymem(p, ctx->host.data, ctx->host.len); - *p++ = CR; *p++ = LF; - - /* add "\r\n" at the header end */ - *p++ = CR; *p++ = LF; - - b->last = p; - ctx->request = b; - - OCSP_REQUEST_free(ocsp); - - return NGX_OK; - -failed: - - OCSP_REQUEST_free(ocsp); - - return NGX_ERROR; -} - - -static ngx_int_t -ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx) -{ - ngx_int_t rc; - - rc = ngx_ssl_ocsp_parse_status_line(ctx); - - if (rc == NGX_OK) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp status %ui \"%*s\"", - ctx->code, - ctx->header_end - ctx->header_start, - ctx->header_start); - - ctx->process = ngx_ssl_ocsp_process_headers; - return ctx->process(ctx); - } - - if (rc == NGX_AGAIN) { - return NGX_AGAIN; - } - - /* rc == NGX_ERROR */ - - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP responder sent invalid response"); - - return NGX_ERROR; -} - - -static ngx_int_t -ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx) -{ - u_char ch; - u_char *p; - ngx_buf_t *b; - enum { - sw_start = 0, - sw_H, - sw_HT, - sw_HTT, - sw_HTTP, - sw_first_major_digit, - sw_major_digit, - sw_first_minor_digit, - sw_minor_digit, - sw_status, - sw_space_after_status, - sw_status_text, - sw_almost_done - } state; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp process status line"); - - state = ctx->state; - b = ctx->response; - - for (p = b->pos; p < b->last; p++) { - ch = *p; - - switch (state) { - - /* "HTTP/" */ - case sw_start: - switch (ch) { - case 'H': - state = sw_H; - break; - default: - return NGX_ERROR; - } - break; - - case sw_H: - switch (ch) { - case 'T': - state = sw_HT; - break; - default: - return NGX_ERROR; - } - break; - - case sw_HT: - switch (ch) { - case 'T': - state = sw_HTT; - break; - default: - return NGX_ERROR; - } - break; - - case sw_HTT: - switch (ch) { - case 'P': - state = sw_HTTP; - break; - default: - return NGX_ERROR; - } - break; - - case sw_HTTP: - switch (ch) { - case '/': - state = sw_first_major_digit; - break; - default: - return NGX_ERROR; - } - break; - - /* the first digit of major HTTP version */ - case sw_first_major_digit: - if (ch < '1' || ch > '9') { - return NGX_ERROR; - } - - state = sw_major_digit; - break; - - /* the major HTTP version or dot */ - case sw_major_digit: - if (ch == '.') { - state = sw_first_minor_digit; - break; - } - - if (ch < '0' || ch > '9') { - return NGX_ERROR; - } - - break; - - /* the first digit of minor HTTP version */ - case sw_first_minor_digit: - if (ch < '0' || ch > '9') { - return NGX_ERROR; - } - - state = sw_minor_digit; - break; - - /* the minor HTTP version or the end of the request line */ - case sw_minor_digit: - if (ch == ' ') { - state = sw_status; - break; - } - - if (ch < '0' || ch > '9') { - return NGX_ERROR; - } - - break; - - /* HTTP status code */ - case sw_status: - if (ch == ' ') { - break; - } - - if (ch < '0' || ch > '9') { - return NGX_ERROR; - } - - ctx->code = ctx->code * 10 + ch - '0'; - - if (++ctx->count == 3) { - state = sw_space_after_status; - ctx->header_start = p - 2; - } - - break; - - /* space or end of line */ - case sw_space_after_status: - switch (ch) { - case ' ': - state = sw_status_text; - break; - case '.': /* IIS may send 403.1, 403.2, etc */ - state = sw_status_text; - break; - case CR: - state = sw_almost_done; - break; - case LF: - ctx->header_end = p; - goto done; - default: - return NGX_ERROR; - } - break; - - /* any text until end of line */ - case sw_status_text: - switch (ch) { - case CR: - state = sw_almost_done; - break; - case LF: - ctx->header_end = p; - goto done; - } - break; - - /* end of status line */ - case sw_almost_done: - switch (ch) { - case LF: - ctx->header_end = p - 1; - goto done; - default: - return NGX_ERROR; - } - } - } - - b->pos = p; - ctx->state = state; - - return NGX_AGAIN; - -done: - - b->pos = p + 1; - ctx->state = sw_start; - - return NGX_OK; -} - - -static ngx_int_t -ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx) -{ - size_t len; - ngx_int_t rc; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp process headers"); - - for ( ;; ) { - rc = ngx_ssl_ocsp_parse_header_line(ctx); - - if (rc == NGX_OK) { - - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp header \"%*s: %*s\"", - ctx->header_name_end - ctx->header_name_start, - ctx->header_name_start, - ctx->header_end - ctx->header_start, - ctx->header_start); - - len = ctx->header_name_end - ctx->header_name_start; - - if (len == sizeof("Content-Type") - 1 - && ngx_strncasecmp(ctx->header_name_start, - (u_char *) "Content-Type", - sizeof("Content-Type") - 1) - == 0) - { - len = ctx->header_end - ctx->header_start; - - if (len != sizeof("application/ocsp-response") - 1 - || ngx_strncasecmp(ctx->header_start, - (u_char *) "application/ocsp-response", - sizeof("application/ocsp-response") - 1) - != 0) - { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP responder sent invalid " - "\"Content-Type\" header: \"%*s\"", - ctx->header_end - ctx->header_start, - ctx->header_start); - return NGX_ERROR; - } - - continue; - } - - /* TODO: honor Content-Length */ - - continue; - } - - if (rc == NGX_DONE) { - break; - } - - if (rc == NGX_AGAIN) { - return NGX_AGAIN; - } - - /* rc == NGX_ERROR */ - - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP responder sent invalid response"); - - return NGX_ERROR; - } - - ctx->process = ngx_ssl_ocsp_process_body; - return ctx->process(ctx); -} - - -static ngx_int_t -ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx) -{ - u_char c, ch, *p; - enum { - sw_start = 0, - sw_name, - sw_space_before_value, - sw_value, - sw_space_after_value, - sw_almost_done, - sw_header_almost_done - } state; - - state = ctx->state; - - for (p = ctx->response->pos; p < ctx->response->last; p++) { - ch = *p; - -#if 0 - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "s:%d in:'%02Xd:%c'", state, ch, ch); -#endif - - switch (state) { - - /* first char */ - case sw_start: - - switch (ch) { - case CR: - ctx->header_end = p; - state = sw_header_almost_done; - break; - case LF: - ctx->header_end = p; - goto header_done; - default: - state = sw_name; - ctx->header_name_start = p; - - c = (u_char) (ch | 0x20); - if (c >= 'a' && c <= 'z') { - break; - } - - if (ch >= '0' && ch <= '9') { - break; - } - - return NGX_ERROR; - } - break; - - /* header name */ - case sw_name: - c = (u_char) (ch | 0x20); - if (c >= 'a' && c <= 'z') { - break; - } - - if (ch == ':') { - ctx->header_name_end = p; - state = sw_space_before_value; - break; - } - - if (ch == '-') { - break; - } - - if (ch >= '0' && ch <= '9') { - break; - } - - if (ch == CR) { - ctx->header_name_end = p; - ctx->header_start = p; - ctx->header_end = p; - state = sw_almost_done; - break; - } - - if (ch == LF) { - ctx->header_name_end = p; - ctx->header_start = p; - ctx->header_end = p; - goto done; - } - - return NGX_ERROR; - - /* space* before header value */ - case sw_space_before_value: - switch (ch) { - case ' ': - break; - case CR: - ctx->header_start = p; - ctx->header_end = p; - state = sw_almost_done; - break; - case LF: - ctx->header_start = p; - ctx->header_end = p; - goto done; - default: - ctx->header_start = p; - state = sw_value; - break; - } - break; - - /* header value */ - case sw_value: - switch (ch) { - case ' ': - ctx->header_end = p; - state = sw_space_after_value; - break; - case CR: - ctx->header_end = p; - state = sw_almost_done; - break; - case LF: - ctx->header_end = p; - goto done; - } - break; - - /* space* before end of header line */ - case sw_space_after_value: - switch (ch) { - case ' ': - break; - case CR: - state = sw_almost_done; - break; - case LF: - goto done; - default: - state = sw_value; - break; - } - break; - - /* end of header line */ - case sw_almost_done: - switch (ch) { - case LF: - goto done; - default: - return NGX_ERROR; - } - - /* end of header */ - case sw_header_almost_done: - switch (ch) { - case LF: - goto header_done; - default: - return NGX_ERROR; - } - } - } - - ctx->response->pos = p; - ctx->state = state; - - return NGX_AGAIN; - -done: - - ctx->response->pos = p + 1; - ctx->state = sw_start; - - return NGX_OK; - -header_done: - - ctx->response->pos = p + 1; - ctx->state = sw_start; - - return NGX_DONE; -} - - -static ngx_int_t -ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx) -{ - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp process body"); - - if (ctx->done) { - ctx->handler(ctx); - return NGX_DONE; - } - - return NGX_AGAIN; -} - - -static u_char * -ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len) -{ - u_char *p; - ngx_ssl_ocsp_ctx_t *ctx; - - p = buf; - - if (log->action) { - p = ngx_snprintf(buf, len, " while %s", log->action); - len -= p - buf; - buf = p; - } - - ctx = log->data; - - if (ctx) { - p = ngx_snprintf(buf, len, ", responder: %V", &ctx->host); - len -= p - buf; - buf = p; - } - - if (ctx && ctx->peer.name) { - p = ngx_snprintf(buf, len, ", peer: %V", ctx->peer.name); - len -= p - buf; - buf = p; - } - - if (ctx && ctx->name) { - p = ngx_snprintf(buf, len, ", certificate: \"%s\"", ctx->name); - len -= p - buf; - buf = p; - } - - return p; -} - - -#else - - -ngx_int_t -ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, - ngx_str_t *responder, ngx_uint_t verify) -{ - ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_stapling\" ignored, not supported"); - - return NGX_OK; -} - - -ngx_int_t -ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_resolver_t *resolver, ngx_msec_t resolver_timeout) -{ - return NGX_OK; -} - - -#endif diff --git a/app/nginx/src/event/ngx_event_pipe.c b/app/nginx/src/event/ngx_event_pipe.c deleted file mode 100644 index da7c4ee..0000000 --- a/app/nginx/src/event/ngx_event_pipe.c +++ /dev/null @@ -1,1110 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> -#include <ngx_event_pipe.h> - - -static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p); -static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p); - -static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p); -static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf); -static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p); - - -ngx_int_t -ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write) -{ - ngx_int_t rc; - ngx_uint_t flags; - ngx_event_t *rev, *wev; - - for ( ;; ) { - if (do_write) { - p->log->action = "sending to client"; - - rc = ngx_event_pipe_write_to_downstream(p); - - if (rc == NGX_ABORT) { - return NGX_ABORT; - } - - if (rc == NGX_BUSY) { - return NGX_OK; - } - } - - p->read = 0; - p->upstream_blocked = 0; - - p->log->action = "reading upstream"; - - if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) { - return NGX_ABORT; - } - - if (!p->read && !p->upstream_blocked) { - break; - } - - do_write = 1; - } - - if (p->upstream->fd != (ngx_socket_t) -1) { - rev = p->upstream->read; - - flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0; - - if (ngx_handle_read_event(rev, flags) != NGX_OK) { - return NGX_ABORT; - } - - if (!rev->delayed) { - if (rev->active && !rev->ready) { - ngx_add_timer(rev, p->read_timeout); - - } else if (rev->timer_set) { - ngx_del_timer(rev); - } - } - } - - if (p->downstream->fd != (ngx_socket_t) -1 - && p->downstream->data == p->output_ctx) - { - wev = p->downstream->write; - if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) { - return NGX_ABORT; - } - - if (!wev->delayed) { - if (wev->active && !wev->ready) { - ngx_add_timer(wev, p->send_timeout); - - } else if (wev->timer_set) { - ngx_del_timer(wev); - } - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_event_pipe_read_upstream(ngx_event_pipe_t *p) -{ - off_t limit; - ssize_t n, size; - ngx_int_t rc; - ngx_buf_t *b; - ngx_msec_t delay; - ngx_chain_t *chain, *cl, *ln; - - if (p->upstream_eof || p->upstream_error || p->upstream_done) { - return NGX_OK; - } - -#if (NGX_THREADS) - - if (p->aio) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe read upstream: aio"); - return NGX_AGAIN; - } - - if (p->writing) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe read upstream: writing"); - - rc = ngx_event_pipe_write_chain_to_temp_file(p); - - if (rc != NGX_OK) { - return rc; - } - } - -#endif - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe read upstream: %d", p->upstream->read->ready); - - for ( ;; ) { - - if (p->upstream_eof || p->upstream_error || p->upstream_done) { - break; - } - - if (p->preread_bufs == NULL && !p->upstream->read->ready) { - break; - } - - if (p->preread_bufs) { - - /* use the pre-read bufs if they exist */ - - chain = p->preread_bufs; - p->preread_bufs = NULL; - n = p->preread_size; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe preread: %z", n); - - if (n) { - p->read = 1; - } - - } else { - -#if (NGX_HAVE_KQUEUE) - - /* - * kqueue notifies about the end of file or a pending error. - * This test allows not to allocate a buf on these conditions - * and not to call c->recv_chain(). - */ - - if (p->upstream->read->available == 0 - && p->upstream->read->pending_eof) - { - p->upstream->read->ready = 0; - p->upstream->read->eof = 1; - p->upstream_eof = 1; - p->read = 1; - - if (p->upstream->read->kq_errno) { - p->upstream->read->error = 1; - p->upstream_error = 1; - p->upstream_eof = 0; - - ngx_log_error(NGX_LOG_ERR, p->log, - p->upstream->read->kq_errno, - "kevent() reported that upstream " - "closed connection"); - } - - break; - } -#endif - - if (p->limit_rate) { - if (p->upstream->read->delayed) { - break; - } - - limit = (off_t) p->limit_rate * (ngx_time() - p->start_sec + 1) - - p->read_length; - - if (limit <= 0) { - p->upstream->read->delayed = 1; - delay = (ngx_msec_t) (- limit * 1000 / p->limit_rate + 1); - ngx_add_timer(p->upstream->read, delay); - break; - } - - } else { - limit = 0; - } - - if (p->free_raw_bufs) { - - /* use the free bufs if they exist */ - - chain = p->free_raw_bufs; - if (p->single_buf) { - p->free_raw_bufs = p->free_raw_bufs->next; - chain->next = NULL; - } else { - p->free_raw_bufs = NULL; - } - - } else if (p->allocated < p->bufs.num) { - - /* allocate a new buf if it's still allowed */ - - b = ngx_create_temp_buf(p->pool, p->bufs.size); - if (b == NULL) { - return NGX_ABORT; - } - - p->allocated++; - - chain = ngx_alloc_chain_link(p->pool); - if (chain == NULL) { - return NGX_ABORT; - } - - chain->buf = b; - chain->next = NULL; - - } else if (!p->cacheable - && p->downstream->data == p->output_ctx - && p->downstream->write->ready - && !p->downstream->write->delayed) - { - /* - * if the bufs are not needed to be saved in a cache and - * a downstream is ready then write the bufs to a downstream - */ - - p->upstream_blocked = 1; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe downstream ready"); - - break; - - } else if (p->cacheable - || p->temp_file->offset < p->max_temp_file_size) - { - - /* - * if it is allowed, then save some bufs from p->in - * to a temporary file, and add them to a p->out chain - */ - - rc = ngx_event_pipe_write_chain_to_temp_file(p); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe temp offset: %O", p->temp_file->offset); - - if (rc == NGX_BUSY) { - break; - } - - if (rc != NGX_OK) { - return rc; - } - - chain = p->free_raw_bufs; - if (p->single_buf) { - p->free_raw_bufs = p->free_raw_bufs->next; - chain->next = NULL; - } else { - p->free_raw_bufs = NULL; - } - - } else { - - /* there are no bufs to read in */ - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "no pipe bufs to read in"); - - break; - } - - n = p->upstream->recv_chain(p->upstream, chain, limit); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe recv chain: %z", n); - - if (p->free_raw_bufs) { - chain->next = p->free_raw_bufs; - } - p->free_raw_bufs = chain; - - if (n == NGX_ERROR) { - p->upstream_error = 1; - break; - } - - if (n == NGX_AGAIN) { - if (p->single_buf) { - ngx_event_pipe_remove_shadow_links(chain->buf); - } - - break; - } - - p->read = 1; - - if (n == 0) { - p->upstream_eof = 1; - break; - } - } - - delay = p->limit_rate ? (ngx_msec_t) n * 1000 / p->limit_rate : 0; - - p->read_length += n; - cl = chain; - p->free_raw_bufs = NULL; - - while (cl && n > 0) { - - ngx_event_pipe_remove_shadow_links(cl->buf); - - size = cl->buf->end - cl->buf->last; - - if (n >= size) { - cl->buf->last = cl->buf->end; - - /* STUB */ cl->buf->num = p->num++; - - if (p->input_filter(p, cl->buf) == NGX_ERROR) { - return NGX_ABORT; - } - - n -= size; - ln = cl; - cl = cl->next; - ngx_free_chain(p->pool, ln); - - } else { - cl->buf->last += n; - n = 0; - } - } - - if (cl) { - for (ln = cl; ln->next; ln = ln->next) { /* void */ } - - ln->next = p->free_raw_bufs; - p->free_raw_bufs = cl; - } - - if (delay > 0) { - p->upstream->read->delayed = 1; - ngx_add_timer(p->upstream->read, delay); - break; - } - } - -#if (NGX_DEBUG) - - for (cl = p->busy; cl; cl = cl->next) { - ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf busy s:%d t:%d f:%d " - "%p, pos %p, size: %z " - "file: %O, size: %O", - (cl->buf->shadow ? 1 : 0), - cl->buf->temporary, cl->buf->in_file, - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos, - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - } - - for (cl = p->out; cl; cl = cl->next) { - ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf out s:%d t:%d f:%d " - "%p, pos %p, size: %z " - "file: %O, size: %O", - (cl->buf->shadow ? 1 : 0), - cl->buf->temporary, cl->buf->in_file, - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos, - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - } - - for (cl = p->in; cl; cl = cl->next) { - ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf in s:%d t:%d f:%d " - "%p, pos %p, size: %z " - "file: %O, size: %O", - (cl->buf->shadow ? 1 : 0), - cl->buf->temporary, cl->buf->in_file, - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos, - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - } - - for (cl = p->free_raw_bufs; cl; cl = cl->next) { - ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf free s:%d t:%d f:%d " - "%p, pos %p, size: %z " - "file: %O, size: %O", - (cl->buf->shadow ? 1 : 0), - cl->buf->temporary, cl->buf->in_file, - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos, - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe length: %O", p->length); - -#endif - - if (p->free_raw_bufs && p->length != -1) { - cl = p->free_raw_bufs; - - if (cl->buf->last - cl->buf->pos >= p->length) { - - p->free_raw_bufs = cl->next; - - /* STUB */ cl->buf->num = p->num++; - - if (p->input_filter(p, cl->buf) == NGX_ERROR) { - return NGX_ABORT; - } - - ngx_free_chain(p->pool, cl); - } - } - - if (p->length == 0) { - p->upstream_done = 1; - p->read = 1; - } - - if ((p->upstream_eof || p->upstream_error) && p->free_raw_bufs) { - - /* STUB */ p->free_raw_bufs->buf->num = p->num++; - - if (p->input_filter(p, p->free_raw_bufs->buf) == NGX_ERROR) { - return NGX_ABORT; - } - - p->free_raw_bufs = p->free_raw_bufs->next; - - if (p->free_bufs && p->buf_to_file == NULL) { - for (cl = p->free_raw_bufs; cl; cl = cl->next) { - if (cl->buf->shadow == NULL) { - ngx_pfree(p->pool, cl->buf->start); - } - } - } - } - - if (p->cacheable && (p->in || p->buf_to_file)) { - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write chain"); - - rc = ngx_event_pipe_write_chain_to_temp_file(p); - - if (rc != NGX_OK) { - return rc; - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p) -{ - u_char *prev; - size_t bsize; - ngx_int_t rc; - ngx_uint_t flush, flushed, prev_last_shadow; - ngx_chain_t *out, **ll, *cl; - ngx_connection_t *downstream; - - downstream = p->downstream; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write downstream: %d", downstream->write->ready); - -#if (NGX_THREADS) - - if (p->writing) { - rc = ngx_event_pipe_write_chain_to_temp_file(p); - - if (rc == NGX_ABORT) { - return NGX_ABORT; - } - } - -#endif - - flushed = 0; - - for ( ;; ) { - if (p->downstream_error) { - return ngx_event_pipe_drain_chains(p); - } - - if (p->upstream_eof || p->upstream_error || p->upstream_done) { - - /* pass the p->out and p->in chains to the output filter */ - - for (cl = p->busy; cl; cl = cl->next) { - cl->buf->recycled = 0; - } - - if (p->out) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write downstream flush out"); - - for (cl = p->out; cl; cl = cl->next) { - cl->buf->recycled = 0; - } - - rc = p->output_filter(p->output_ctx, p->out); - - if (rc == NGX_ERROR) { - p->downstream_error = 1; - return ngx_event_pipe_drain_chains(p); - } - - p->out = NULL; - } - - if (p->writing) { - break; - } - - if (p->in) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write downstream flush in"); - - for (cl = p->in; cl; cl = cl->next) { - cl->buf->recycled = 0; - } - - rc = p->output_filter(p->output_ctx, p->in); - - if (rc == NGX_ERROR) { - p->downstream_error = 1; - return ngx_event_pipe_drain_chains(p); - } - - p->in = NULL; - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write downstream done"); - - /* TODO: free unused bufs */ - - p->downstream_done = 1; - break; - } - - if (downstream->data != p->output_ctx - || !downstream->write->ready - || downstream->write->delayed) - { - break; - } - - /* bsize is the size of the busy recycled bufs */ - - prev = NULL; - bsize = 0; - - for (cl = p->busy; cl; cl = cl->next) { - - if (cl->buf->recycled) { - if (prev == cl->buf->start) { - continue; - } - - bsize += cl->buf->end - cl->buf->start; - prev = cl->buf->start; - } - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write busy: %uz", bsize); - - out = NULL; - - if (bsize >= (size_t) p->busy_size) { - flush = 1; - goto flush; - } - - flush = 0; - ll = NULL; - prev_last_shadow = 1; - - for ( ;; ) { - if (p->out) { - cl = p->out; - - if (cl->buf->recycled) { - ngx_log_error(NGX_LOG_ALERT, p->log, 0, - "recycled buffer in pipe out chain"); - } - - p->out = p->out->next; - - } else if (!p->cacheable && !p->writing && p->in) { - cl = p->in; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write buf ls:%d %p %z", - cl->buf->last_shadow, - cl->buf->pos, - cl->buf->last - cl->buf->pos); - - if (cl->buf->recycled && prev_last_shadow) { - if (bsize + cl->buf->end - cl->buf->start > p->busy_size) { - flush = 1; - break; - } - - bsize += cl->buf->end - cl->buf->start; - } - - prev_last_shadow = cl->buf->last_shadow; - - p->in = p->in->next; - - } else { - break; - } - - cl->next = NULL; - - if (out) { - *ll = cl; - } else { - out = cl; - } - ll = &cl->next; - } - - flush: - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write: out:%p, f:%ui", out, flush); - - if (out == NULL) { - - if (!flush) { - break; - } - - /* a workaround for AIO */ - if (flushed++ > 10) { - return NGX_BUSY; - } - } - - rc = p->output_filter(p->output_ctx, out); - - ngx_chain_update_chains(p->pool, &p->free, &p->busy, &out, p->tag); - - if (rc == NGX_ERROR) { - p->downstream_error = 1; - return ngx_event_pipe_drain_chains(p); - } - - for (cl = p->free; cl; cl = cl->next) { - - if (cl->buf->temp_file) { - if (p->cacheable || !p->cyclic_temp_file) { - continue; - } - - /* reset p->temp_offset if all bufs had been sent */ - - if (cl->buf->file_last == p->temp_file->offset) { - p->temp_file->offset = 0; - } - } - - /* TODO: free buf if p->free_bufs && upstream done */ - - /* add the free shadow raw buf to p->free_raw_bufs */ - - if (cl->buf->last_shadow) { - if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) { - return NGX_ABORT; - } - - cl->buf->last_shadow = 0; - } - - cl->buf->shadow = NULL; - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p) -{ - ssize_t size, bsize, n; - ngx_buf_t *b; - ngx_uint_t prev_last_shadow; - ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free; - -#if (NGX_THREADS) - - if (p->writing) { - - if (p->aio) { - return NGX_AGAIN; - } - - out = p->writing; - p->writing = NULL; - - n = ngx_write_chain_to_temp_file(p->temp_file, NULL); - - if (n == NGX_ERROR) { - return NGX_ABORT; - } - - goto done; - } - -#endif - - if (p->buf_to_file) { - out = ngx_alloc_chain_link(p->pool); - if (out == NULL) { - return NGX_ABORT; - } - - out->buf = p->buf_to_file; - out->next = p->in; - - } else { - out = p->in; - } - - if (!p->cacheable) { - - size = 0; - cl = out; - ll = NULL; - prev_last_shadow = 1; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe offset: %O", p->temp_file->offset); - - do { - bsize = cl->buf->last - cl->buf->pos; - - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf ls:%d %p, pos %p, size: %z", - cl->buf->last_shadow, cl->buf->start, - cl->buf->pos, bsize); - - if (prev_last_shadow - && ((size + bsize > p->temp_file_write_size) - || (p->temp_file->offset + size + bsize - > p->max_temp_file_size))) - { - break; - } - - prev_last_shadow = cl->buf->last_shadow; - - size += bsize; - ll = &cl->next; - cl = cl->next; - - } while (cl); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "size: %z", size); - - if (ll == NULL) { - return NGX_BUSY; - } - - if (cl) { - p->in = cl; - *ll = NULL; - - } else { - p->in = NULL; - p->last_in = &p->in; - } - - } else { - p->in = NULL; - p->last_in = &p->in; - } - -#if (NGX_THREADS) - if (p->thread_handler) { - p->temp_file->thread_write = 1; - p->temp_file->file.thread_task = p->thread_task; - p->temp_file->file.thread_handler = p->thread_handler; - p->temp_file->file.thread_ctx = p->thread_ctx; - } -#endif - - n = ngx_write_chain_to_temp_file(p->temp_file, out); - - if (n == NGX_ERROR) { - return NGX_ABORT; - } - -#if (NGX_THREADS) - - if (n == NGX_AGAIN) { - p->writing = out; - p->thread_task = p->temp_file->file.thread_task; - return NGX_AGAIN; - } - -done: - -#endif - - if (p->buf_to_file) { - p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos; - n -= p->buf_to_file->last - p->buf_to_file->pos; - p->buf_to_file = NULL; - out = out->next; - } - - if (n > 0) { - /* update previous buffer or add new buffer */ - - if (p->out) { - for (cl = p->out; cl->next; cl = cl->next) { /* void */ } - - b = cl->buf; - - if (b->file_last == p->temp_file->offset) { - p->temp_file->offset += n; - b->file_last = p->temp_file->offset; - goto free; - } - - last_out = &cl->next; - - } else { - last_out = &p->out; - } - - cl = ngx_chain_get_free_buf(p->pool, &p->free); - if (cl == NULL) { - return NGX_ABORT; - } - - b = cl->buf; - - ngx_memzero(b, sizeof(ngx_buf_t)); - - b->tag = p->tag; - - b->file = &p->temp_file->file; - b->file_pos = p->temp_file->offset; - p->temp_file->offset += n; - b->file_last = p->temp_file->offset; - - b->in_file = 1; - b->temp_file = 1; - - *last_out = cl; - } - -free: - - for (last_free = &p->free_raw_bufs; - *last_free != NULL; - last_free = &(*last_free)->next) - { - /* void */ - } - - for (cl = out; cl; cl = next) { - next = cl->next; - - cl->next = p->free; - p->free = cl; - - b = cl->buf; - - if (b->last_shadow) { - - tl = ngx_alloc_chain_link(p->pool); - if (tl == NULL) { - return NGX_ABORT; - } - - tl->buf = b->shadow; - tl->next = NULL; - - *last_free = tl; - last_free = &tl->next; - - b->shadow->pos = b->shadow->start; - b->shadow->last = b->shadow->start; - - ngx_event_pipe_remove_shadow_links(b->shadow); - } - } - - return NGX_OK; -} - - -/* the copy input filter */ - -ngx_int_t -ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf) -{ - ngx_buf_t *b; - ngx_chain_t *cl; - - if (buf->pos == buf->last) { - return NGX_OK; - } - - cl = ngx_chain_get_free_buf(p->pool, &p->free); - if (cl == NULL) { - return NGX_ERROR; - } - - b = cl->buf; - - ngx_memcpy(b, buf, sizeof(ngx_buf_t)); - b->shadow = buf; - b->tag = p->tag; - b->last_shadow = 1; - b->recycled = 1; - buf->shadow = b; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num); - - if (p->in) { - *p->last_in = cl; - } else { - p->in = cl; - } - p->last_in = &cl->next; - - if (p->length == -1) { - return NGX_OK; - } - - p->length -= b->last - b->pos; - - return NGX_OK; -} - - -static ngx_inline void -ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf) -{ - ngx_buf_t *b, *next; - - b = buf->shadow; - - if (b == NULL) { - return; - } - - while (!b->last_shadow) { - next = b->shadow; - - b->temporary = 0; - b->recycled = 0; - - b->shadow = NULL; - b = next; - } - - b->temporary = 0; - b->recycled = 0; - b->last_shadow = 0; - - b->shadow = NULL; - - buf->shadow = NULL; -} - - -ngx_int_t -ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b) -{ - ngx_chain_t *cl; - - cl = ngx_alloc_chain_link(p->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - if (p->buf_to_file && b->start == p->buf_to_file->start) { - b->pos = p->buf_to_file->last; - b->last = p->buf_to_file->last; - - } else { - b->pos = b->start; - b->last = b->start; - } - - b->shadow = NULL; - - cl->buf = b; - - if (p->free_raw_bufs == NULL) { - p->free_raw_bufs = cl; - cl->next = NULL; - - return NGX_OK; - } - - if (p->free_raw_bufs->buf->pos == p->free_raw_bufs->buf->last) { - - /* add the free buf to the list start */ - - cl->next = p->free_raw_bufs; - p->free_raw_bufs = cl; - - return NGX_OK; - } - - /* the first free buf is partially filled, thus add the free buf after it */ - - cl->next = p->free_raw_bufs->next; - p->free_raw_bufs->next = cl; - - return NGX_OK; -} - - -static ngx_int_t -ngx_event_pipe_drain_chains(ngx_event_pipe_t *p) -{ - ngx_chain_t *cl, *tl; - - for ( ;; ) { - if (p->busy) { - cl = p->busy; - p->busy = NULL; - - } else if (p->out) { - cl = p->out; - p->out = NULL; - - } else if (p->in) { - cl = p->in; - p->in = NULL; - - } else { - return NGX_OK; - } - - while (cl) { - if (cl->buf->last_shadow) { - if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) { - return NGX_ABORT; - } - - cl->buf->last_shadow = 0; - } - - cl->buf->shadow = NULL; - tl = cl->next; - cl->next = p->free; - p->free = cl; - cl = tl; - } - } -} diff --git a/app/nginx/src/event/ngx_event_pipe.h b/app/nginx/src/event/ngx_event_pipe.h deleted file mode 100644 index 10a3340..0000000 --- a/app/nginx/src/event/ngx_event_pipe.h +++ /dev/null @@ -1,107 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_EVENT_PIPE_H_INCLUDED_ -#define _NGX_EVENT_PIPE_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -typedef struct ngx_event_pipe_s ngx_event_pipe_t; - -typedef ngx_int_t (*ngx_event_pipe_input_filter_pt)(ngx_event_pipe_t *p, - ngx_buf_t *buf); -typedef ngx_int_t (*ngx_event_pipe_output_filter_pt)(void *data, - ngx_chain_t *chain); - - -struct ngx_event_pipe_s { - ngx_connection_t *upstream; - ngx_connection_t *downstream; - - ngx_chain_t *free_raw_bufs; - ngx_chain_t *in; - ngx_chain_t **last_in; - - ngx_chain_t *writing; - - ngx_chain_t *out; - ngx_chain_t *free; - ngx_chain_t *busy; - - /* - * the input filter i.e. that moves HTTP/1.1 chunks - * from the raw bufs to an incoming chain - */ - - ngx_event_pipe_input_filter_pt input_filter; - void *input_ctx; - - ngx_event_pipe_output_filter_pt output_filter; - void *output_ctx; - -#if (NGX_THREADS || NGX_COMPAT) - ngx_int_t (*thread_handler)(ngx_thread_task_t *task, - ngx_file_t *file); - void *thread_ctx; - ngx_thread_task_t *thread_task; -#endif - - unsigned read:1; - unsigned cacheable:1; - unsigned single_buf:1; - unsigned free_bufs:1; - unsigned upstream_done:1; - unsigned upstream_error:1; - unsigned upstream_eof:1; - unsigned upstream_blocked:1; - unsigned downstream_done:1; - unsigned downstream_error:1; - unsigned cyclic_temp_file:1; - unsigned aio:1; - - ngx_int_t allocated; - ngx_bufs_t bufs; - ngx_buf_tag_t tag; - - ssize_t busy_size; - - off_t read_length; - off_t length; - - off_t max_temp_file_size; - ssize_t temp_file_write_size; - - ngx_msec_t read_timeout; - ngx_msec_t send_timeout; - ssize_t send_lowat; - - ngx_pool_t *pool; - ngx_log_t *log; - - ngx_chain_t *preread_bufs; - size_t preread_size; - ngx_buf_t *buf_to_file; - - size_t limit_rate; - time_t start_sec; - - ngx_temp_file_t *temp_file; - - /* STUB */ int num; -}; - - -ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write); -ngx_int_t ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf); -ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b); - - -#endif /* _NGX_EVENT_PIPE_H_INCLUDED_ */ diff --git a/app/nginx/src/event/ngx_event_posted.c b/app/nginx/src/event/ngx_event_posted.c deleted file mode 100644 index d851f3d..0000000 --- a/app/nginx/src/event/ngx_event_posted.c +++ /dev/null @@ -1,35 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -ngx_queue_t ngx_posted_accept_events; -ngx_queue_t ngx_posted_events; - - -void -ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted) -{ - ngx_queue_t *q; - ngx_event_t *ev; - - while (!ngx_queue_empty(posted)) { - - q = ngx_queue_head(posted); - ev = ngx_queue_data(q, ngx_event_t, queue); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "posted event %p", ev); - - ngx_delete_posted_event(ev); - - ev->handler(ev); - } -} diff --git a/app/nginx/src/event/ngx_event_posted.h b/app/nginx/src/event/ngx_event_posted.h deleted file mode 100644 index 145d30f..0000000 --- a/app/nginx/src/event/ngx_event_posted.h +++ /dev/null @@ -1,48 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_EVENT_POSTED_H_INCLUDED_ -#define _NGX_EVENT_POSTED_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#define ngx_post_event(ev, q) \ - \ - if (!(ev)->posted) { \ - (ev)->posted = 1; \ - ngx_queue_insert_tail(q, &(ev)->queue); \ - \ - ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, "post event %p", ev);\ - \ - } else { \ - ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \ - "update posted event %p", ev); \ - } - - -#define ngx_delete_posted_event(ev) \ - \ - (ev)->posted = 0; \ - ngx_queue_remove(&(ev)->queue); \ - \ - ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \ - "delete posted event %p", ev); - - - -void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted); - - -extern ngx_queue_t ngx_posted_accept_events; -extern ngx_queue_t ngx_posted_events; - - -#endif /* _NGX_EVENT_POSTED_H_INCLUDED_ */ diff --git a/app/nginx/src/event/ngx_event_timer.c b/app/nginx/src/event/ngx_event_timer.c deleted file mode 100644 index 698b88f..0000000 --- a/app/nginx/src/event/ngx_event_timer.c +++ /dev/null @@ -1,126 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -ngx_rbtree_t ngx_event_timer_rbtree; -static ngx_rbtree_node_t ngx_event_timer_sentinel; - -/* - * the event timer rbtree may contain the duplicate keys, however, - * it should not be a problem, because we use the rbtree to find - * a minimum timer value only - */ - -ngx_int_t -ngx_event_timer_init(ngx_log_t *log) -{ - ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel, - ngx_rbtree_insert_timer_value); - - return NGX_OK; -} - - -ngx_msec_t -ngx_event_find_timer(void) -{ - ngx_msec_int_t timer; - ngx_rbtree_node_t *node, *root, *sentinel; - - if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) { - return NGX_TIMER_INFINITE; - } - - root = ngx_event_timer_rbtree.root; - sentinel = ngx_event_timer_rbtree.sentinel; - - node = ngx_rbtree_min(root, sentinel); - - timer = (ngx_msec_int_t) (node->key - ngx_current_msec); - - return (ngx_msec_t) (timer > 0 ? timer : 0); -} - - -void -ngx_event_expire_timers(void) -{ - ngx_event_t *ev; - ngx_rbtree_node_t *node, *root, *sentinel; - - sentinel = ngx_event_timer_rbtree.sentinel; - - for ( ;; ) { - root = ngx_event_timer_rbtree.root; - - if (root == sentinel) { - return; - } - - node = ngx_rbtree_min(root, sentinel); - - /* node->key > ngx_current_msec */ - - if ((ngx_msec_int_t) (node->key - ngx_current_msec) > 0) { - return; - } - - ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "event timer del: %d: %M", - ngx_event_ident(ev->data), ev->timer.key); - - ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); - -#if (NGX_DEBUG) - ev->timer.left = NULL; - ev->timer.right = NULL; - ev->timer.parent = NULL; -#endif - - ev->timer_set = 0; - - ev->timedout = 1; - - ev->handler(ev); - } -} - - -ngx_int_t -ngx_event_no_timers_left(void) -{ - ngx_event_t *ev; - ngx_rbtree_node_t *node, *root, *sentinel; - - sentinel = ngx_event_timer_rbtree.sentinel; - root = ngx_event_timer_rbtree.root; - - if (root == sentinel) { - return NGX_OK; - } - - for (node = ngx_rbtree_min(root, sentinel); - node; - node = ngx_rbtree_next(&ngx_event_timer_rbtree, node)) - { - ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); - - if (!ev->cancelable) { - return NGX_AGAIN; - } - } - - /* only cancelable timers left */ - - return NGX_OK; -} diff --git a/app/nginx/src/event/ngx_event_timer.h b/app/nginx/src/event/ngx_event_timer.h deleted file mode 100644 index be81b15..0000000 --- a/app/nginx/src/event/ngx_event_timer.h +++ /dev/null @@ -1,90 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_EVENT_TIMER_H_INCLUDED_ -#define _NGX_EVENT_TIMER_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> - - -#define NGX_TIMER_INFINITE (ngx_msec_t) -1 - -#define NGX_TIMER_LAZY_DELAY 300 - - -ngx_int_t ngx_event_timer_init(ngx_log_t *log); -ngx_msec_t ngx_event_find_timer(void); -void ngx_event_expire_timers(void); -ngx_int_t ngx_event_no_timers_left(void); - - -extern ngx_rbtree_t ngx_event_timer_rbtree; - - -static ngx_inline void -ngx_event_del_timer(ngx_event_t *ev) -{ - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "event timer del: %d: %M", - ngx_event_ident(ev->data), ev->timer.key); - - ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); - -#if (NGX_DEBUG) - ev->timer.left = NULL; - ev->timer.right = NULL; - ev->timer.parent = NULL; -#endif - - ev->timer_set = 0; -} - - -static ngx_inline void -ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer) -{ - ngx_msec_t key; - ngx_msec_int_t diff; - - key = ngx_current_msec + timer; - - if (ev->timer_set) { - - /* - * Use a previous timer value if difference between it and a new - * value is less than NGX_TIMER_LAZY_DELAY milliseconds: this allows - * to minimize the rbtree operations for fast connections. - */ - - diff = (ngx_msec_int_t) (key - ev->timer.key); - - if (ngx_abs(diff) < NGX_TIMER_LAZY_DELAY) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "event timer: %d, old: %M, new: %M", - ngx_event_ident(ev->data), ev->timer.key, key); - return; - } - - ngx_del_timer(ev); - } - - ev->timer.key = key; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "event timer add: %d: %M:%M", - ngx_event_ident(ev->data), timer, ev->timer.key); - - ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer); - - ev->timer_set = 1; -} - - -#endif /* _NGX_EVENT_TIMER_H_INCLUDED_ */ |