Skip to content

Commit 4e78090

Browse files
committed
added proxy protocol support
1 parent 876de48 commit 4e78090

7 files changed

+211
-1
lines changed

config

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
4444
$ngx_addon_dir/ngx_rtmp_relay_module.h \
4545
$ngx_addon_dir/ngx_rtmp_streams.h \
4646
$ngx_addon_dir/ngx_rtmp_bitop.h \
47+
$ngx_addon_dir/ngx_rtmp_proxy_protocol.h \
4748
$ngx_addon_dir/hls/ngx_rtmp_mpegts.h \
4849
$ngx_addon_dir/dash/ngx_rtmp_mp4.h \
4950
"
@@ -79,6 +80,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
7980
$ngx_addon_dir/ngx_rtmp_log_module.c \
8081
$ngx_addon_dir/ngx_rtmp_limit_module.c \
8182
$ngx_addon_dir/ngx_rtmp_bitop.c \
83+
$ngx_addon_dir/ngx_rtmp_proxy_protocol.c \
8284
$ngx_addon_dir/hls/ngx_rtmp_hls_module.c \
8385
$ngx_addon_dir/dash/ngx_rtmp_dash_module.c \
8486
$ngx_addon_dir/hls/ngx_rtmp_mpegts.c \

ngx_rtmp.c

+3
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ ngx_rtmp_add_ports(ngx_conf_t *cf, ngx_array_t *ports,
544544
addr->bind = listen->bind;
545545
addr->wildcard = listen->wildcard;
546546
addr->so_keepalive = listen->so_keepalive;
547+
addr->proxy_protocol = listen->proxy_protocol;
547548
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
548549
addr->tcp_keepidle = listen->tcp_keepidle;
549550
addr->tcp_keepintvl = listen->tcp_keepintvl;
@@ -702,6 +703,7 @@ ngx_rtmp_add_addrs(ngx_conf_t *cf, ngx_rtmp_port_t *mport,
702703

703704
addrs[i].conf.addr_text.len = len;
704705
addrs[i].conf.addr_text.data = p;
706+
addrs[i].conf.proxy_protocol = addr->proxy_protocol;
705707
}
706708

707709
return NGX_OK;
@@ -751,6 +753,7 @@ ngx_rtmp_add_addrs6(ngx_conf_t *cf, ngx_rtmp_port_t *mport,
751753

752754
addrs6[i].conf.addr_text.len = len;
753755
addrs6[i].conf.addr_text.data = p;
756+
addrs6[i].conf.proxy_protocol = addr->proxy_protocol;
754757
}
755758

756759
return NGX_OK;

ngx_rtmp.h

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef struct {
4343
unsigned ipv6only:2;
4444
#endif
4545
unsigned so_keepalive:2;
46+
unsigned proxy_protocol:1;
4647
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
4748
int tcp_keepidle;
4849
int tcp_keepintvl;
@@ -54,6 +55,7 @@ typedef struct {
5455
typedef struct {
5556
ngx_rtmp_conf_ctx_t *ctx;
5657
ngx_str_t addr_text;
58+
unsigned proxy_protocol:1;
5759
} ngx_rtmp_addr_conf_t;
5860

5961
typedef struct {
@@ -97,6 +99,7 @@ typedef struct {
9799
unsigned ipv6only:2;
98100
#endif
99101
unsigned so_keepalive:2;
102+
unsigned proxy_protocol:1;
100103
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
101104
int tcp_keepidle;
102105
int tcp_keepintvl;

ngx_rtmp_core_module.c

+5
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,11 @@ ngx_rtmp_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
719719
#endif
720720
}
721721

722+
if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) {
723+
ls->proxy_protocol = 1;
724+
continue;
725+
}
726+
722727
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
723728
"the invalid \"%V\" parameter", &value[i]);
724729
return NGX_CONF_ERROR;

ngx_rtmp_init.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <ngx_config.h>
88
#include <ngx_core.h>
99
#include "ngx_rtmp.h"
10+
#include "ngx_rtmp_proxy_protocol.h"
1011

1112

1213
static void ngx_rtmp_close_connection(ngx_connection_t *c);
@@ -130,7 +131,12 @@ ngx_rtmp_init_connection(ngx_connection_t *c)
130131

131132
s->auto_pushed = unix_socket;
132133

133-
ngx_rtmp_handshake(s);
134+
if (addr_conf->proxy_protocol) {
135+
ngx_rtmp_proxy_protocol(s);
136+
137+
} else {
138+
ngx_rtmp_handshake(s);
139+
}
134140
}
135141

136142

ngx_rtmp_proxy_protocol.c

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
2+
/*
3+
* Copyright (C) Roman Arutyunyan
4+
*/
5+
6+
7+
#include <ngx_config.h>
8+
#include <ngx_core.h>
9+
#include "ngx_rtmp_proxy_protocol.h"
10+
11+
12+
static void ngx_rtmp_proxy_protocol_recv(ngx_event_t *rev);
13+
14+
15+
void
16+
ngx_rtmp_proxy_protocol(ngx_rtmp_session_t *s)
17+
{
18+
ngx_connection_t *c;
19+
20+
c = s->connection;
21+
c->read->handler = ngx_rtmp_proxy_protocol_recv;
22+
23+
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
24+
"proxy_protocol: start");
25+
26+
ngx_rtmp_proxy_protocol_recv(c->read);
27+
}
28+
29+
30+
static void
31+
ngx_rtmp_proxy_protocol_recv(ngx_event_t *rev)
32+
{
33+
u_char buf[107], *p, *pp, *text;
34+
size_t len;
35+
ssize_t n;
36+
ngx_err_t err;
37+
ngx_int_t i;
38+
ngx_addr_t addr;
39+
ngx_connection_t *c;
40+
ngx_rtmp_session_t *s;
41+
42+
c = rev->data;
43+
s = c->data;
44+
45+
if (c->destroyed) {
46+
return;
47+
}
48+
49+
if (rev->timedout) {
50+
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
51+
"proxy_protocol: recv: client timed out");
52+
c->timedout = 1;
53+
ngx_rtmp_finalize_session(s);
54+
return;
55+
}
56+
57+
if (rev->timer_set) {
58+
ngx_del_timer(rev);
59+
}
60+
61+
n = recv(c->fd, buf, sizeof(buf), MSG_PEEK);
62+
63+
err = ngx_socket_errno;
64+
65+
if (n == -1) {
66+
67+
if (err == NGX_EAGAIN) {
68+
ngx_add_timer(rev, s->timeout);
69+
70+
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
71+
ngx_rtmp_finalize_session(s);
72+
}
73+
74+
return;
75+
}
76+
77+
ngx_rtmp_finalize_session(s);
78+
79+
return;
80+
}
81+
82+
p = buf;
83+
84+
if (n <= 8 && ngx_strncmp(p, "PROXY ", 6) != 0) {
85+
goto bad_header;
86+
}
87+
88+
n -= 6;
89+
p += 6;
90+
91+
ngx_memzero(&addr, sizeof(ngx_addr_t));
92+
93+
if (n >= 7 && ngx_strncmp(p, "UNKNOWN", 7) == 0) {
94+
n -= 7;
95+
p += 7;
96+
goto skip;
97+
}
98+
99+
if (n < 5 || ngx_strncmp(p, "TCP", 3) != 0
100+
|| (p[3] != '4' && p[3] != '6') || p[4] != ' ')
101+
{
102+
goto bad_header;
103+
}
104+
105+
n -= 5;
106+
p += 5;
107+
108+
pp = ngx_strlchr(p, p + n, ' ');
109+
110+
if (pp == NULL) {
111+
goto bad_header;
112+
}
113+
114+
if (ngx_parse_addr(s->connection->pool, &addr, p, pp - p) != NGX_OK) {
115+
goto bad_header;
116+
}
117+
118+
n -= pp - p;
119+
p = pp;
120+
121+
skip:
122+
123+
for (i = 0; i + 1 < n; i++) {
124+
if (p[i] == CR && p[i + 1] == LF) {
125+
break;
126+
}
127+
}
128+
129+
if (i + 1 == n) {
130+
goto bad_header;
131+
}
132+
133+
n = p - buf + i + 2;
134+
135+
if (c->recv(c, buf, n) != n) {
136+
goto failed;
137+
}
138+
139+
if (addr.socklen) {
140+
text = ngx_palloc(s->connection->pool, NGX_SOCKADDR_STRLEN);
141+
142+
if (text == NULL) {
143+
goto failed;
144+
}
145+
146+
len = ngx_sock_ntop(addr.sockaddr, addr.socklen, text,
147+
NGX_SOCKADDR_STRLEN, 0);
148+
if (len == 0) {
149+
goto failed;
150+
}
151+
152+
c->sockaddr = addr.sockaddr;
153+
c->socklen = addr.socklen;
154+
c->addr_text.data = text;
155+
c->addr_text.len = len;
156+
157+
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, c->log, 0,
158+
"proxy_protocol: remote_addr:'%V'", &c->addr_text);
159+
}
160+
161+
ngx_rtmp_handshake(s);
162+
163+
return;
164+
165+
bad_header:
166+
167+
ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxy_protocol: bad header");
168+
169+
failed:
170+
171+
ngx_rtmp_finalize_session(s);
172+
}

ngx_rtmp_proxy_protocol.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
/*
3+
* Copyright (C) Roman Arutyunyan
4+
*/
5+
6+
7+
#ifndef _NGX_RTMP_PROXY_PROTOCOL_H_INCLUDED_
8+
#define _NGX_RTMP_PROXY_PROTOCOL_H_INCLUDED_
9+
10+
11+
#include <ngx_config.h>
12+
#include <ngx_core.h>
13+
#include "ngx_rtmp.h"
14+
15+
16+
void ngx_rtmp_proxy_protocol(ngx_rtmp_session_t *c);
17+
18+
19+
#endif /* _NGX_RTMP_PROXY_PROTOCOL_H_INCLUDED_ */

0 commit comments

Comments
 (0)