Example #1
0
static void
ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
{
    u_char                       *p;
    ngx_connection_t             *c, *pc;
    ngx_log_handler_pt            handler;
    ngx_stream_upstream_t        *u;
    ngx_stream_proxy_srv_conf_t  *pscf;

    u = s->upstream;

    if (u->proxy_protocol) {
        if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
            return;
        }

        u->proxy_protocol = 0;
    }

    pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

    pc = u->peer.connection;

#if (NGX_STREAM_SSL)
    if (pscf->ssl && pc->ssl == NULL) {
        ngx_stream_proxy_ssl_init_connection(s);
        return;
    }
#endif

    c = s->connection;

    if (c->log->log_level >= NGX_LOG_INFO) {
        ngx_str_t  s;
        u_char     addr[NGX_SOCKADDR_STRLEN];

        s.len = NGX_SOCKADDR_STRLEN;
        s.data = addr;

        if (ngx_connection_local_sockaddr(pc, &s, 1) == NGX_OK) {
            handler = c->log->handler;
            c->log->handler = NULL;

            ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxy %V connected to %V",
                          &s, u->peer.name);

            c->log->handler = handler;
        }
    }

    c->log->action = "proxying connection";

    p = ngx_pnalloc(c->pool, pscf->buffer_size);
    if (p == NULL) {
        ngx_stream_proxy_finalize(s, NGX_ERROR);
        return;
    }

    u->upstream_buf.start = p;
    u->upstream_buf.end = p + pscf->buffer_size;
    u->upstream_buf.pos = p;
    u->upstream_buf.last = p;

    u->connected = 1;

    pc->read->handler = ngx_stream_proxy_upstream_handler;
    pc->write->handler = ngx_stream_proxy_upstream_handler;

    if (ngx_stream_proxy_process(s, 1, 0) != NGX_OK) {
        return;
    }

    ngx_stream_proxy_process(s, 0, 1);
}
static void
ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
{
    int                           tcp_nodelay;
    u_char                       *p;
    ngx_connection_t             *c, *pc;
    ngx_log_handler_pt            handler;
    ngx_stream_upstream_t        *u;
    ngx_stream_core_srv_conf_t   *cscf;
    ngx_stream_proxy_srv_conf_t  *pscf;

    u = s->upstream;
    pc = u->peer.connection;

    cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

    if (pc->type == SOCK_STREAM
        && cscf->tcp_nodelay
        && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
    {
        ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay");

        tcp_nodelay = 1;

        if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY,
                       (const void *) &tcp_nodelay, sizeof(int)) == -1)
        {
            ngx_connection_error(pc, ngx_socket_errno,
                                 "setsockopt(TCP_NODELAY) failed");
            ngx_stream_proxy_next_upstream(s);
            return;
        }

        pc->tcp_nodelay = NGX_TCP_NODELAY_SET;
    }

    if (u->proxy_protocol) {
        if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
            return;
        }

        u->proxy_protocol = 0;
    }

    pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

#if (NGX_STREAM_SSL)
    if (pc->type == SOCK_STREAM && pscf->ssl && pc->ssl == NULL) {
        ngx_stream_proxy_ssl_init_connection(s);
        return;
    }
#endif

    c = s->connection;

    if (c->log->log_level >= NGX_LOG_INFO) {
        ngx_str_t  str;
        u_char     addr[NGX_SOCKADDR_STRLEN];

        str.len = NGX_SOCKADDR_STRLEN;
        str.data = addr;

        if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
            handler = c->log->handler;
            c->log->handler = NULL;

            ngx_log_error(NGX_LOG_INFO, c->log, 0,
                          "%sproxy %V connected to %V",
                          pc->type == SOCK_DGRAM ? "udp " : "",
                          &str, u->peer.name);

            c->log->handler = handler;
        }
    }

    c->log->action = "proxying connection";

    if (u->upstream_buf.start == NULL) {
        p = ngx_pnalloc(c->pool, pscf->buffer_size);
        if (p == NULL) {
            ngx_stream_proxy_finalize(s, NGX_ERROR);
            return;
        }

        u->upstream_buf.start = p;
        u->upstream_buf.end = p + pscf->buffer_size;
        u->upstream_buf.pos = p;
        u->upstream_buf.last = p;
    }

    if (c->type == SOCK_DGRAM) {
        s->received = c->buffer->last - c->buffer->pos;
        u->downstream_buf = *c->buffer;

        if (pscf->responses == 0) {
            pc->read->ready = 0;
            pc->read->eof = 1;
        }
    }

    u->connected = 1;

    pc->read->handler = ngx_stream_proxy_upstream_handler;
    pc->write->handler = ngx_stream_proxy_upstream_handler;

    if (pc->read->ready || pc->read->eof) {
        ngx_post_event(pc->read, &ngx_posted_events);
    }

    ngx_stream_proxy_process(s, 0, 1);
}