summaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ngx_array.h2
-rw-r--r--src/core/ngx_connection.c153
-rw-r--r--src/core/ngx_connection.h4
-rw-r--r--src/core/ngx_log.c3
-rw-r--r--src/core/ngx_log.h8
5 files changed, 168 insertions, 2 deletions
diff --git a/src/core/ngx_array.h b/src/core/ngx_array.h
index 848596cdf..fadb203fb 100644
--- a/src/core/ngx_array.h
+++ b/src/core/ngx_array.h
@@ -41,5 +41,7 @@ ngx_inline static ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool,
ngx_test_null(a.elts, ngx_palloc(p, n * s), rc); \
a.nelts = 0; a.size = s; a.nalloc = n; a.pool = p;
+#define ngx_array_push ngx_push_array
+
#endif /* _NGX_ARRAY_H_INCLUDED_ */
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index d5de07675..5fc99b39e 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -7,6 +7,55 @@
ngx_os_io_t ngx_io;
+ngx_listening_t *ngx_listening_inet_stream_socket(ngx_conf_t *cf,
+ in_addr_t addr,
+ in_port_t port)
+{
+ size_t len;
+ ngx_listening_t *ls;
+ struct sockaddr_in *addr_in;
+
+ if (!(ls = ngx_array_push(&cf->cycle->listening))) {
+ return NULL;
+ }
+
+ ngx_memzero(ls, sizeof(ngx_listening_t));
+
+ if (!(addr_in = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)))) {
+ return NULL;
+ }
+
+#if (HAVE_SIN_LEN)
+ addr_in->sin_len = sizeof(struct sockaddr_in);
+#endif
+ addr_in->sin_family = AF_INET;
+ addr_in->sin_addr.s_addr = addr;
+ addr_in->sin_port = htons(port);
+
+ if (!(ls->addr_text.data = ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6))) {
+ return NULL;
+ }
+
+ len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data, INET_ADDRSTRLEN);
+ ls->addr_text.len = ngx_snprintf((char *) ls->addr_text.data + len,
+ 6, ":%d", port);
+
+ ls->fd = (ngx_socket_t) -1;
+ ls->family = AF_INET;
+ ls->type = SOCK_STREAM;
+ ls->protocol = IPPROTO_IP;
+#if (WIN32)
+ ls->flags = WSA_FLAG_OVERLAPPED;
+#endif
+ ls->sockaddr = (struct sockaddr *) addr_in;
+ ls->socklen = sizeof(struct sockaddr_in);
+ ls->addr = offsetof(struct sockaddr_in, sin_addr);
+ ls->addr_text_max_len = INET_ADDRSTRLEN;
+
+ return ls;
+}
+
+
ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle)
{
ngx_uint_t i;
@@ -251,6 +300,110 @@ void ngx_close_listening_sockets(ngx_cycle_t *cycle)
}
+void ngx_close_connection(ngx_connection_t *c)
+{
+ ngx_socket_t fd;
+
+ if (c->pool == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
+ return;
+ }
+
+#if (NGX_OPENSSL)
+
+ if (c->ssl) {
+ if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
+ c->read->event_handler = ngx_ssl_close_handler;
+ c->write->event_handler = ngx_ssl_close_handler;
+ return;
+ }
+ }
+
+#endif
+
+ if (c->read->timer_set) {
+ ngx_del_timer(c->read);
+ }
+
+ if (c->write->timer_set) {
+ ngx_del_timer(c->write);
+ }
+
+ if (ngx_del_conn) {
+ ngx_del_conn(c, NGX_CLOSE_EVENT);
+
+ } else {
+ if (c->read->active || c->read->disabled) {
+ ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+ }
+
+ if (c->write->active || c->write->disabled) {
+ ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
+ }
+ }
+
+#if (NGX_THREADS)
+
+ /*
+ * we have to clean the connection information before the closing
+ * because another thread may reopen the same file descriptor
+ * before we clean the connection
+ */
+
+ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_OK) {
+
+ if (c->read->prev) {
+ ngx_delete_posted_event(c->read);
+ }
+
+ if (c->write->prev) {
+ ngx_delete_posted_event(c->write);
+ }
+
+ c->read->closed = 1;
+ c->write->closed = 1;
+
+ if (c->single_connection) {
+ ngx_unlock(&c->lock);
+ c->read->locked = 0;
+ c->write->locked = 0;
+ }
+
+ ngx_mutex_unlock(ngx_posted_events_mutex);
+ }
+
+#else
+
+ if (c->read->prev) {
+ ngx_delete_posted_event(c->read);
+ }
+
+ if (c->write->prev) {
+ ngx_delete_posted_event(c->write);
+ }
+
+ c->read->closed = 1;
+ c->write->closed = 1;
+
+#endif
+
+ fd = c->fd;
+ c->fd = (ngx_socket_t) -1;
+ c->data = NULL;
+
+ ngx_destroy_pool(c->pool);
+
+ if (ngx_close_socket(fd) == -1) {
+
+ /* we use ngx_cycle->log because c->log was in c->pool */
+
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
+ ngx_close_socket_n " failed");
+ }
+}
+
+
+
ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
{
ngx_uint_t level;
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index c2bdcea4b..b84695685 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -129,9 +129,13 @@ struct ngx_connection_s {
#endif
+ngx_listening_t *ngx_listening_inet_stream_socket(ngx_conf_t *cf,
+ in_addr_t addr,
+ in_port_t port);
ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle);
ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle);
void ngx_close_listening_sockets(ngx_cycle_t *cycle);
+void ngx_close_connection(ngx_connection_t *c);
ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text);
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index a3f6e77cb..05ee4dd1d 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -47,7 +47,8 @@ static const char *err_levels[] = {
};
static const char *debug_levels[] = {
- "debug_core", "debug_alloc", "debug_mutex", "debug_event", "debug_http"
+ "debug_core", "debug_alloc", "debug_mutex", "debug_event",
+ "debug_http", "debug_imap"
};
diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h
index 20fb227df..21d3e6b76 100644
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -21,9 +21,15 @@
#define NGX_LOG_DEBUG_MUTEX 0x040
#define NGX_LOG_DEBUG_EVENT 0x080
#define NGX_LOG_DEBUG_HTTP 0x100
+#define NGX_LOG_DEBUG_IMAP 0x200
+
+/*
+ * after the adding a new debug level do not forget to update
+ * debug_levels[] in src/core/ngx_log.c
+ */
#define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG_CORE
-#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_HTTP
+#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_IMAP
#define NGX_LOG_DEBUG_CONNECTION 0x80000000
#define NGX_LOG_DEBUG_ALL 0x7ffffff0