Skip to content
69 changes: 52 additions & 17 deletions modules/ngx_tcp_generic_proxy_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ typedef struct ngx_tcp_proxy_conf_s {
} ngx_tcp_proxy_conf_t;


static void ngx_tcp_proxy_init_session(ngx_tcp_session_t *s);
static void ngx_tcp_proxy_init_upstream(ngx_connection_t *c,
static void ngx_tcp_proxy_init_session(ngx_tcp_session_t *s);
static void ngx_tcp_proxy_init_upstream(ngx_connection_t *c,
ngx_tcp_session_t *s);
static void ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s,
static void ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s,
ngx_tcp_upstream_t *u);
static char *ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void ngx_tcp_proxy_dummy_read_handler(ngx_event_t *ev);
Expand Down Expand Up @@ -114,8 +114,8 @@ ngx_module_t ngx_tcp_proxy_module = {
};


static void
ngx_tcp_proxy_init_session(ngx_tcp_session_t *s)
static void
ngx_tcp_proxy_init_session(ngx_tcp_session_t *s)
{
ngx_connection_t *c;
ngx_tcp_proxy_conf_t *pcf;
Expand Down Expand Up @@ -149,7 +149,7 @@ ngx_tcp_proxy_init_session(ngx_tcp_session_t *s)


static void
ngx_tcp_proxy_dummy_write_handler(ngx_event_t *wev)
ngx_tcp_proxy_dummy_write_handler(ngx_event_t *wev)
{
ngx_connection_t *c;
ngx_tcp_session_t *s;
Expand All @@ -167,7 +167,7 @@ ngx_tcp_proxy_dummy_write_handler(ngx_event_t *wev)


static void
ngx_tcp_proxy_dummy_read_handler(ngx_event_t *rev)
ngx_tcp_proxy_dummy_read_handler(ngx_event_t *rev)
{
ngx_connection_t *c;
ngx_tcp_session_t *s;
Expand Down Expand Up @@ -233,7 +233,40 @@ ngx_tcp_proxy_init_upstream(ngx_connection_t *c, ngx_tcp_session_t *s)
}


static void
static void
ngx_tcp_proxy_send_proxy_protocol(ngx_tcp_session_t *s, ngx_tcp_upstream_t *u)
{
ngx_connection_t *c;
ngx_str_t proxy_line;
struct sockaddr_in *client, *listener;
u_char *src_addr, *dst_addr;

c = u->peer.connection;
c->log->action = "ngx_tcp_proxy_send_proxy_protocol";

client = (struct sockaddr_in*)s->connection->sockaddr;
listener = (struct sockaddr_in*)s->connection->local_sockaddr; // doesn't appear to be correct
src_addr = (u_char *)&client->sin_addr;
dst_addr = (u_char *)&listener->sin_addr;


ngx_log_debug0(NGX_LOG_DEBUG_TCP, c->log, 0, "sending proxy protocol");

// PROXY TCP4 <src ip> <dst ip> <src port> <dst port>\r\n
proxy_line.data = ngx_pnalloc(c->pool, 56); // maximum length for TCP4
proxy_line.len = ngx_sprintf(proxy_line.data,
"PROXY TCP4 %ud.%ud.%ud.%ud %ud.%ud.%ud.%ud %d %d\r\n",
src_addr[0], src_addr[1], src_addr[2], src_addr[3],
dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3],
client->sin_port,
listener->sin_port
) - proxy_line.data;

c->send(c, proxy_line.data, proxy_line.len);
}


static void
ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s, ngx_tcp_upstream_t *u)
{
ngx_connection_t *c;
Expand Down Expand Up @@ -284,30 +317,32 @@ ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s, ngx_tcp_upstream_t *u)

#if (NGX_TCP_SSL)

/*
/*
* The ssl connection with client may not trigger the read event again,
* So I trigger it in this function.
* */
if (s->connection->ssl) {
ngx_tcp_proxy_handler(s->connection->read);
ngx_tcp_proxy_handler(s->connection->read);
}

#endif

if (s->upstream->conf->upstream->accept_proxy > 0) {
ngx_tcp_proxy_send_proxy_protocol(s, u);
}
return;
}


static void
ngx_tcp_proxy_handler(ngx_event_t *ev)
ngx_tcp_proxy_handler(ngx_event_t *ev)
{
char *action, *recv_action, *send_action;
off_t *read_bytes, *write_bytes;
size_t size;
ssize_t n;
ngx_buf_t *b;
ngx_err_t err;
ngx_uint_t do_write, first_read;
ngx_uint_t do_write, first_read = 0;
ngx_connection_t *c, *src, *dst;
ngx_tcp_session_t *s;
ngx_tcp_proxy_conf_t *pcf;
Expand Down Expand Up @@ -431,7 +466,7 @@ ngx_tcp_proxy_handler(ngx_event_t *ev)
size = b->end - b->last;

if (size) {
if (src->read->ready || first_read) {
if (src->read->ready || first_read) {

first_read = 0;
c->log->action = recv_action;
Expand Down Expand Up @@ -522,7 +557,7 @@ ngx_tcp_proxy_handler(ngx_event_t *ev)


static char *
ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_tcp_proxy_conf_t *pcf = conf;

Expand Down Expand Up @@ -570,7 +605,7 @@ ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)


static void *
ngx_tcp_proxy_create_conf(ngx_conf_t *cf)
ngx_tcp_proxy_create_conf(ngx_conf_t *cf)
{
ngx_tcp_proxy_conf_t *pcf;

Expand All @@ -590,7 +625,7 @@ ngx_tcp_proxy_create_conf(ngx_conf_t *cf)


static char *
ngx_tcp_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_tcp_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_tcp_proxy_conf_t *prev = parent;
ngx_tcp_proxy_conf_t *conf = child;
Expand Down
7 changes: 7 additions & 0 deletions ngx_tcp_upstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ static ngx_command_t ngx_tcp_upstream_commands[] = {
offsetof(ngx_tcp_upstream_main_conf_t, check_shm_size),
NULL },

{ ngx_string("accept_proxy"),
NGX_TCP_UPS_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_TCP_SRV_CONF_OFFSET,
offsetof(ngx_tcp_upstream_srv_conf_t, accept_proxy),
NULL },
ngx_null_command
};

Expand Down Expand Up @@ -691,6 +697,7 @@ ngx_tcp_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
uscf->line = cf->conf_file->line;
uscf->port = u->port;
uscf->default_port = u->default_port;
uscf->accept_proxy = NGX_CONF_UNSET;
#if (nginx_version) >= 1003011
uscf->no_port = u->no_port;
#endif
Expand Down
1 change: 1 addition & 0 deletions ngx_tcp_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct ngx_tcp_upstream_srv_conf_s {

check_conf_t *check_type_conf;
ngx_str_t send;
ngx_flag_t accept_proxy;

union {
ngx_uint_t return_code;
Expand Down
Loading