static void ngx_mail_auth_http_read_handler(ngx_event_t *rev) { ssize_t n, size; ngx_connection_t *c; ngx_mail_session_t *s; ngx_mail_auth_http_ctx_t *ctx; c = rev->data; s = c->data; ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth http read handler"); ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); if (rev->timedout) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, "auth http server %V timed out", ctx->peer.name); ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); return; } if (ctx->response == NULL) { ctx->response = ngx_create_temp_buf(ctx->pool, 1024); if (ctx->response == NULL) { ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); return; } } size = ctx->response->end - ctx->response->last; n = ngx_recv(c, ctx->response->pos, size); if (n > 0) { ctx->response->last += n; ctx->handler(s, ctx); return; } if (n == NGX_AGAIN) { return; } ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); }
static ngx_int_t ngx_imap_proxy_read_response(ngx_imap_session_t *s) { u_char *p; ssize_t n; ngx_buf_t *b; b = s->proxy->buffer; n = ngx_recv(s->proxy->upstream.connection, b->last, b->end - b->last); if (n == NGX_ERROR || n == 0) { return NGX_ERROR; } if (n == NGX_AGAIN) { return NGX_AGAIN; } b->last += n; if (b->last - b->pos < 5) { return NGX_AGAIN; } if (*(b->last - 2) != CR || *(b->last - 1) != LF) { if (b->last == b->end) { *(b->last - 1) = '\0'; ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "upstream sent too long response line: \"%s\"", b->pos); return NGX_IMAP_PROXY_INVALID; } return NGX_AGAIN; } p = b->pos; if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') { return NGX_OK; } if (p[0] == '-' && p[1] == 'E' && p[2] == 'R' && p[3] == 'R') { return NGX_IMAP_PROXY_ERROR; } *(b->last - 2) = '\0'; ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "upstream sent invalid greeting line: \"%s\"", p); return NGX_IMAP_PROXY_INVALID; }
int ngx_http_clojure_socket_upstream_read(ngx_http_clojure_socket_upstream_t *u, void *buf, size_t size) { ngx_connection_t *c = u->peer.connection; ngx_int_t rc = ngx_recv(c, buf, size); if (rc == NGX_AGAIN) { if (u->read_timeout > 0) { ngx_add_timer(c->read, u->read_timeout); } rc = NGX_HTTP_CLOJURE_SOCKET_ERR_AGAIN; }else if (rc < 0) { rc = NGX_HTTP_CLOJURE_SOCKET_ERR_READ; } return rc; }
static void ngx_mysql_read_query_result(ngx_event_t *rev) { ssize_t n, len; ngx_str_t msg; ngx_mysql_t *m; ngx_connection_t *c; ngx_mysql_error_pkt_t *epkt; ngx_mysql_response_pkt_t *pkt; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql read query result"); c = rev->data; m = c->data; m->peer.log->action = "reading mysql read query result"; n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024); if (n == NGX_AGAIN) { return; } if (n < 5) { ngx_mysql_close(m, NGX_ERROR); return; } pkt = (ngx_mysql_response_pkt_t *) m->buf->pos; len = ngx_m24toh(pkt->pktlen); if (len > n - 4) { ngx_log_error(NGX_LOG_ERR, rev->log, 0, "mysql server %V sent incomplete response packet", m->peer.name); ngx_mysql_close(m, NGX_ERROR); return; } if (pkt->fields != 0xff) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql query OK"); m->state = NGX_OK; m->pktn = pkt->pktn; m->handler(m); return; } epkt = (ngx_mysql_error_pkt_t *) pkt; msg.len = (u_char *) epkt + 4 + len - epkt->message; msg.data = epkt->message; ngx_log_error(NGX_LOG_ERR, rev->log, 0, "mysql server %V sent error (%ud): \"%V\"", m->peer.name, ngx_m16toh(epkt->code), &msg); ngx_mysql_close(m, NGX_ERROR); }
static void ngx_ssl_ocsp_read_handler(ngx_event_t *rev) { ssize_t n, size; ngx_int_t rc; ngx_ssl_ocsp_ctx_t *ctx; ngx_connection_t *c; 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_lua_smtp_read_handler(ngx_event_t *rev) { ssize_t n; ngx_int_t rc; ngx_buf_t *b; ngx_connection_t *c; ngx_lua_smtp_ctx_t *ctx; ngx_log_debug0(NGX_LOG_DEBUG_CORE, rev->log, 0, "lua smtp read handler"); c = rev->data; ctx = c->data; if (rev->timedout) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, "lua smtp read %V timed out", ctx->peer.name); ngx_lua_smtp_finalize(ctx, "ngx_lua_smtp_read_handler() timed out"); return; } if (rev->timer_set) { ngx_del_timer(rev); } b = ctx->response; while (1) { n = ngx_recv(c, b->last, b->end - b->last); if (n > 0) { b->last += n; rc = ngx_lua_smtp_handle_response(ctx); if (rc == NGX_OK) { return; } if (rc == NGX_AGAIN) { continue; } if (rc == NGX_DONE) { ngx_lua_smtp_finalize(ctx, NULL); return; } /* rc == NGX_ERROR */ ngx_lua_smtp_finalize(ctx, "ngx_lua_smtp_handle_response() failed"); return; } if (n == NGX_AGAIN) { ngx_add_timer(rev, ctx->read_timeout); ctx->rc = NGX_AGAIN; return; } /* n == NGX_ERROR || n == 0 */ ngx_lua_smtp_finalize(ctx, "ngx_recv() failed"); return; } }
static void ngx_http_cloudrouter_peer_preconnect_read(ngx_event_t *rev) { ngx_connection_t *c; ngx_http_cloudrouter_peer_preconnect_data_t *pcd; ngx_http_upstream_t *u; ngx_http_request_t *r; int i; hs_route_t *route; c = rev->data; pcd = c->data; r = pcd->r; u = pcd->u; route = &pcd->route; ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "preconnect: read"); if (pcd->done>0) { return; } if (r->main==NULL||r->request_complete||r->pool==NULL||r!=r->main) { ngx_close_connection(c); c->destroyed = 1; return; } if (rev->timedout) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, "cloudrouter preconnect server timed out"); return ngx_http_cloudrouter_peer_preconnect_close(c, pcd, NGX_ERROR); } if (pcd->buf==NULL) { int size = sizeof(char)*1000; ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "creating buf"); pcd->buf = ngx_pcalloc(r->pool, size); pcd->bufend = pcd->buf+size; pcd->bufpos = pcd->buf; if (pcd->buf==NULL) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ENOMEM, "preconnect: read: could not allocate buf"); return ngx_http_cloudrouter_peer_preconnect_close(c, pcd, NGX_ERROR); } } /* * Protocol format: * IP1\nPORT1\n * (optional) IPz\nPORTz\n * -- */ int bufsize = pcd->bufend - pcd->bufpos; ngx_int_t received; if (bufsize > 0) { received = ngx_recv(c, pcd->bufpos, bufsize); } else { received = 0; } if (received==NGX_AGAIN) { return; } else if (received>=0) { pcd->bufpos += received; for (i=0;i<(pcd->bufpos-pcd->buf);i++) { if (*(pcd->buf + i )=='-') { pcd->end_marker_count++; } } if (pcd->end_marker_count>=2) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "CloudRouter preconnect: message complete"); ngx_http_cloudrouter_peer_t *peer = (ngx_http_cloudrouter_peer_t *)u->peer.data; unsigned char* next = pcd->buf; int new_node = 0; ngx_shmtx_lock(&ngx_http_cloudrouter_shpool->mutex); ngx_http_cloudrouter_node_t *e = ngx_http_cloudrouter_get_locked(route); if (e == NULL) { /* likely() */ e = ngx_slab_alloc_locked(ngx_http_cloudrouter_shpool, sizeof *e); new_node = 1; e->node.key = ngx_http_cloudrouter_hash_route(route); (void)ngx_copy(e->di_name, route->di_name, sizeof(route->di_name)); e->di_nlen = route->di_nlen; } else { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "CloudRouter preconnect: reusing existing node"); } e->timestamp = time(NULL); ngx_http_cloudrouter_clear_remotes_locked(e, rev->log); while (next < pcd->bufpos) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "CloudRouter preconnect: parsing message"); unsigned char *ip = NULL; unsigned char *port = NULL; ip = next; while (++next < pcd->bufpos) { if (*(next-1) == '\n') { if (ip && port) break; port = next; } } if (ip && port) { ngx_http_cloudrouter_remote_t *remote = ngx_http_cloudrouter_add_remote_locked(e); int iplen = port-ip-1; iplen = iplen > 16 ? 16 : iplen; remote->inet_addr = ngx_inet_addr(ip, iplen); if (remote->inet_addr == INADDR_NONE) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_EINVAL, "CloudRouter preconnect: IP address from Agent invalid for route %s", e->di_name); goto failure; } int portlen = next-port-1; remote->port_n = htons(ngx_atoi(port,portlen)); ngx_log_debug7(NGX_LOG_DEBUG_HTTP, rev->log, 0, "CloudRouter preconnect: cached values SET: e=%p rem=%p ts=%d %s[%d] %uxD:%d", e, remote, e->timestamp, e->di_name, e->di_nlen, remote->inet_addr, remote->port_n); } } if (!e->remote) { ngx_log_debug(NGX_LOG_DEBUG_HTTP, rev->log, 0, "CloudRouter preconnect: Agent sent no remotes"); goto failure; } ngx_http_cloudrouter_set_hostandport(r, peer, e); if (new_node) { ngx_rbtree_insert(ngx_http_cloudrouter_rbtree, &e->node); } ngx_shmtx_unlock(&ngx_http_cloudrouter_shpool->mutex); return ngx_http_cloudrouter_peer_preconnect_close(c, pcd, NGX_OK); failure: if (!new_node) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pcd->r->connection->log, 0, "peer_preconnect_read: calling rbtree_delete"); ngx_rbtree_delete(ngx_http_cloudrouter_rbtree, &e->node); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pcd->r->connection->log, 0, "peer_preconnect_read: calling free_node_locked"); ngx_http_cloudrouter_free_node_locked(e, rev->log); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pcd->r->connection->log, 0, "peer_preconnect_read: calling shmtx_unlock"); ngx_shmtx_unlock(&ngx_http_cloudrouter_shpool->mutex); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pcd->r->connection->log, 0, "peer_preconnect_read: calling peer_preconnect_close"); return ngx_http_cloudrouter_peer_preconnect_close(c, pcd, NGX_ERROR); } return; } /* unknown error condition from ngx_recv */ return; }
static void ngx_mysql_read_server_greeting(ngx_event_t *rev) { size_t len; u_char *p; ssize_t n; ngx_uint_t i, capacity; ngx_mysql_t *m; ngx_connection_t *c; ngx_mysql_greeting1_pkt_t *gr1; ngx_mysql_greeting2_pkt_t *gr2; ngx_mysql_auth_pkt_t *auth; ngx_sha1_t sha; u_char hash1[20], hash2[20]; c = rev->data; m = c->data; if (rev->timedout) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, "mysql server %V timed out", m->peer.name); ngx_mysql_close(m, NGX_ERROR); return; } if (m->buf == NULL) { m->peer.log->action = "reading mysql server greeting"; m->buf = ngx_create_temp_buf(m->pool, /* STUB */ 1024); if (m->buf == NULL) { ngx_mysql_close(m, NGX_ERROR); return; } } n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024); if (n == NGX_AGAIN) { return; } if (n < 5) { ngx_mysql_close(m, NGX_ERROR); return; } gr1 = (ngx_mysql_greeting1_pkt_t *) m->buf->pos; if (ngx_m24toh(gr1->pktlen) > n - 4) { ngx_log_error(NGX_LOG_ERR, rev->log, 0, "mysql server %V sent incomplete greeting packet", m->peer.name); ngx_mysql_close(m, NGX_ERROR); return; } if (gr1->protocol < 10) { ngx_log_error(NGX_LOG_ERR, rev->log, 0, "mysql server %V sent unsupported protocol version %ud", m->peer.name, gr1->protocol); ngx_mysql_close(m, NGX_ERROR); return; } gr2 = (ngx_mysql_greeting2_pkt_t *) (gr1->version + ngx_strlen(gr1->version) + 1); capacity = ngx_m16toh(gr2->capacity); ngx_log_debug8(NGX_LOG_DEBUG_MYSQL, rev->log, 0, "mysql version: %ud, \"%s\", thread: %ud, salt: \"%s\", " "capacity: %Xd, charset: %ud, status: %ud, salt rest \"%s\"", gr1->protocol, gr1->version, ngx_m32toh(gr2->thread), gr2->salt1, capacity, gr2->charset, ngx_m16toh(gr2->status), &gr2->salt2); capacity = NGX_MYSQL_LONG_PASSWORD | NGX_MYSQL_CONNECT_WITH_DB | NGX_MYSQL_PROTOCOL_41 | NGX_MYSQL_SECURE_CONNECTION; len = 4 + 4 + 4 + 1 + 23 + m->login->len + 1 + 1 + m->database->len + 1; if (m->passwd->len) { len += 20; } auth = ngx_pnalloc(m->pool, len); if (auth == NULL) { ngx_mysql_close(m, NGX_ERROR); return; } ngx_htom24(auth->pktlen, len - 4); auth->pktn = (u_char)(gr1->pktn + 1); ngx_htom32(auth->capacity, capacity); ngx_htom32(auth->max_packet, 0x01000000); /* max packet size 2^24 */ ngx_memzero(auth->zero, 24); auth->charset = gr2->charset; p = ngx_copy(auth->login, m->login->data, m->login->len); *p++ = '\0'; if (m->passwd->len) { *p++ = (u_char) 20; ngx_sha1_init(&sha); ngx_sha1_update(&sha, m->passwd->data, m->passwd->len); ngx_sha1_final(hash1, &sha); ngx_sha1_init(&sha); ngx_sha1_update(&sha, hash1, 20); ngx_sha1_final(hash2, &sha); ngx_sha1_init(&sha); ngx_sha1_update(&sha, gr2->salt1, 8); ngx_sha1_update(&sha, gr2->salt2, 12); ngx_sha1_update(&sha, hash2, 20); ngx_sha1_final(hash2, &sha); for (i = 0; i < 20; i++) { *p++ = (u_char)(hash1[i] ^ hash2[i]); } } else { *p++ = '\0'; } p = ngx_copy(p, m->database->data, m->database->len); *p = '\0'; n = ngx_send(m->peer.connection, (void *) auth, len); if (n < (ssize_t) len) { ngx_log_error(NGX_LOG_ERR, rev->log, 0, "the incomplete packet was sent to mysql server %V", m->peer.name); ngx_mysql_close(m, NGX_ERROR); return; } m->peer.connection->read->handler = ngx_mysql_read_auth_result; ngx_add_timer(m->peer.connection->read, /* STUB */ 5000); }
static void ngx_squ_tcp_request_read_handler(ngx_event_t *rev) { char *errstr; ssize_t n; ngx_int_t rc; ngx_buf_t *b; ngx_connection_t *c; ngx_squ_thread_t *thr; ngx_squ_tcp_ctx_t *ctx; ngx_tcp_session_t *s; ngx_log_debug0(NGX_LOG_DEBUG_CORE, rev->log, 0, "squ tcp request read handler"); c = rev->data; s = c->data; thr = ngx_tcp_get_module_ctx(s, ngx_squ_tcp_module); ctx = thr->module_ctx; b = s->buffer; errstr = NULL; if (rev->timedout) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, "squ tcp request read %V timed out", &c->addr_text); errstr = "ngx_squ_tcp_request_read_handler() timed out"; n = NGX_ERROR; goto done; } if (rev->timer_set) { ngx_del_timer(rev); } while (1) { n = ngx_recv(c, b->last, b->end - b->last); if (n > 0) { b->last += n; break; } if (n == NGX_AGAIN) { /* TODO */ ngx_add_timer(rev, 60000); if (ngx_handle_read_event(rev, 0) != NGX_OK) { errstr = "ngx_handle_read_event() failed"; n = NGX_ERROR; goto done; } ctx->rc = NGX_AGAIN; return; } /* n == NGX_ERROR || n == 0 */ break; } done: rev->handler = ngx_squ_tcp_request_dummy_handler; ctx->rc = 1; if (n > 0) { sq_pushstring(thr->v, (SQChar *) b->pos, n); } else { sq_pushbool(thr->v, SQFalse); #if 0 if (errstr != NULL) { sq_pushstring(thr->v, errstr, -1); ctx->rc++; } #endif } if (ctx->not_event) { return; } rc = ngx_squ_thread_run(thr, ctx->rc); if (rc == NGX_AGAIN) { return; } ngx_squ_finalize(thr, rc); }
static void ngx_imap_proxy_handler(ngx_event_t *ev) { size_t size; ssize_t n; ngx_buf_t *b; ngx_uint_t again, do_write; ngx_connection_t *c, *src, *dst; ngx_imap_session_t *s; c = ev->data; s = c->data; if (ev->timedout) { if (c == s->connection) { ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); } else { ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "upstream timed out"); } ngx_imap_proxy_close_session(s); return; } if (c == s->connection) { if (ev->write) { src = s->proxy->upstream.connection; dst = c; b = s->proxy->buffer; } else { src = c; dst = s->proxy->upstream.connection; b = s->buffer; } } else { if (ev->write) { src = s->connection; dst = c; b = s->buffer; } else { src = c; dst = s->connection; b = s->proxy->buffer; } } do_write = ev->write ? 1 : 0; ngx_log_debug3(NGX_LOG_DEBUG_IMAP, ev->log, 0, "imap proxy handler: %d, #%d > #%d", do_write, src->fd, dst->fd); do { again = 0; if (do_write == 1) { size = b->last - b->pos; if (size && dst->write->ready) { n = ngx_send(dst, b->pos, size); if (n == NGX_ERROR) { ngx_imap_proxy_close_session(s); return; } if (n > 0) { again = 1; b->pos += n; if (b->pos == b->last) { b->pos = b->start; b->last = b->start; } } if (n == NGX_AGAIN || n < (ssize_t) size) { dst->write->available = 0; if (ngx_handle_write_event(dst->write, NGX_LOWAT_EVENT) == NGX_ERROR) { ngx_imap_proxy_close_session(s); return; } } } } size = b->end - b->last; if (size && src->read->ready) { n = ngx_recv(src, b->last, size); if (n == NGX_ERROR || n == 0) { ngx_imap_proxy_close_session(s); return; } if (n > 0) { again = 1; do_write = 1; b->last += n; } if (n == NGX_AGAIN || n < (ssize_t) size) { if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) { ngx_imap_proxy_close_session(s); return; } } } } while (again); }