当前位置:首页 > 网络安全 > 正文内容

nginx启动初始化代码执行流程

访客4年前 (2021-04-15)网络安全411

流程图

代码执行流程

ngx_event_process_init:遍历connections,初始化listenfd的回调函数,添加事件监听

static ngx_int_t

ngx_event_process_init(ngx_cycle_t *cycle)

{

...

cycle->connections=

ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);


cycle->read_events=ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,

cycle->log);

...

ls=cycle->listening.elts;

for (i=0; i < cycle->listening.nelts; i++) {

c=ngx_get_connection(ls[i].fd, cycle->log);

c->listening=&ls[i];

rev=c->read;

}

...

rev->handler=ngx_event_accept;

ngx_add_event(rev, NGX_READ_EVENT, 0)

...

}


ngx_event_accept:调用ngx_listening_t的回调函数

void

ngx_event_accept(ngx_event_t *ev)

{

...

lc=ev->data;

ls=lc->listening;

...

s=accept(lc->fd, (struct sockaddr *) sa, &socklen);

c=ngx_get_connection(s, ev->log);

ngx_add_conn(c)

ls->handler(c);

...

}


找到ls->handler(c)的位置

static char *

ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

...

if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) !=NGX_OK) {

return NGX_CONF_ERROR;

}

...

}



static ngx_int_t

ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,

ngx_array_t *ports)

{

...

if (ngx_http_init_listening(cf, &port[p]) !=NGX_OK) {

return NGX_ERROR;

}

...

}



static ngx_int_t

ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port)

{

...

ls=ngx_http_add_listening(cf, &addr[i]);

if (ls==NULL) {

return NGX_ERROR;

}

...

}



static ngx_listening_t *

ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)

{

...

ls->handler=ngx_http_init_connection;

...

}


第三方模块(输出):

server {

listen 0.0.0.0:70;

location / {

root /usr/local/nginx/html/bak/;

limit_req zone=req10k burst=5 nodelay;

shuchu "helloworld";

}

}


一个模块的三大核心

static ngx_command_t ngx_http_shuchu_commands[]={

{

ngx_string("shuchu"),

NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,

ngx_http_shuchu,

NGX_HTTP_LOC_CONF_OFFSET,

offsetof(ngx_http_shuchu_loc_conf_t, content),

NULL,

},?

ngx_null_command,

};


static ngx_http_module_t? ngx_http_shuchu_ctx={

NULL,

ngx_http_shuchu_init,

NULL,

NULL,

NULL,

NULL,

ngx_http_shuchu_create_loc_conf,

ngx_http_shuchu_merge_loc_conf

};



ngx_module_t ngx_http_shuchu_module={

NGX_MODULE_V1,

&ngx_http_shuchu_ctx,?

ngx_http_shuchu_commands,?

NGX_HTTP_MODULE,

NULL,?

NULL,?

NULL,?

NULL,?

NULL,?

NULL,?

NULL,?

NGX_MODULE_V1_PADDING

};


ngx_conf_parse:解析配置

char *

ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)

{

...

type=parse_file;

fd=ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);

rc=ngx_conf_read_token(cf);

省略对rc和type组合的判定

rc=ngx_conf_handler(cf, rc);

...

}


ngx_conf_handler:对指令进行处理

static ngx_int_t

ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)

{

...

for (i=0; ngx_modules[i]; i++) {


cmd=ngx_modules[i]->commands;

for ( ; cmd->name.len; cmd++) {

if (cmd->type & NGX_DIRECT_CONF) {

conf=((void **) cf->ctx)[ngx_modules[i]->index];


} else if (cmd->type & NGX_MAIN_CONF) {

conf=&(((void **) cf->ctx)[ngx_modules[i]->index]);


} else if (cf->ctx) {

confp=*(void **) ((char *) cf->ctx + cmd->conf);


if (confp) {

conf=confp[ngx_modules[i]->ctx_index];

}

}

rv=cmd->set(cf, cmd, conf);

}

}

...

}


ngx_http_block

static char *

ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

...

ctx->main_conf=ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

ctx->srv_conf=ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

ctx->loc_conf=ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

for (m=0; ngx_modules[m]; m++) {

if (ngx_modules[m]->type !=NGX_HTTP_MODULE) {

continue;

}


module=ngx_modules[m]->ctx;

mi=ngx_modules[m]->ctx_index;


if (module->create_main_conf) {

ctx->main_conf[mi]=module->create_main_conf(cf);

if (ctx->main_conf[mi]==NULL) {

return NGX_CONF_ERROR;

}

}


if (module->create_srv_conf) {

ctx->srv_conf[mi]=module->create_srv_conf(cf);

if (ctx->srv_conf[mi]==NULL) {

return NGX_CONF_ERROR;

}

}


if (module->create_loc_conf) {

ctx->loc_conf[mi]=module->create_loc_conf(cf);

if (ctx->loc_conf[mi]==NULL) {

return NGX_CONF_ERROR;

}

}

}



pcf=*cf;

cf->ctx=ctx;

...


cf->module_type=NGX_HTTP_MODULE;

cf->cmd_type=NGX_HTTP_MAIN_CONF;

rv=ngx_conf_parse(cf, NULL);

...

}


ngx_http_core_server

static char *

ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)

{

...

ctx=ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));

if (ctx==NULL) {

return NGX_CONF_ERROR;

}


http_ctx=cf->ctx;

ctx->main_conf=http_ctx->main_conf;

ctx->srv_conf=ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

ctx->loc_conf=ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

...

cscf=ctx->srv_conf[ngx_http_core_module.ctx_index];

cscf->ctx=ctx;



cmcf=ctx->main_conf[ngx_http_core_module.ctx_index];


cscfp=ngx_array_push(&cmcf->servers);

if (cscfp==NULL) {

return NGX_CONF_ERROR;

}


*cscfp=cscf;




pcf=*cf;

cf->ctx=ctx;

cf->cmd_type=NGX_HTTP_SRV_CONF;


rv=ngx_conf_parse(cf, NULL);

...

}


ngx_http_core_listen

static char *

ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

...

cscf->listen=1;


value=cf->args->elts;


ngx_memzero(&u, sizeof(ngx_url_t));


u.url=value[1];

ngx_parse_url(cf->pool, &u);

if (ngx_http_add_listen(cf, cscf, &lsopt)==NGX_OK) {

return NGX_CONF_OK;

}

...

}


ngx_http_add_listen

ngx_int_t

ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,

ngx_http_listen_opt_t *lsopt)

{

...

cmcf=ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);


if (cmcf->ports==NULL) {

cmcf->ports=ngx_array_create(cf->temp_pool, 2,

sizeof(ngx_http_conf_port_t));

if (cmcf->ports==NULL) {

return NGX_ERROR;

}

}

sin=&lsopt->u.sockaddr_in;

p=sin->sin_port;

port=ngx_array_push(cmcf->ports);

port->family=sa->sa_family;

port->port=p;

port->addrs.elts=NULL;

ngx_http_add_address(cf, cscf, port, lsopt);

...

}


ngx_http_add_address

static ngx_int_t

ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,

ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)

{

...

addr=ngx_array_push(&port->addrs);

addr->opt=*lsopt;

addr->default_server=cscf;

...}


ngx_http_add_server

static ngx_int_t

ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,

ngx_http_conf_addr_t *addr)

{

...

server=ngx_array_push(&addr->servers);

*server=cscf;

...

}


到这里为止,整个配置的基本架构已经搞起来了,port(ngx_http_conf_port_t)下挂着多个监听的地址(ngx_http_conf_addr_t),每个地址后的opt目前都是配置里面读出来,存着监听器的信息,监听地址(ngx_http_conf_addr_t)后面还挂着这个监听地址所存在的server块(ngx_http_core_srv_conf_t),接下来就要最后在optmize一下,把opt里的东西搞一下,然后做hash:

ngx_http_optimize_servers

static ngx_int_t

ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,

ngx_array_t *ports)

{

...

port=ports->elts;

for (p=0; p < ports->nelts; p++) {

addr=port[p].addrs.elts;

for (a=0; a < port[p].addrs.nelts; a++) {

if (ngx_http_server_names(cf, cmcf, &addr[a]) !=NGX_OK) {

return NGX_ERROR;

}

}

if (ngx_http_init_listening(cf, &port[p]) !=NGX_OK) {

return NGX_ERROR;

}

}

...

}


ngx_http_server_names:整理addr中的servers,将sn和对应的srv_conf对应起来

static ngx_int_t

ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,

ngx_array_t *ports)

{

...

ha.pool=cf->pool;

cscfp=addr->servers.elts;

for (s=0; s < addr->servers.nelts; s++) {

name=cscfp[s]->server_names.elts;

for (n=0; n < cscfp[s]->server_names.nelts; n++) {

rc=ngx_hash_add_key(&ha, &name[n].name, name[n].server,

NGX_HASH_WILDCARD_KEY);

}

...

hash.hash=&addr->hash;

ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts);

}

...

}


ngx_http_add_listening

static ngx_listening_t *

ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)

{

...

ls=ngx_create_listening(cf, &addr->opt.u.sockaddr, addr->opt.socklen);

ls->handler=ngx_http_init_connection;

...

}


instance

每次get_connection都会将instance取反,s是accept获取的socket,是一个int,赋值给c->fd

ngx_connection_t *

ngx_get_connection(ngx_socket_t s, ngx_log_t *log)

{

...

c=ngx_cycle->free_connections;

ngx_cycle->free_connections=c->data;

ngx_cycle->free_connection_n--;

rev=c->read;

wev=c->write;

ngx_memzero(c, sizeof(ngx_connection_t));

c->read=rev;

c->write=wev;

c->fd=s;

rev->instance=!instance;

wev->instance=!instance;

rev->data=c;

wev->data=c;

return c;

...

}

而free的时候只移动链表,清空文件,将当前链表变成可用

void

ngx_free_connection(ngx_connection_t *c)

{

...

c->data=ngx_cycle->free_connections;

ngx_cycle->free_connections=c;

ngx_cycle->free_connection_n++;


if (ngx_cycle->files) {

ngx_cycle->files[c->fd]=NULL;

...

}

而无论是add_event还是add_connection,都是直接将epoll指向的直接与instance,在process_events的时候,拿出来事件指向的

static ngx_int_t

ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)

{

...

ee.data.ptr=(void *) ((uintptr_t) c | ev->instance);

...

}

static ngx_int_t

ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)

{

...

c=event_list[i].data.ptr;

instance=(uintptr_t) c & 1;

if (c->fd==-1 || rev->instance !=instance) {

...

}


扫描二维码推送至手机访问。

版权声明:本文由黑客接单发布,如需转载请注明出处。

本文链接:https://therlest.com/106125.html

分享给朋友:

“nginx启动初始化代码执行流程” 的相关文章

洗米华小三(浅谈米花三笑的微博)

据长江网2021年11月26日23:49:22的最新消息,微博网友@ 爆料。 平安夜来临之际,事件,在网上炒得沸沸扬扬,引发全网热议! 据悉,洗米华小三。猜测这是洗米华在暗中帮助着Mandy。挺想看他老婆小三都抛弃他的场面。 1.洗米华小三 m...

【紧急+重要】勒索病毒解决方案!附:MS17-010补丁下载

  滚动更新:2017年5月13日16:57:22   游侠安全网(良心网站,站长先贴上注意事项和解决方法!防止你看本文的时候就被加密了!   1、本次共计是自动化攻击,利用了Windows的MS17-010。但苹果的MacOS用户不用得意,因为在昨晚之前,我这里得到的好几起勒索攻击案例都是针对...

干洗对衣物有害吗

干洗对衣物有害吗 干洗剂实际上就是有机溶剂,所以对衣服多少都有点危害,只不过高级的干洗剂对衣服损伤小一些而已。 随着人们工作的繁忙和生活节奏的加快,现代人更多地把换下的衣物送到洗衣店干洗,以保证衣服不变形和有更多的时间休闲娱乐,这本是一件提高生活品质的好事,但据最新的研究显示,干洗衣物对身...

奥门币币对人民币换算 - 澳元兑换人民币汇率

在珠海拱北口岸地下商城,公布当日主要交易货币“美元、此外汇牌价汇率表仅供参考=6点0442则一元人民币换0,点04762元,很高兴为你解答。 1点2208澳门元数据对仅供参考,划算 另外,另外汇率是不断变化的,可以百度输入"澳门元对人民币汇率,货币兑换1澳元=4点。 在外面买东西的小店不是太正规的,...

53度最便宜酱香郎酒_郎酒经典酱香53度

我一朋友,500多到600多,10年红花郎288,现在估价至少在2000元以上,郎酒老郎酒淡雅2002年出厂,三星,关键是看款型,1992年53-1度酱香型。 郎酒还是1898起步比较好。对了,或者以前的,未来两年必定疯长!不知道怎么上图,现在的价格是158元每瓶便宜,你好。 看目前郎酒的上涨势头,...

定增一般需要多长时间,定增价格确定后股票走势

就会增加公司的流通股,标签:增发定向投资机会瞄准四个南京医药投资者报分类:股票为什么留意这样的股票,先是股东大会审议通过,不低于20个交易日的平均价格,具体来讲,一般需要至少半年以上。2011-05-1815:56:01,定向增发流程现在相对是比较简单的,另外,而是证监会。 或大概后说个区间,中国证...

评论列表

冬马僚兮
2年前 (2022-07-06)

cmd_type=NGX_HTTP_SRV_CONF;rv=ngx_conf_parse(cf, NULL);...}ngx_http_core_listensta

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。