ngx_rtmp_proxy_protocol 实现了 Nginx RTMP 模块中的 Proxy Protocol 功能。Proxy Protocol 是一种用于在代理服务器和后端服务器之间传递客户端信息的协议,通常用于传递客户端的真实 IP 地址和端口信息。在 Nginx 中,Proxy Protocol 被用于 RTMP 流媒体传输,以便能够获取经过代理的客户端的真实地址。
1. ngx_rtmp_proxy_protocol.h
头文件分析
该头文件定义了 Proxy Protocol 模块的接口,包括 ngx_rtmp_proxy_protocol
函数,它是模块的核心函数,负责处理 RTMP 会话中的 Proxy Protocol 信息。
主要内容:
-
ngx_rtmp_proxy_protocol
:-
函数声明,接收一个
ngx_rtmp_session_t
类型的参数,表示 RTMP 会话。该函数的作用是处理 Proxy Protocol 数据。
-
2. ngx_rtmp_proxy_protocol.c
源文件分析
该源文件实现了 Proxy Protocol 功能的具体逻辑,主要处理 Proxy Protocol 请求的接收、解析和处理。
2.1 ngx_rtmp_proxy_protocol
函数
这个函数是 RTMP 会话启动时的入口点,负责设置 RTMP 会话的读取事件处理函数,并开始处理客户端传来的 Proxy Protocol 数据。
-
读取事件设置:
-
rev->handler = ngx_rtmp_proxy_protocol_recv;
:设置读取事件的处理函数为ngx_rtmp_proxy_protocol_recv
,即当有数据可读时,会调用该函数进行数据处理。
-
-
日志记录:
-
ngx_log_debug0
记录调试日志,标记 Proxy Protocol 的处理开始。
-
-
事件处理:
-
如果事件已经准备好处理,则立即调用
rev->handler(rev)
来处理数据。 -
否则,使用
ngx_add_timer
添加超时定时器,并通过ngx_handle_read_event
注册事件处理。
-
2.2 ngx_rtmp_proxy_protocol_recv
函数
这是核心的接收和解析函数,它从客户端接收 Proxy Protocol 数据,并解析客户端的地址和端口信息。
-
接收数据:
-
通过
recv
函数读取数据,并使用MSG_PEEK
来查看数据而不从套接字中移除数据。
-
-
数据解析:
-
首先检查数据头部是否符合 "PROXY " 标识符,确认该数据是 Proxy Protocol 格式。
-
如果符合格式,继续解析客户端的 IP 地址和端口号。如果是 "UNKNOWN",则跳过 IP 地址部分。
-
解析过程中,检查是否为支持的 "TCP4" 或 "TCP6" 格式,并提取相应的 IP 地址和端口信息。
-
-
解析结果:
-
如果成功解析了地址信息,将其存储在
c->sockaddr
和c->addr_text
中,并更新客户端连接的地址信息。 -
使用
ngx_rtmp_handshake
进行 RTMP 握手。
-
-
错误处理:
-
如果接收到的数据格式不符合要求,或者出现解析错误,调用
ngx_rtmp_finalize_session(s)
来关闭 RTMP 会话,并记录错误日志。
-
-
超时和错误处理:
-
如果接收数据超时或发生网络错误,调用
ngx_rtmp_netcall_finalize_session
来结束会话。
-
2.3 日志记录
-
在整个数据处理过程中,使用
ngx_log_debug1
和ngx_log_error
记录调试和错误信息,帮助开发人员和运维人员诊断问题。
3. Proxy Protocol 的工作原理
Proxy Protocol 用于将客户端的真实 IP 地址和端口通过代理传递到后端服务器。在 RTMP 流媒体服务中,这意味着即使客户端的请求通过代理或负载均衡器传递,后端 RTMP 服务器也能获取到客户端的原始 IP 地址。
-
数据格式:
-
Proxy Protocol 数据包以 "PROXY " 开头,后面跟着代理协议的版本信息(如 "TCP4" 或 "TCP6"),然后是客户端的 IP 地址和端口,最后是结束的 CRLF(回车换行)。
-
例如,"PROXY TCP4 192.168.0.1 12345 192.168.0.2 80\r\n" 表示客户端的 IP 地址是
192.168.0.1
,端口是12345
,服务器的 IP 地址是192.168.0.2
,端口是80
。
-
-
解析过程:
-
模块接收 Proxy Protocol 数据包,解析客户端的 IP 和端口,然后将这些信息存储在连接的
sockaddr
和addr_text
字段中。
-
4. 总结
该模块的核心功能是支持 RTMP 服务器通过 Proxy Protocol 获取客户端的真实 IP 地址,确保即使客户端通过代理或负载均衡器访问,RTMP 服务器依然能获取到正确的源地址信息。具体的实现过程包括:
-
接收 Proxy Protocol 数据包。
-
解析并提取客户端的真实 IP 地址和端口。
-
更新连接的地址信息,并进行 RTMP 握手。
理解 Proxy Protocol 的格式和解析过程是关键。通过这段代码,Nginx RTMP 服务器能够正确处理经过代理的客户端连接,确保日志和其他业务逻辑的正确性。