深入理解Nginx流代理模块SSL连接源代码解析 - 第三部分:详细源码剖析
最编程
2024-08-01 15:03:55
...
本文主要聚焦在ssl连接逻辑的分析,所以中间会跳过和ssl逻辑不太相关的代码,虽然可能这部分对nginx本身的功能逻辑非常重要。另外,本文也假设只是TCP代理,不对UDP代理进行分析。
下面直接进入主题,从代理模块的请求入口点开始分析。
3.1 代理模块的请求入口点分析
代理模块的请求入口点是ngx_stream_proxy_handler函数,一旦客户端和nginx建立了TCP连接后,nginx就会调用代理模块的这个函数,开始与上游服务器建立连接。
该函数源码主要就是以下列出的三个步骤:
static void
ngx_stream_proxy_handler(ngx_stream_session_t *s)
{
/* 创建ngx_stream_upstream_t上下文,对它进行必要的初始化,
并关联到ngx_stream_session_t中 */
/* 如果上游服务器的地址已经解析好就调用ngx_stream_proxy_connect开始连接上游服务器 */
/* 如果上游服务器的地址需要域名解析则开启异步解析流程 */
}
因此,我们需要重点关注的是ngx_stream_proxy_connect,它负责与上游服务器建立TCP连接。
3.2 发起与上游服务器的连接
static void
ngx_stream_proxy_connect(ngx_stream_session_t *s)
{
ngx_int_t rc;
ngx_connection_t *c, *pc;
ngx_stream_upstream_t *u;
ngx_stream_proxy_srv_conf_t *pscf;
c = s->connection;
c->log->action = "connecting to upstream";
pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
u = s->upstream;
u->connected = 0;
u->proxy_protocol = pscf->proxy_protocol;
if (u->state) {
u->state->response_time = ngx_current_msec - u->start_time;
}
u->state = ngx_array_push(s->upstream_states);
if (u->state == NULL) {
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));
u->start_time = ngx_current_msec;
u->state->connect_time = (ngx_msec_t) -1;
u->state->first_byte_time = (ngx_msec_t) -1;
u->state->response_time = (ngx_msec_t) -1;
/* 创建SOCKET,并发起异步连接请求*/
rc = ngx_event_connect_peer(&u->peer);
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
if (rc == NGX_ERROR) {
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
u->state->peer = u->peer.name;
if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams")
上一篇: FPGA开发