Skip to content

Commit

Permalink
added proxy protocol support
Browse files Browse the repository at this point in the history
  • Loading branch information
arut committed Mar 31, 2014
1 parent 876de48 commit 4e78090
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 1 deletion.
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
$ngx_addon_dir/ngx_rtmp_relay_module.h \
$ngx_addon_dir/ngx_rtmp_streams.h \
$ngx_addon_dir/ngx_rtmp_bitop.h \
$ngx_addon_dir/ngx_rtmp_proxy_protocol.h \
$ngx_addon_dir/hls/ngx_rtmp_mpegts.h \
$ngx_addon_dir/dash/ngx_rtmp_mp4.h \
"
Expand Down Expand Up @@ -79,6 +80,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/ngx_rtmp_log_module.c \
$ngx_addon_dir/ngx_rtmp_limit_module.c \
$ngx_addon_dir/ngx_rtmp_bitop.c \
$ngx_addon_dir/ngx_rtmp_proxy_protocol.c \
$ngx_addon_dir/hls/ngx_rtmp_hls_module.c \
$ngx_addon_dir/dash/ngx_rtmp_dash_module.c \
$ngx_addon_dir/hls/ngx_rtmp_mpegts.c \
Expand Down
3 changes: 3 additions & 0 deletions ngx_rtmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ ngx_rtmp_add_ports(ngx_conf_t *cf, ngx_array_t *ports,
addr->bind = listen->bind;
addr->wildcard = listen->wildcard;
addr->so_keepalive = listen->so_keepalive;
addr->proxy_protocol = listen->proxy_protocol;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
addr->tcp_keepidle = listen->tcp_keepidle;
addr->tcp_keepintvl = listen->tcp_keepintvl;
Expand Down Expand Up @@ -702,6 +703,7 @@ ngx_rtmp_add_addrs(ngx_conf_t *cf, ngx_rtmp_port_t *mport,

addrs[i].conf.addr_text.len = len;
addrs[i].conf.addr_text.data = p;
addrs[i].conf.proxy_protocol = addr->proxy_protocol;
}

return NGX_OK;
Expand Down Expand Up @@ -751,6 +753,7 @@ ngx_rtmp_add_addrs6(ngx_conf_t *cf, ngx_rtmp_port_t *mport,

addrs6[i].conf.addr_text.len = len;
addrs6[i].conf.addr_text.data = p;
addrs6[i].conf.proxy_protocol = addr->proxy_protocol;
}

return NGX_OK;
Expand Down
3 changes: 3 additions & 0 deletions ngx_rtmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef struct {
unsigned ipv6only:2;
#endif
unsigned so_keepalive:2;
unsigned proxy_protocol:1;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
int tcp_keepidle;
int tcp_keepintvl;
Expand All @@ -54,6 +55,7 @@ typedef struct {
typedef struct {
ngx_rtmp_conf_ctx_t *ctx;
ngx_str_t addr_text;
unsigned proxy_protocol:1;
} ngx_rtmp_addr_conf_t;

typedef struct {
Expand Down Expand Up @@ -97,6 +99,7 @@ typedef struct {
unsigned ipv6only:2;
#endif
unsigned so_keepalive:2;
unsigned proxy_protocol:1;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
int tcp_keepidle;
int tcp_keepintvl;
Expand Down
5 changes: 5 additions & 0 deletions ngx_rtmp_core_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,11 @@ ngx_rtmp_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#endif
}

if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) {
ls->proxy_protocol = 1;
continue;
}

ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the invalid \"%V\" parameter", &value[i]);
return NGX_CONF_ERROR;
Expand Down
8 changes: 7 additions & 1 deletion ngx_rtmp_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include "ngx_rtmp.h"
#include "ngx_rtmp_proxy_protocol.h"


static void ngx_rtmp_close_connection(ngx_connection_t *c);
Expand Down Expand Up @@ -130,7 +131,12 @@ ngx_rtmp_init_connection(ngx_connection_t *c)

s->auto_pushed = unix_socket;

ngx_rtmp_handshake(s);
if (addr_conf->proxy_protocol) {
ngx_rtmp_proxy_protocol(s);

} else {
ngx_rtmp_handshake(s);
}
}


Expand Down
172 changes: 172 additions & 0 deletions ngx_rtmp_proxy_protocol.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@

/*
* Copyright (C) Roman Arutyunyan
*/


#include <ngx_config.h>
#include <ngx_core.h>
#include "ngx_rtmp_proxy_protocol.h"


static void ngx_rtmp_proxy_protocol_recv(ngx_event_t *rev);


void
ngx_rtmp_proxy_protocol(ngx_rtmp_session_t *s)
{
ngx_connection_t *c;

c = s->connection;
c->read->handler = ngx_rtmp_proxy_protocol_recv;

ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"proxy_protocol: start");

ngx_rtmp_proxy_protocol_recv(c->read);
}


static void
ngx_rtmp_proxy_protocol_recv(ngx_event_t *rev)
{
u_char buf[107], *p, *pp, *text;
size_t len;
ssize_t n;
ngx_err_t err;
ngx_int_t i;
ngx_addr_t addr;
ngx_connection_t *c;
ngx_rtmp_session_t *s;

c = rev->data;
s = c->data;

if (c->destroyed) {
return;
}

if (rev->timedout) {
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
"proxy_protocol: recv: client timed out");
c->timedout = 1;
ngx_rtmp_finalize_session(s);
return;
}

if (rev->timer_set) {
ngx_del_timer(rev);
}

n = recv(c->fd, buf, sizeof(buf), MSG_PEEK);

err = ngx_socket_errno;

if (n == -1) {

if (err == NGX_EAGAIN) {
ngx_add_timer(rev, s->timeout);

if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
ngx_rtmp_finalize_session(s);
}

return;
}

ngx_rtmp_finalize_session(s);

return;
}

p = buf;

if (n <= 8 && ngx_strncmp(p, "PROXY ", 6) != 0) {
goto bad_header;
}

n -= 6;
p += 6;

ngx_memzero(&addr, sizeof(ngx_addr_t));

if (n >= 7 && ngx_strncmp(p, "UNKNOWN", 7) == 0) {
n -= 7;
p += 7;
goto skip;
}

if (n < 5 || ngx_strncmp(p, "TCP", 3) != 0
|| (p[3] != '4' && p[3] != '6') || p[4] != ' ')
{
goto bad_header;
}

n -= 5;
p += 5;

pp = ngx_strlchr(p, p + n, ' ');

if (pp == NULL) {
goto bad_header;
}

if (ngx_parse_addr(s->connection->pool, &addr, p, pp - p) != NGX_OK) {
goto bad_header;
}

n -= pp - p;
p = pp;

skip:

for (i = 0; i + 1 < n; i++) {
if (p[i] == CR && p[i + 1] == LF) {
break;
}
}

if (i + 1 == n) {
goto bad_header;
}

n = p - buf + i + 2;

if (c->recv(c, buf, n) != n) {
goto failed;
}

if (addr.socklen) {
text = ngx_palloc(s->connection->pool, NGX_SOCKADDR_STRLEN);

if (text == NULL) {
goto failed;
}

len = ngx_sock_ntop(addr.sockaddr, addr.socklen, text,
NGX_SOCKADDR_STRLEN, 0);
if (len == 0) {
goto failed;
}

c->sockaddr = addr.sockaddr;
c->socklen = addr.socklen;
c->addr_text.data = text;
c->addr_text.len = len;

ngx_log_debug1(NGX_LOG_DEBUG_RTMP, c->log, 0,
"proxy_protocol: remote_addr:'%V'", &c->addr_text);
}

ngx_rtmp_handshake(s);

return;

bad_header:

ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxy_protocol: bad header");

failed:

ngx_rtmp_finalize_session(s);
}
19 changes: 19 additions & 0 deletions ngx_rtmp_proxy_protocol.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

/*
* Copyright (C) Roman Arutyunyan
*/


#ifndef _NGX_RTMP_PROXY_PROTOCOL_H_INCLUDED_
#define _NGX_RTMP_PROXY_PROTOCOL_H_INCLUDED_


#include <ngx_config.h>
#include <ngx_core.h>
#include "ngx_rtmp.h"


void ngx_rtmp_proxy_protocol(ngx_rtmp_session_t *c);


#endif /* _NGX_RTMP_PROXY_PROTOCOL_H_INCLUDED_ */

0 comments on commit 4e78090

Please sign in to comment.