core/ngx_inet.h头文件分析
本节我们讲述一下nginx inet相关数据结构定义及操作函数。
1. socket地址长度相关定义
这里首先定义字符串表示形式下ipv4、ipv6以及unix domain socket的地址长度。在objs/ngx_auto_config.h头文件中我们有如下定义:
#ifndef NGX_HAVE_UNIX_DOMAIN #define NGX_HAVE_UNIX_DOMAIN 1 #endif
2. 相关数据结构定义
-
ngx_in_cidr_t
: 是ipv4无类域间ip地址 -
ngx_in6_cidr_t
: 是ipv6无类域间ip地址。当前我们并不支持NGX_HAVE_INET6
-
ngx_cidr_t
: 无类域间ip地址 -
ngx_addr_t
: socket ip地址封装
3. ngx_url_t数据结构
在介绍ngx_url_t
数据结构之前,我们先来了解一下nginx中所配置url大体是什么样式。搜索ngx_parse_url()
函数,并找到所使用ngx_url_t
的一些位置。
1) core模块中的listen指令
可以在listen
指令后为IP设置address
以及port
,或者指定一个unix域socket。服务器将会在这些地址上接收外部请求。可以同时指定address
以及port
,也可只指定address
或port
。而对于address
也可以用主机名代替。例如:
listen 127.0.0.1:8000; listen 127.0.0.1; listen 8000; listen *:8000; listen localhost:8000;
对于IPV6地址,可以在方括号中指定。例如:
listen [::]:8000; listen [::1];
对于unix域socket,则必须添加unix:
前缀:
listen unix:/var/run/nginx.sock;
上面如果只指定了IP地址,没有指明端口的话,则默认会采用80端口。
2) events模块debug_connection指令
events { debug_connection 127.0.0.1; debug_connection localhost; debug_connection 192.0.2.0/24; debug_connection ::1; debug_connection 2001:0db8::/32; debug_connection unix:; ... }
debug_connection
指令用于为指定的客户端使能调试日志。而对于其他的连接,则会使用error_log
指令的相应设置来打印日志。指定的debug connection可以是ipv4或者ipv6形式,也可以是hostname形式表示的地址,也可以是一个unix域socket形式。
3) http模块memcached_pass指令
用于设置memcached服务器地址。该地址可以通过一个domain name或IP地址,和一个port的形式来指定。例如:
memcached_pass localhost:11211;
而对于一个unix域socket,可以通过如下方式指定:
memcached_pass unix:/tmp/memcached.socket;
4) http核心模块resolver指令
用于配置将upstream servers解析成IP地址的一个服务地址。例如:
resolver 127.0.0.1 [::1]:5353;
假如没有指定端口的话,默认使用53端口
5) stream模块listen指令
用于指定服务器在给定address
以及port
处接受连接请求。可以单独指定port。address
也可以是一个Hostname。例如:
listen 127.0.0.1:12345; listen *:12345; listen 12345; # same as *:12345 listen localhost:12345;
也可以通过方括号的形式指定IPv6地址:
listen [::1]:12345; listen [::]:12345;
也可以通过unix:
前缀来指定unix域socket:
listen unix:/var/run/nginx.sock;
6) 核心模块error_log指令
error_log
指令用于配置日志输出。当配置为输出到syslog
中时,配置如下:
error_log syslog:server=192.168.1.1 debug; access_log syslog:server=unix:/var/log/nginx.sock,nohostname; access_log syslog:server=[2001:db8::1]:12345,facility=local7,tag=nginx,severity=info combined;
通过上面6个url配置示例,我们可以看到url的一个大体样式。包含ipv4
、ipv6
以及unix域socket
这3种形式。这里注意在进行解析ngx_url_t
时,一般都会去掉前缀,如http
、https
、以及syslog:server=
这样的前缀。
下面我们再来分析ngx_url_t
数据结构:
-
url
: 该url的字符串表示形式 -
host
: 在有些地方是通过主机名的形式来指定某一项服务,此时会设置此字段。一般只是作为服务的一个标识。例如http upstream模块下的server指令:
server backend.example.com service=_http._tcp resolve;
此种情况一般不需要经过ngx_parse_url()
函数来解析。
-
port_text
: 端口的字符串表示形式 -
uri
: uri标识,一般为url中最后一个/
后的内容。 -
port
: 网络字节序表示的端口 -
default_port
: 如果在配置中端口没有指定的话,会采用系统所指定的一个默认端口。 -
family
: 所指定的协议类型(IPv4/IPv7/Unix domain) -
listen
: 是否需要建立监听socket。针对有一些配置可能需要建立,而另外一些如events模块中的debug_connection指令,则不需要建立专门的监听socket。 -
uri_part
: 是否具有uri部分 -
no_resolve
: 需不需要进行DNS解析 -
one_addr
: 本字段暂时未使用 -
no_port
: 表明当前url中是否配置了端口(如果没有配置,且需要端口的话,则会采用默认端口) -
wildcard
: 是否为一个通配地址 -
socklen
: 所对应的socket长度 -
sockaddr
: 存放socket地址的内存空间(此地址存放的一般是选作为默认的socket地址,请参看如下字段) -
addrs
: 存放所有socket的地址的数组空间(有时配置是一个通配地址,或者是一个域名地址,在完成DNS解析后可能会解析出多个地址) -
naddrs
: 上面addrs数组元素的个数 -
err
: 用于存放对应的错误信息字符串
4. 相关函数声明
-
ngx_inet_addr()
: 用于将字符串表示的IPv4地址转换成in_addr_t类型表示 -
ngx_inet6_addr()
: 用于将字符串表示的IPv6地址转换成ipv6相应结构,存放在addr所指向的内存中。当前我们并不支持NGX_HAVE_INET6
宏定义。 -
ngx_inet6_ntop()
: 用于将ipv6相应内存结构转换成字符串表示形式 -
ngx_sock_ntop()
: 用于将ipv4、ipv6、unix域socket地址转换成字符串表示形式,存放在text中 -
ngx_inet_ntop()
: 用于将ipv4、ipv6表示的相应结构转换成字符串表示形式,存放在text中 -
ngx_ptocidr()
: 将字符串表示形式的ip地址(ipv4/ipv6)转换成cidr表示形式 -
ngx_parse_addr()
: 将text
表示形式的IP地址转换成ngx_addr_t结构 -
ngx_parse_url()
: 解析ngx_url_t
数据结构 -
ngx_inet_resolve()
: 将主机名转换成socket地址结构 -
ngx_cmp_sockaddr()
: 比较两个IP地址
[参考]