ngx_int_t ngx_stream_lua_send_chain_link(ngx_stream_session_t *s, ngx_stream_lua_ctx_t *ctx, ngx_chain_t *in) { ngx_int_t rc; #if 0 if (ctx->acquired_raw_req_socket || (in && ctx->eof)) { dd("ctx->eof already set or raw req socket already acquired"); return NGX_OK; } #endif rc = ngx_chain_writer(&ctx->out_writer, in); if (rc == NGX_ERROR) { s->connection->error = 1; } ngx_chain_update_chains(s->connection->pool, &ctx->free_bufs, &ctx->downstream_busy_bufs, &in, (ngx_buf_tag_t) &ngx_stream_lua_module); ngx_stream_lua_assert(rc != NGX_AGAIN || ctx->downstream_busy_bufs); return rc; }
static void ngx_stream_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_stream_session_t *s; ngx_connection_t *c; ngx_stream_lua_resolved_t *ur; ngx_stream_lua_ctx_t *lctx; lua_State *L; u_char *p; size_t len; #if defined(nginx_version) && nginx_version >= 1005008 socklen_t socklen; struct sockaddr *sockaddr; #else struct sockaddr_in *sin; #endif ngx_uint_t i; unsigned waiting; ngx_stream_lua_socket_udp_upstream_t *u; u = ctx->data; s = u->session; c = s->connection; ur = u->resolved; ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "stream lua udp socket resolve handler"); lctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module); if (lctx == NULL) { return; } lctx->cur_co_ctx = u->co_ctx; u->co_ctx->cleanup = NULL; L = lctx->cur_co_ctx->co; dd("setting socket_ready to 1"); waiting = u->waiting; if (ctx->state) { ngx_log_debug2(NGX_LOG_DEBUG_STREAM, c->log, 0, "stream lua udp socket resolver error: %s (waiting: %d)", ngx_resolver_strerror(ctx->state), (int) u->waiting); lua_pushnil(L); lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len); lua_pushfstring(L, " could not be resolved (%d: %s)", (int) ctx->state, ngx_resolver_strerror(ctx->state)); lua_concat(L, 2); #if 1 ngx_resolve_name_done(ctx); ur->ctx = NULL; #endif u->prepare_retvals = ngx_stream_lua_socket_error_retval_handler; ngx_stream_lua_socket_udp_handle_error(s, u, NGX_STREAM_LUA_SOCKET_FT_RESOLVER); return; } ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { # if defined(nginx_version) && nginx_version >= 1005008 u_char text[NGX_SOCKADDR_STRLEN]; ngx_str_t addr; # else in_addr_t addr; # endif ngx_uint_t i; # if defined(nginx_version) && nginx_version >= 1005008 addr.data = text; for (i = 0; i < ctx->naddrs; i++) { addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen, text, NGX_SOCKADDR_STRLEN, 0); ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, "name was resolved to %V", &addr); } # else for (i = 0; i < ctx->naddrs; i++) { dd("addr i: %d %p", (int) i, &ctx->addrs[i]); addr = ntohl(ctx->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_STREAM, c->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } # endif } #endif ngx_stream_lua_assert(ur->naddrs > 0); if (ur->naddrs == 1) { i = 0; } else { i = ngx_random() % ur->naddrs; } dd("selected addr index: %d", (int) i); #if defined(nginx_version) && nginx_version >= 1005008 socklen = ur->addrs[i].socklen; sockaddr = ngx_palloc(s->connection->pool, socklen); if (sockaddr == NULL) { goto nomem; } ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); switch (sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port); break; #endif default: /* AF_INET */ ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port); } p = ngx_pnalloc(s->connection->pool, NGX_SOCKADDR_STRLEN); if (p == NULL) { goto nomem; } len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); ur->sockaddr = sockaddr; ur->socklen = socklen; #else /* for nginx older than 1.5.8 */ len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(s->pool, len + sizeof(struct sockaddr_in)); if (p == NULL) { goto nomem; } sin = (struct sockaddr_in *) &p[len]; ngx_memzero(sin, sizeof(struct sockaddr_in)); len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; ur->sockaddr = (struct sockaddr *) sin; ur->socklen = sizeof(struct sockaddr_in); #endif ur->host.data = p; ur->host.len = len; ur->naddrs = 1; ngx_resolve_name_done(ctx); ur->ctx = NULL; u->waiting = 0; if (waiting) { lctx->resume_handler = ngx_stream_lua_socket_udp_resume; lctx->write_event_handler(s, lctx); } else { (void) ngx_stream_lua_socket_resolve_retval_handler(s, u, L); } return; nomem: if (ur->ctx) { ngx_resolve_name_done(ctx); ur->ctx = NULL; } u->prepare_retvals = ngx_stream_lua_socket_error_retval_handler; ngx_stream_lua_socket_udp_handle_error(s, u, NGX_STREAM_LUA_SOCKET_FT_NOMEM); if (!waiting) { lua_pushnil(L); lua_pushliteral(L, "no memory"); } }