From 9549579639590404a3e56886cf587437992d22a6 Mon Sep 17 00:00:00 2001 From: harijvs6 Date: Tue, 9 Oct 2018 04:45:36 +0530 Subject: [PATCH 1/4] cosockets nonblocking listen accept feature base version --- src/ngx_http_lua_socket_tcp.c | 1391 ++++++++++++++++++++++++++++++++- src/ngx_http_lua_socket_tcp.h | 22 + 2 files changed, 1393 insertions(+), 20 deletions(-) diff --git a/src/ngx_http_lua_socket_tcp.c b/src/ngx_http_lua_socket_tcp.c index af7b28921e..6f9f8ed557 100644 --- a/src/ngx_http_lua_socket_tcp.c +++ b/src/ngx_http_lua_socket_tcp.c @@ -142,6 +142,38 @@ static int ngx_http_lua_ssl_free_session(lua_State *L); #endif static void ngx_http_lua_socket_tcp_close_connection(ngx_connection_t *c); +static int ngx_http_lua_socket_tcp_bind(lua_State *L); +static int ngx_http_lua_socket_tcp_bind_listening(ngx_http_request_t *r, + ngx_listening_t *ls); +static ngx_listening_t * + ngx_http_lua_socket_init_listening(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *server); +static ngx_listening_t * + ngx_http_lua_socket_create_listening(ngx_http_request_t *r, + struct sockaddr *sockaddr, socklen_t socklen); +static int ngx_http_lua_socket_open_listening(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L); +static int ngx_http_lua_socket_tcp_server_listen(lua_State *L); +static int ngx_http_lua_socket_tcp_server_accept(lua_State *L); +static int ngx_http_lua_socket_tcp_server_close(lua_State *L); +static int ngx_http_lua_socket_tcp_master_listen(lua_State *L); +static int ngx_http_lua_socket_tcp_register_read(ngx_listening_t *ls); +static void ngx_http_lua_socket_accept_handler(ngx_connection_t *c); +static void ngx_http_lua_socket_tcp_server_cleanup(void *data); +static void ngx_http_lua_socket_tcp_server_finalize(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s); +static void ngx_http_lua_socket_handle_accept_error(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, ngx_uint_t ft_type); +static void ngx_http_lua_socket_handle_accept_success(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *u); +static int ngx_http_lua_socket_tcp_bind_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L); +static int ngx_http_lua_socket_tcp_listen_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L); +static int ngx_http_lua_socket_tcp_accept_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L); +static int ngx_http_lua_socket_tcp_server_destroy(lua_State *L); +static ngx_int_t ngx_http_lua_socket_tcp_accept_resume(ngx_http_request_t *r); enum { SOCKET_CTX_INDEX = 1, @@ -153,12 +185,21 @@ enum { enum { + SOCKET_OP_ACCEPT, SOCKET_OP_CONNECT, SOCKET_OP_READ, SOCKET_OP_WRITE }; +#define ngx_http_lua_socket_check_busy_accepting(r, s, L) \ + if ((s)->accept_waiting) { \ + lua_pushnil(L); \ + lua_pushliteral(L, "socket busy accepting"); \ + return 2; \ + } + + #define ngx_http_lua_socket_check_busy_connecting(r, u, L) \ if ((u)->conn_waiting) { \ lua_pushnil(L); \ @@ -192,6 +233,8 @@ enum { static char ngx_http_lua_req_socket_metatable_key; static char ngx_http_lua_raw_req_socket_metatable_key; +static char ngx_http_lua_tcp_server_metatable_key; +static char ngx_http_lua_server_udata_metatable_key; static char ngx_http_lua_tcp_socket_metatable_key; static char ngx_http_lua_upstream_udata_metatable_key; static char ngx_http_lua_downstream_udata_metatable_key; @@ -282,10 +325,36 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) lua_rawset(L, LUA_REGISTRYINDEX); /* }}} */ + /* {{{tcp server object metatable */ + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + tcp_server_metatable_key)); + lua_createtable(L, 0 /* narr */, 4 /* nrec */); + + lua_pushcfunction(L, ngx_http_lua_socket_tcp_server_listen); + lua_setfield(L, -2, "listen"); + + lua_pushcfunction(L, ngx_http_lua_socket_tcp_server_accept); + lua_setfield(L, -2, "accept"); + + lua_pushcfunction(L, ngx_http_lua_socket_tcp_server_close); + lua_setfield(L, -2, "close"); + + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + + lua_rawset(L, LUA_REGISTRYINDEX); + /* }}} */ + /* {{{tcp object metatable */ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( tcp_socket_metatable_key)); - lua_createtable(L, 0 /* narr */, 12 /* nrec */); + lua_createtable(L, 0 /* narr */, 14 /* nrec */); + + lua_pushcfunction(L, ngx_http_lua_socket_tcp_bind); + lua_setfield(L, -2, "bind"); + + lua_pushcfunction(L, ngx_http_lua_socket_tcp_master_listen); + lua_setfield(L, -2, "listen"); lua_pushcfunction(L, ngx_http_lua_socket_tcp_connect); lua_setfield(L, -2, "connect"); @@ -332,6 +401,15 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) lua_rawset(L, LUA_REGISTRYINDEX); /* }}} */ + /* {{{server userdata metatable */ + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + server_udata_metatable_key)); + lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */ + lua_pushcfunction(L, ngx_http_lua_socket_tcp_server_destroy); + lua_setfield(L, -2, "__gc"); + lua_rawset(L, LUA_REGISTRYINDEX); + /* }}} */ + /* {{{upstream userdata metatable */ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( upstream_udata_metatable_key)); @@ -5401,9 +5479,10 @@ ngx_http_lua_socket_tcp_resume_helper(ngx_http_request_t *r, int socket_op) ngx_http_lua_ctx_t *ctx; ngx_http_lua_co_ctx_t *coctx; - ngx_http_lua_socket_tcp_retval_handler prepare_retvals; - + ngx_http_lua_socket_tcp_retval_handler prepare_retvals; + ngx_http_lua_socket_tcp_server_retval_handler accept_prepare_retvals; ngx_http_lua_socket_tcp_upstream_t *u; + ngx_http_lua_socket_tcp_server_t *s; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { @@ -5419,28 +5498,38 @@ ngx_http_lua_socket_tcp_resume_helper(ngx_http_request_t *r, int socket_op) dd("coctx: %p", coctx); - u = coctx->data; + if(socket_op == SOCKET_OP_ACCEPT) { + s = coctx->data; - switch (socket_op) { - case SOCKET_OP_CONNECT: - case SOCKET_OP_WRITE: - prepare_retvals = u->write_prepare_retvals; - break; + accept_prepare_retvals = s->prepare_retvals; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket calling prepare retvals handler %p, " + "s:%p", accept_prepare_retvals, s); + nret = accept_prepare_retvals(r, s, ctx->cur_co_ctx->co); + } else { + u = coctx->data; - case SOCKET_OP_READ: - prepare_retvals = u->read_prepare_retvals; - break; + switch (socket_op) { + case SOCKET_OP_CONNECT: + case SOCKET_OP_WRITE: + prepare_retvals = u->write_prepare_retvals; + break; - default: - /* impossible to reach here */ - return NGX_ERROR; - } + case SOCKET_OP_READ: + prepare_retvals = u->read_prepare_retvals; + break; - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua tcp socket calling prepare retvals handler %p, " - "u:%p", prepare_retvals, u); + default: + /* impossible to reach here */ + return NGX_ERROR; + } - nret = prepare_retvals(r, u, ctx->cur_co_ctx->co); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket calling prepare retvals handler %p, " + "u:%p", prepare_retvals, u); + nret = prepare_retvals(r, u, ctx->cur_co_ctx->co); + } + if (nret == NGX_AGAIN) { return NGX_DONE; } @@ -5569,4 +5658,1266 @@ ngx_http_lua_cleanup_conn_pools(lua_State *L) lua_pop(L, 1); } +static int +ngx_http_lua_socket_tcp_bind(lua_State *L) +{ + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + ngx_listening_t *ls; + ngx_http_lua_socket_tcp_server_t *s; + int n; + ngx_str_t host; + int port; + ngx_http_cleanup_t *cln; + + dd("tcp bind"); + n = lua_gettop(L); + if (n != 2 && n != 3 && n != 4) { + return luaL_error(L, "ngx.socket connect: expecting 2, 3, or 4 " + "arguments (including the object), but seen %d", n); + } + + r = ngx_http_lua_get_req(L); + if (r == NULL) { + return luaL_error(L, "no request found"); + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return luaL_error(L, "no ctx found"); + } + + ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_ACCESS + | NGX_HTTP_LUA_CONTEXT_CONTENT + | NGX_HTTP_LUA_CONTEXT_TIMER + | NGX_HTTP_LUA_CONTEXT_SSL_CERT + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH); + + luaL_checktype(L, 1, LUA_TTABLE); + + host.data = (u_char *) luaL_checklstring(L, 2, &host.len); + + if (lua_type(L, n) == LUA_TTABLE) { + + /* found the last optional option table */ + + // TODO allow to configure bind options + + n--; + } + + /* the fourth argument is not a table */ + if (n == 4) { + lua_pop(L, 1); + n--; + } + if (n == 3) { + port = luaL_checkinteger(L, 3); + + if (port < 0 || port > 65535) { + lua_pushnil(L); + lua_pushfstring(L, "bad port number: %d", port); + return 2; + } + + dd("port: %d", port); + + } else { /* n == 2 */ + port = 0; + } + + s = lua_newuserdata(L, sizeof(ngx_http_lua_socket_tcp_server_t)); + if (s == NULL) { + return luaL_error(L, "no memory"); + } + +#if 1 + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + server_udata_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); +#endif + + ngx_memzero(s, sizeof(ngx_http_lua_socket_tcp_server_t)); + + s->request = r; /* set the controlling request */ + s->host = host; + s->port = port; + + if (s->cleanup == NULL) { + cln = ngx_http_lua_cleanup_add(r, 0); + if (cln == NULL) { + s->ft_type |= NGX_HTTP_LUA_SOCKET_FT_ERROR; + lua_pushnil(L); + lua_pushliteral(L, "no memory"); + return 2; + } + + cln->handler = ngx_http_lua_socket_tcp_server_cleanup; + cln->data = s; + s->cleanup = &cln->handler; + } + + ls = ngx_http_lua_socket_init_listening(r, s); + if(ls == NULL) { + s->ft_type |= NGX_HTTP_LUA_SOCKET_FT_ERROR; + lua_pushnil(L); + lua_pushliteral(L, "bind failure"); + return 2; + } + + ngx_http_lua_socket_tcp_bind_listening(r, ls); + + s->listening = ls; + + return ngx_http_lua_socket_tcp_bind_retval_handler(r, s, L); +} + +static int +ngx_http_lua_socket_tcp_server_accept(lua_State *L) +{ + int n; + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_socket_tcp_server_t *s; + ngx_connection_t *c; + ngx_event_t *rev; + ngx_http_lua_co_ctx_t *coctx; + ngx_int_t rc; + ngx_http_request_t *r; + ngx_listening_t *ls; + + dd("tcp accept"); + n = lua_gettop(L); + if (n != 1) { + return luaL_error(L, "ngx.socket accept: expecting 1 " + "arguments (including the object), but seen %d", n); + } + + r = ngx_http_lua_get_req(L); + if (r == NULL) { + return luaL_error(L, "no request found"); + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return luaL_error(L, "no ctx found"); + } + + ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_ACCESS + | NGX_HTTP_LUA_CONTEXT_CONTENT + | NGX_HTTP_LUA_CONTEXT_TIMER + | NGX_HTTP_LUA_CONTEXT_SSL_CERT + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH); + + luaL_checktype(L, 1, LUA_TTABLE); + lua_rawgeti(L, 1, SOCKET_CTX_INDEX); + + s = lua_touserdata(L, -1); + lua_pop(L, 1); + if (s == NULL) { + + lua_pushnil(L); + lua_pushliteral(L, "closed"); + return 2; + } + + if (s->request != r) { + return luaL_error(L, "bad request"); + } + + ls = s->listening; + + c = ngx_get_connection(ls->fd, r->connection->log); + + if (c == NULL) { + return luaL_error(L, "connection error"); + } + c->type = ls->type; + + c->listening = ls; + ls->connection = c; + + rev = c->read; + + rev->log = c->log; + rev->accept = 1; + +#if (NGX_HAVE_DEFERRED_ACCEPT) + rev->deferred_accept = ls->deferred_accept; +#endif + + rc = ngx_http_lua_socket_tcp_register_read(ls); + if(rc == NGX_ERROR) { + return luaL_error(L, "register failed"); + } + + // rc == NGX_AGAIN + + coctx = ctx->cur_co_ctx; + + coctx->data = s; + s->co_ctx = coctx; + s->accept_waiting = 1; + s->prepare_retvals = ngx_http_lua_socket_tcp_accept_retval_handler; + + dd("setting data to %p", s); + + if (ctx->entered_content_phase) { + r->write_event_handler = ngx_http_lua_content_wev_handler; + + } else { + r->write_event_handler = ngx_http_core_run_phases; + } + + return lua_yield(L, 0); +} + +static int +ngx_http_lua_socket_tcp_register_read(ngx_listening_t *ls) +{ + + ngx_connection_t *c; + ngx_event_t *rev; + + c = ls->connection; + rev = c->read; + +#if (NGX_WIN32) + + if (ngx_event_flags & NGX_USE_IOCP_EVENT) { + ngx_iocp_conf_t *iocpcf; + + rev->handler = ngx_event_acceptex; + + if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) { + return NGX_ERROR; + } + + ls->log.handler = ngx_acceptex_log_error; + + iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); + if (ngx_event_post_acceptex(ls, iocpcf->post_acceptex) + == NGX_ERROR) + { + return NGX_ERROR; + } + + } else { + rev->handler = ngx_event_accept; + + 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->reuseport) { + if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { + return NGX_ERROR; + } + return NGX_AGAIN; + } + +#endif + +#if (NGX_HAVE_EPOLLEXCLUSIVE) + + // TODO alternative to work processes. light threads? + if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) + && 1) + { + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT) + == NGX_ERROR) + { + return NGX_ERROR; + } + return NGX_AGAIN; + } + +#endif + + if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { + return NGX_ERROR; + } + +#endif + return NGX_AGAIN; +} + +static int +ngx_http_lua_socket_tcp_bind_listening(ngx_http_request_t *r, + ngx_listening_t *ls) +{ + int reuseaddr; + ngx_err_t err; + ngx_log_t *log; + ngx_socket_t s; + + reuseaddr = 1; + + log = r->connection->log; + +#if (NGX_HAVE_REUSEPORT) + if (ls->add_reuseport) { + + /* + * to allow transition from a socket without SO_REUSEPORT + * to multiple sockets with SO_REUSEPORT, we have to set + * SO_REUSEPORT on the old socket before opening new ones + */ + + int reuseport = 1; + + if (setsockopt(ls->fd, SOL_SOCKET, SO_REUSEPORT, + (const void *) &reuseport, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + "setsockopt(SO_REUSEPORT) %V failed, ignored", + &ls->addr_text); + } + + ls->add_reuseport = 0; + } +#endif + if (ls->fd != (ngx_socket_t) -1) { + return NGX_OK; + } + + if (ls->inherited) { + + /* TODO: close on exit */ + /* TODO: nonblocking */ + /* TODO: deferred accept */ + + return NGX_ERROR; + } + + s = ngx_socket(ls->sockaddr->sa_family, ls->type, 0); + if (s == (ngx_socket_t) -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_socket_n " %V failed", &ls->addr_text); + return NGX_ERROR; + } + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (const void *) &reuseaddr, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "setsockopt(SO_REUSEADDR) %V failed", + &ls->addr_text); + + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls->addr_text); + } + + return NGX_ERROR; + } + +#if (NGX_HAVE_REUSEPORT) + + if (ls->reuseport) { + int reuseport; + + reuseport = 1; + + if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, + (const void *) &reuseport, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "setsockopt(SO_REUSEPORT) %V failed", + &ls->addr_text); + + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls->addr_text); + } + + return NGX_ERROR; + } + } +#endif + +#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) + + if (ls->sockaddr->sa_family == AF_INET6) { + int ipv6only; + + ipv6only = ls->ipv6only; + + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + (const void *) &ipv6only, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "setsockopt(IPV6_V6ONLY) %V failed, ignored", + &ls->addr_text); + } + } +#endif + /* TODO: close on exit */ + + if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { + if (ngx_nonblocking(s) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_nonblocking_n " %V failed", + &ls->addr_text); + + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls->addr_text); + } + + return NGX_ERROR; + } + } + + ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0, + "bind() %V #%d ", &ls->addr_text, s); + + if (bind(s, ls->sockaddr, ls->socklen) == -1) { + err = ngx_socket_errno; + + if (err != NGX_EADDRINUSE) { + ngx_log_error(NGX_LOG_EMERG, log, err, + "bind() to %V failed", &ls->addr_text); + } + + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls->addr_text); + } + + return NGX_ERROR; + } + +#if (NGX_HAVE_UNIX_DOMAIN) + + if (ls->sockaddr->sa_family == AF_UNIX) { + mode_t mode; + u_char *name; + + name = ls->addr_text.data + sizeof("unix:") - 1; + mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); + + if (chmod((char *) name, mode) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "chmod() \"%s\" failed", name); + } + + if (ngx_delete_file(name) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + ngx_delete_file_n " %s failed", name); + } + } +#endif + + ls->fd = s; + + return NGX_OK; +} + +static int +ngx_http_lua_socket_tcp_server_listen(lua_State *L) +{ + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + ngx_listening_t *ls; + ngx_http_lua_socket_tcp_server_t *s; + int n; + int backlog; + + dd("tcp server listen"); + n = lua_gettop(L); + if (n != 1 && n != 2) { + return luaL_error(L, "ngx.socket listen: expecting 1, 2 " + "arguments (including the object), but seen %d", n); + } + + r = ngx_http_lua_get_req(L); + if (r == NULL) { + return luaL_error(L, "no request found"); + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return luaL_error(L, "no ctx found"); + } + + ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_ACCESS + | NGX_HTTP_LUA_CONTEXT_CONTENT + | NGX_HTTP_LUA_CONTEXT_TIMER + | NGX_HTTP_LUA_CONTEXT_SSL_CERT + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH); + + luaL_checktype(L, 1, LUA_TTABLE); + + lua_rawgeti(L, 1, SOCKET_CTX_INDEX); + s = lua_touserdata(L, -1); + lua_pop(L, 1); + + if (s == NULL) { + + lua_pushnil(L); + lua_pushliteral(L, "closed"); + return 2; + } + + if (s->request != r) { + return luaL_error(L, "bad request"); + } + + ls = s->listening; + + if (ls->listen == 1) { + return luaL_error(L, "already listening"); + } + + if (n == 2) { + backlog = luaL_checkinteger(L, 2); + lua_pop(L, 1); + ls->backlog = backlog; + } + + return ngx_http_lua_socket_open_listening(r, s, L); +} + + +static int +ngx_http_lua_socket_tcp_master_listen(lua_State *L) +{ + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + ngx_listening_t *ls; + ngx_http_lua_socket_tcp_server_t *s; + int n; + int backlog; + ngx_str_t host = ngx_string("0.0.0.0"); + ngx_http_cleanup_t *cln; + ngx_int_t rc; + + dd("tcp master listen"); + n = lua_gettop(L); + if (n != 1 && n != 2) { + return luaL_error(L, "ngx.socket listen: expecting 1, 2 " + "arguments (including the object), but seen %d", n); + } + + r = ngx_http_lua_get_req(L); + if (r == NULL) { + return luaL_error(L, "no request found"); + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return luaL_error(L, "no ctx found"); + } + + ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_ACCESS + | NGX_HTTP_LUA_CONTEXT_CONTENT + | NGX_HTTP_LUA_CONTEXT_TIMER + | NGX_HTTP_LUA_CONTEXT_SSL_CERT + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH); + + luaL_checktype(L, 1, LUA_TTABLE); + + s = lua_newuserdata(L, sizeof(ngx_http_lua_socket_tcp_server_t)); + if (s == NULL) { + return luaL_error(L, "no memory"); + } + +#if 1 + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + server_udata_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); +#endif + + ngx_memzero(s, sizeof(ngx_http_lua_socket_tcp_server_t)); + + s->request = r; /* set the controlling request */ + s->host = host; + s->port = 0; + + if (s->cleanup == NULL) { + cln = ngx_http_lua_cleanup_add(r, 0); + if (cln == NULL) { + lua_pushnil(L); + lua_pushliteral(L, "no memory"); + return 2; + } + + cln->handler = ngx_http_lua_socket_tcp_server_cleanup; + cln->data = s; + s->cleanup = &cln->handler; + } + + ls = ngx_http_lua_socket_init_listening(r, s); + if(ls == NULL) { + lua_pushnil(L); + lua_pushliteral(L, "listening prepare error"); + return 2; + } + + rc = ngx_http_lua_socket_tcp_bind_listening(r, ls); + if(rc == NGX_ERROR) { + lua_pushnil(L); + lua_pushliteral(L, "bind failed"); + return 2; + } + + s->listening = ls; + + if (n == 2) { + backlog = luaL_checkinteger(L, 2); + lua_pop(L, 1); + ls->backlog = backlog; + } + + return ngx_http_lua_socket_open_listening(r, s, L); +} + + +static int +ngx_http_lua_socket_open_listening(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L) +{ + ngx_listening_t *ls; + ngx_socket_t so; + ngx_log_t *log; + ngx_err_t err; + + ls = s->listening; + so = ls->fd; + log = r->connection->log; + + if (listen(so, ls->backlog) == -1) { + err = ngx_socket_errno; + + /* + * on OpenVZ after suspend/resume EADDRINUSE + * may be returned by listen() instead of bind(), see + * https://bugzilla.openvz.org/show_bug.cgi?id=2470 + */ + + ngx_log_error(NGX_LOG_EMERG, log, err, + "listen() to %V, backlog %d failed", + &ls->addr_text, ls->backlog); + + if (ngx_close_socket(so) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls->addr_text); + } + + lua_pushnil(L); + if(err == NGX_EADDRINUSE) { + lua_pushliteral(L, "addr already in use"); + } else { + lua_pushliteral(L, "listen failed"); + } + return 2; + } + + ls->listen = 1; + + return ngx_http_lua_socket_tcp_listen_retval_handler(r, s, L); +} + +static ngx_listening_t * +ngx_http_lua_socket_init_listening(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s) +{ + + ngx_listening_t *ls; + ngx_http_listen_opt_t lsopt; + ngx_http_conf_addr_t *addr; + ngx_url_t u; + + ngx_memzero(&u, sizeof(ngx_url_t)); + + u.url.len = s->host.len; + u.url.data = s->host.data; + u.default_port = (in_port_t) s->port; + u.listen = 1; + + if (ngx_parse_url(r->pool, &u) != NGX_OK) { + return NULL; + } + + ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t)); + + ngx_memcpy(&lsopt.sockaddr.sockaddr, &u.sockaddr, u.socklen); + + lsopt.socklen = u.socklen; + lsopt.backlog = NGX_LISTEN_BACKLOG; + lsopt.rcvbuf = -1; + lsopt.sndbuf = -1; +#if (NGX_HAVE_SETFIB) + lsopt.setfib = -1; +#endif +#if (NGX_HAVE_TCP_FASTOPEN) + lsopt.fastopen = -1; +#endif + lsopt.wildcard = u.wildcard; +#if (NGX_HAVE_INET6) + lsopt.ipv6only = 1; +#endif + + (void) ngx_sock_ntop(&lsopt.sockaddr.sockaddr, lsopt.socklen, lsopt.addr, + NGX_SOCKADDR_STRLEN, 1); + + lsopt.set = 1; + lsopt.bind = 1; + lsopt.reuseport = 1; + + addr = ngx_pcalloc(r->pool, sizeof(ngx_http_conf_addr_t)); + if (addr == NULL) { + return NULL; + } + + addr->opt = lsopt; + addr->hash.buckets = NULL; + addr->hash.size = 0; + addr->wc_head = NULL; + addr->wc_tail = NULL; +#if (NGX_PCRE) + addr->nregex = 0; + addr->regex = NULL; +#endif + addr->default_server = NULL; + addr->servers.elts = NULL; + + ls = ngx_http_lua_socket_create_listening(r, &addr->opt.sockaddr.sockaddr, + addr->opt.socklen); + if (ls == NULL) { + return NULL; + } + + ls->addr_ntop = 1; + + ls->handler = ngx_http_lua_socket_accept_handler; + + ls->log.data = &ls->addr_text; + ls->log.handler = ngx_accept_log_error; + +#if (NGX_WIN32) + { + ngx_iocp_conf_t *iocpcf = NULL; + + if (ngx_get_conf(cf->cycle->conf_ctx, ngx_events_module)) { + iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module); + } + if (iocpcf && iocpcf->acceptex_read) { + ls->post_accept_buffer_size = cscf->client_header_buffer_size; + } + } +#endif + + ls->backlog = addr->opt.backlog; + ls->rcvbuf = addr->opt.rcvbuf; + ls->sndbuf = addr->opt.sndbuf; + + ls->keepalive = addr->opt.so_keepalive; +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + ls->keepidle = addr->opt.tcp_keepidle; + ls->keepintvl = addr->opt.tcp_keepintvl; + ls->keepcnt = addr->opt.tcp_keepcnt; +#endif + +#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) + ls->accept_filter = addr->opt.accept_filter; +#endif + +#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) + ls->deferred_accept = addr->opt.deferred_accept; +#endif + +#if (NGX_HAVE_INET6) + ls->ipv6only = addr->opt.ipv6only; +#endif + +#if (NGX_HAVE_SETFIB) + ls->setfib = addr->opt.setfib; +#endif + +#if (NGX_HAVE_TCP_FASTOPEN) + ls->fastopen = addr->opt.fastopen; +#endif + +#if (NGX_HAVE_REUSEPORT) + ls->reuseport = addr->opt.reuseport; +#endif + + ls->servers = s; + return ls; +} + +static ngx_listening_t * +ngx_http_lua_socket_create_listening(ngx_http_request_t *r, + struct sockaddr *sockaddr, socklen_t socklen) +{ + size_t len; + ngx_listening_t *ls; + struct sockaddr *sa; + u_char text[NGX_SOCKADDR_STRLEN]; + + ls = ngx_pcalloc(r->pool, sizeof(ngx_listening_t)); + if (ls == NULL) { + return NULL; + } + + sa = ngx_palloc(r->pool, socklen); + if (sa == NULL) { + return NULL; + } + + ngx_memcpy(sa, sockaddr, socklen); + + ls->sockaddr = sa; + ls->socklen = socklen; + + len = ngx_sock_ntop(sa, socklen, text, NGX_SOCKADDR_STRLEN, 1); + ls->addr_text.len = len; + + switch (ls->sockaddr->sa_family) { +#if (NGX_HAVE_INET6) + case AF_INET6: + ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN; + break; +#endif +#if (NGX_HAVE_UNIX_DOMAIN) + case AF_UNIX: + ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN; + len++; + break; +#endif + case AF_INET: + ls->addr_text_max_len = NGX_INET_ADDRSTRLEN; + break; + default: + ls->addr_text_max_len = NGX_SOCKADDR_STRLEN; + break; + } + + ls->addr_text.data = ngx_pnalloc(r->pool, len); + if (ls->addr_text.data == NULL) { + return NULL; + } + + ngx_memcpy(ls->addr_text.data, text, len); + + ls->fd = (ngx_socket_t) -1; + ls->type = SOCK_STREAM; + + ls->backlog = NGX_LISTEN_BACKLOG; + ls->rcvbuf = -1; + ls->sndbuf = -1; + +#if (NGX_HAVE_SETFIB) + ls->setfib = -1; +#endif + +#if (NGX_HAVE_TCP_FASTOPEN) + ls->fastopen = -1; +#endif + + + return ls; +} + +static int +ngx_http_lua_socket_tcp_accept_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L) +{ + ngx_connection_t *c; + ngx_http_lua_socket_tcp_upstream_t *u; + ngx_peer_connection_t *pc; + ngx_http_lua_loc_conf_t *llcf; + ngx_http_cleanup_t *cln; + + lua_createtable(L, 5 /* narr */, 1 /* nrec */); + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + tcp_socket_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); + + u = lua_newuserdata(L, sizeof(ngx_http_lua_socket_tcp_upstream_t)); + if (u == NULL) { + return luaL_error(L, "no memory"); + } + +#if 1 + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + upstream_udata_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); +#endif + + lua_rawseti(L, -2, SOCKET_CTX_INDEX); + + ngx_memzero(u, sizeof(ngx_http_lua_socket_tcp_upstream_t)); + + u->request = r; /* set the controlling request */ + + if (u->cleanup == NULL) { + cln = ngx_http_lua_cleanup_add(r, 0); + if (cln == NULL) { + u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_ERROR; + lua_pushnil(L); + lua_pushliteral(L, "no memory"); + return 2; + } + + cln->handler = ngx_http_lua_socket_tcp_cleanup; + cln->data = u; + u->cleanup = &cln->handler; + } + + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); + + u->conf = llcf; + + pc = &u->peer; + pc->connection = s->connection; + pc->log = r->connection->log; + pc->log_error = NGX_ERROR_ERR; + + s->connection = NULL; + c = pc->connection; + + c->data = u; + c->write->handler = ngx_http_lua_socket_tcp_handler; + c->read->handler = ngx_http_lua_socket_tcp_handler; + + u->write_event_handler = ngx_http_lua_socket_connected_handler; + u->read_event_handler = ngx_http_lua_socket_connected_handler; + + return 1; +} + +static int +ngx_http_lua_socket_tcp_bind_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L) +{ + + lua_createtable(L, 5 /* narr */, 1 /* nrec */); + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + tcp_server_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); + + lua_pushvalue(L, -2); + // set ctx + lua_rawseti(L, -2, SOCKET_CTX_INDEX); + + return 1; +} + +static int +ngx_http_lua_socket_tcp_listen_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L) +{ + + lua_createtable(L, 5 /* narr */, 1 /* nrec */); + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + tcp_server_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); + + lua_pushvalue(L, -2); + // set ctx + lua_rawseti(L, -2, SOCKET_CTX_INDEX); + + return 1; +} + +static int +ngx_http_lua_socket_tcp_server_close(lua_State *L) +{ + ngx_http_request_t *r; + ngx_http_lua_socket_tcp_server_t *s; + + if (lua_gettop(L) != 1) { + return luaL_error(L, "expecting 1 argument " + "(including the object) but seen %d", lua_gettop(L)); + } + + r = ngx_http_lua_get_req(L); + if (r == NULL) { + return luaL_error(L, "no request found"); + } + + luaL_checktype(L, 1, LUA_TTABLE); + + lua_rawgeti(L, 1, SOCKET_CTX_INDEX); + s = lua_touserdata(L, -1); + lua_pop(L, 1); + + if (s == NULL + || s->listening == NULL) + { + lua_pushnil(L); + lua_pushliteral(L, "closed"); + return 2; + } + + if (s->request != r) { + return luaL_error(L, "bad request"); + } + + ngx_http_lua_socket_check_busy_accepting(r, s, L); + + ngx_http_lua_socket_tcp_server_finalize(r, s); + + lua_pushinteger(L, 1); + return 1; +} + + +static void +ngx_http_lua_socket_accept_handler(ngx_connection_t *c) +{ + ngx_listening_t *ls; + ngx_http_lua_socket_tcp_server_t *s; + ngx_http_request_t *r; + ngx_connection_t *ac; + ngx_event_t *rev; + ngx_http_lua_loc_conf_t *llcf; + + dd("accepted connection"); + + ls = c->listening; + s = ls->servers; + r = s->request; + + s->connection = c; + + ac = ls->connection; + rev = ac->read; + + if (ac->read->timedout) { + ac->read->timedout = 0; + + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); + + if (llcf->log_socket_errors) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "lua tcp socket read timed out"); + } + + ngx_http_lua_socket_handle_accept_error(r, s, + NGX_HTTP_LUA_SOCKET_FT_TIMEOUT); + return; + } + + if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "error while deleting read event"); + } + + ngx_http_lua_socket_handle_accept_success(r, s); +} + +static void +ngx_http_lua_socket_handle_accept_success(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s) +{ + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_co_ctx_t *coctx; + + if (s->accept_waiting) { + s->accept_waiting = 0; + + coctx = s->co_ctx; + coctx->cleanup = NULL; + s->co_ctx = NULL; + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return; + } + + ctx->resume_handler = ngx_http_lua_socket_tcp_accept_resume; + ctx->cur_co_ctx = coctx; + + ngx_http_lua_assert(coctx && (!ngx_http_lua_is_thread(ctx) + || coctx->co_ref >= 0)); + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket waking up the current request (conn)"); + r->write_event_handler(r); + } +} + + +static void +ngx_http_lua_socket_handle_accept_error(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, ngx_uint_t ft_type) +{ + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_co_ctx_t *coctx; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket handle accept error"); + + s->ft_type |= ft_type; + +#if 1 + ngx_http_lua_socket_tcp_server_finalize(r, s); +#endif + + if (s->accept_waiting) { + s->accept_waiting = 0; + + coctx = s->co_ctx; + coctx->cleanup = NULL; + s->co_ctx = NULL; + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return; + } + + ctx->resume_handler = ngx_http_lua_socket_tcp_accept_resume; + ctx->cur_co_ctx = coctx; + + ngx_http_lua_assert(coctx && (!ngx_http_lua_is_thread(ctx) + || coctx->co_ref >= 0)); + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket waking up the current request (conn)"); + r->write_event_handler(r); + } +} + +static void +ngx_http_lua_socket_tcp_server_cleanup(void *data) +{ + ngx_http_lua_socket_tcp_server_t *s = data; + + ngx_http_request_t *r; + + r = s->request; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "cleanup lua tcp server socket request: \"%V\"", &r->uri); + + ngx_http_lua_socket_tcp_server_finalize(r, s); +} + +static void +ngx_http_lua_socket_tcp_server_finalize(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s) +{ + ngx_connection_t *c; + ngx_listening_t *ls; + + dd("request: %p, s: %p, s->cleanup: %p", r, s, s->cleanup); + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua finalize socket"); + + if (s->cleanup) { + *s->cleanup = NULL; + ngx_http_lua_cleanup_free(r, s->cleanup); + s->cleanup = NULL; + } + + ls = s->listening; + c = ls->connection; + + if (c) { + if (c->read->active) { + if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { + + /* + * it seems that Linux-2.6.x OpenVZ sends events + * for closed shared listening sockets unless + * the events was explicitly deleted + */ + + ngx_del_event(c->read, NGX_READ_EVENT, 0); + + } else { + ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); + } + } + + ngx_free_connection(c); + + c->fd = (ngx_socket_t) -1; + } + + ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "close listening %V #%d ", &ls->addr_text, ls->fd); + + if (ngx_close_socket(ls->fd) == -1) { + ngx_log_error(NGX_LOG_EMERG, r->connection->log, ngx_socket_errno, + ngx_close_socket_n " %V failed", &ls->addr_text); + } + +#if (NGX_HAVE_UNIX_DOMAIN) + + if (ls->sockaddr->sa_family == AF_UNIX + && ngx_process <= NGX_PROCESS_MASTER + && ngx_new_binary == 0) + { + u_char *name = ls->addr_text.data + sizeof("unix:") - 1; + + if (ngx_delete_file(name) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, r->connection->log, + ngx_socket_errno, ngx_delete_file_n " %s failed", name); + } + } + +#endif + + ls->fd = (ngx_socket_t) -1; +} + + +static int +ngx_http_lua_socket_tcp_server_destroy(lua_State *L) +{ + ngx_http_lua_socket_tcp_server_t *s; + + dd("server destroy triggered by Lua GC"); + + s = lua_touserdata(L, 1); + if (s == NULL) { + return 0; + } + + if (s->cleanup) { + /* it will clear s->cleanup */ + ngx_http_lua_socket_tcp_server_cleanup(s); + } + + return 0; +} + +static ngx_int_t +ngx_http_lua_socket_tcp_accept_resume(ngx_http_request_t *r) +{ + dd("accept resume"); + return ngx_http_lua_socket_tcp_resume_helper(r, SOCKET_OP_ACCEPT); +} + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/ngx_http_lua_socket_tcp.h b/src/ngx_http_lua_socket_tcp.h index dbdee41c6e..766e4e4574 100644 --- a/src/ngx_http_lua_socket_tcp.h +++ b/src/ngx_http_lua_socket_tcp.h @@ -22,6 +22,9 @@ #define NGX_HTTP_LUA_SOCKET_FT_SSL 0x0100 +typedef struct ngx_http_lua_socket_tcp_server_s + ngx_http_lua_socket_tcp_server_t; + typedef struct ngx_http_lua_socket_tcp_upstream_s ngx_http_lua_socket_tcp_upstream_t; @@ -30,6 +33,10 @@ typedef int (*ngx_http_lua_socket_tcp_retval_handler)(ngx_http_request_t *r, ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); +typedef + int (*ngx_http_lua_socket_tcp_server_retval_handler)(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_server_t *s, lua_State *L); + typedef void (*ngx_http_lua_socket_tcp_upstream_handler_pt) (ngx_http_request_t *r, ngx_http_lua_socket_tcp_upstream_t *u); @@ -50,6 +57,21 @@ typedef struct { } ngx_http_lua_socket_pool_t; +struct ngx_http_lua_socket_tcp_server_s { + ngx_http_lua_socket_tcp_server_retval_handler prepare_retvals; + + ngx_str_t host; + int port; + ngx_listening_t *listening; + ngx_http_request_t *request; + ngx_connection_t *connection; + ngx_http_cleanup_pt *cleanup; + + ngx_http_lua_co_ctx_t *co_ctx; + + unsigned ft_type:16; + unsigned accept_waiting:1; +}; struct ngx_http_lua_socket_tcp_upstream_s { ngx_http_lua_socket_tcp_retval_handler read_prepare_retvals; From fe9f7018b3da2937b55aa0fd67f25a6867fd0b0c Mon Sep 17 00:00:00 2001 From: harijvs6 Date: Mon, 21 Sep 2020 01:35:04 +0530 Subject: [PATCH 2/4] fixed indentation errors --- src/ngx_http_lua_socket_tcp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ngx_http_lua_socket_tcp.c b/src/ngx_http_lua_socket_tcp.c index 5eb2801c0c..0acebf06cb 100644 --- a/src/ngx_http_lua_socket_tcp.c +++ b/src/ngx_http_lua_socket_tcp.c @@ -6307,7 +6307,7 @@ ngx_http_lua_socket_tcp_bind(lua_State *L) #if 1 lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( - server_udata_metatable_key)); + server_udata_metatable_key)); lua_rawget(L, LUA_REGISTRYINDEX); lua_setmetatable(L, -2); #endif @@ -6817,7 +6817,7 @@ ngx_http_lua_socket_tcp_master_listen(lua_State *L) #if 1 lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( - server_udata_metatable_key)); + server_udata_metatable_key)); lua_rawget(L, LUA_REGISTRYINDEX); lua_setmetatable(L, -2); #endif @@ -7138,7 +7138,7 @@ ngx_http_lua_socket_tcp_accept_retval_handler(ngx_http_request_t *r, #if 1 lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( - upstream_udata_metatable_key)); + upstream_udata_metatable_key)); lua_rawget(L, LUA_REGISTRYINDEX); lua_setmetatable(L, -2); #endif @@ -7456,7 +7456,7 @@ ngx_http_lua_socket_tcp_server_finalize(ngx_http_request_t *r, if (ngx_delete_file(name) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, r->connection->log, - ngx_socket_errno, ngx_delete_file_n " %s failed", name); + ngx_socket_errno, ngx_delete_file_n " %s failed", name); } } @@ -7479,7 +7479,7 @@ ngx_http_lua_socket_tcp_server_destroy(lua_State *L) } if (s->cleanup) { - /* it will clear s->cleanup */ + /* it will clear s->cleanup */ ngx_http_lua_socket_tcp_server_cleanup(s); } From 589cd4de0440967abcff6235a966f124fbaa4f35 Mon Sep 17 00:00:00 2001 From: harijvs6 Date: Wed, 23 Sep 2020 00:47:52 +0530 Subject: [PATCH 3/4] fix to make it compatible with nginx 1.17 --- src/ngx_http_lua_socket_tcp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ngx_http_lua_socket_tcp.c b/src/ngx_http_lua_socket_tcp.c index 0acebf06cb..fba8d12371 100644 --- a/src/ngx_http_lua_socket_tcp.c +++ b/src/ngx_http_lua_socket_tcp.c @@ -6936,8 +6936,9 @@ ngx_http_lua_socket_init_listening(ngx_http_request_t *r, ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t)); - ngx_memcpy(&lsopt.sockaddr.sockaddr, &u.sockaddr, u.socklen); - + lsopt.sockaddr = u.addrs[0].sockaddr; + lsopt.socklen = u.addrs[0].socklen; + lsopt.addr_text = u.addrs[0].name; lsopt.socklen = u.socklen; lsopt.backlog = NGX_LISTEN_BACKLOG; lsopt.rcvbuf = -1; @@ -6953,9 +6954,6 @@ ngx_http_lua_socket_init_listening(ngx_http_request_t *r, lsopt.ipv6only = 1; #endif - (void) ngx_sock_ntop(&lsopt.sockaddr.sockaddr, lsopt.socklen, lsopt.addr, - NGX_SOCKADDR_STRLEN, 1); - lsopt.set = 1; lsopt.bind = 1; lsopt.reuseport = 1; @@ -6977,12 +6975,12 @@ ngx_http_lua_socket_init_listening(ngx_http_request_t *r, addr->default_server = NULL; addr->servers.elts = NULL; - ls = ngx_http_lua_socket_create_listening(r, &addr->opt.sockaddr.sockaddr, + ls = ngx_http_lua_socket_create_listening(r, addr->opt.sockaddr, addr->opt.socklen); if (ls == NULL) { return NULL; } - + ls->addr_ntop = 1; ls->handler = ngx_http_lua_socket_accept_handler; From 242d003330590883305d36ffbf5c88e079d7405b Mon Sep 17 00:00:00 2001 From: harijvs6 Date: Wed, 23 Sep 2020 22:58:46 +0530 Subject: [PATCH 4/4] fix test cases --- t/062-count.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/062-count.t b/t/062-count.t index 841923b86d..a08ec5bfb8 100644 --- a/t/062-count.t +++ b/t/062-count.t @@ -459,7 +459,7 @@ worker: 4 --- request GET /test --- response_body -n = 13 +n = 15 --- no_error_log [error]