diff --git a/modules/ngx_tcp_generic_proxy_module.c b/modules/ngx_tcp_generic_proxy_module.c index 7af40ca..6c4e631 100644 --- a/modules/ngx_tcp_generic_proxy_module.c +++ b/modules/ngx_tcp_generic_proxy_module.c @@ -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); @@ -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; @@ -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; @@ -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; @@ -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 \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; @@ -284,22 +317,24 @@ 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; @@ -307,7 +342,7 @@ ngx_tcp_proxy_handler(ngx_event_t *ev) 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; @@ -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; @@ -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; @@ -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; @@ -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; diff --git a/ngx_tcp_upstream.c b/ngx_tcp_upstream.c index c880835..32e0e74 100644 --- a/ngx_tcp_upstream.c +++ b/ngx_tcp_upstream.c @@ -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 }; @@ -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 diff --git a/ngx_tcp_upstream.h b/ngx_tcp_upstream.h index 620af7d..98fb4c9 100644 --- a/ngx_tcp_upstream.h +++ b/ngx_tcp_upstream.h @@ -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; diff --git a/parsers/http_request_parser.c b/parsers/http_request_parser.c index 2bc32e0..d833e81 100644 --- a/parsers/http_request_parser.c +++ b/parsers/http_request_parser.c @@ -6,7 +6,7 @@ * You can redistribute it and/or modify it under the same terms as Ruby. */ -#include +#include #include #include @@ -32,14 +32,12 @@ static const int http_request_parser_start = 1; static const int http_request_parser_first_final = 57; static const int http_request_parser_error = 0; -static const int http_request_parser_en_main = 1; - #line 130 "http_request_parser.rl" int http_request_parser_init(http_request_parser *parser) { int cs = 0; - + #line 44 "http_request_parser.c" { cs = http_request_parser_start; @@ -52,7 +50,7 @@ int http_request_parser_init(http_request_parser *parser) { parser->mark = 0; parser->nread = 0; parser->field_len = 0; - parser->field_start = 0; + parser->field_start = 0; return(1); } @@ -68,7 +66,7 @@ size_t http_request_parser_execute(http_request_parser *parser, const signed cha p = buffer + off; pe = buffer + len; - + #line 73 "http_request_parser.c" { if ( p == pe ) @@ -117,8 +115,8 @@ case 2: goto st0; tr2: #line 40 "http_request_parser.rl" - { - if(parser->request_method != NULL) + { + if(parser->request_method != NULL) parser->request_method(parser->data, PTR_TO(mark), LEN(mark, p)); } goto st3; @@ -158,7 +156,7 @@ case 4: goto st0; tr8: #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -186,7 +184,7 @@ case 4: parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p)); } #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -195,24 +193,24 @@ case 4: #line 53 "http_request_parser.rl" {MARK(query_start, p); } #line 54 "http_request_parser.rl" - { + { if(parser->query_string != NULL) parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); } #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } goto st5; tr57: #line 54 "http_request_parser.rl" - { + { if(parser->query_string != NULL) parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); } #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -292,7 +290,7 @@ case 13: goto st0; tr18: #line 59 "http_request_parser.rl" - { + { if(parser->http_version != NULL) parser->http_version(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -360,8 +358,8 @@ case 16: goto st0; tr22: #line 69 "http_request_parser.rl" - { - parser->body_start = p - buffer + 1; + { + parser->body_start = p - buffer + 1; if(parser->header_done != NULL) parser->header_done(parser->data, p + 1, pe - p - 1); {p++; cs = 57; goto _out;} @@ -408,7 +406,7 @@ case 17: goto st0; tr24: #line 30 "http_request_parser.rl" - { + { parser->field_len = LEN(field_start, p); } goto st18; @@ -440,7 +438,7 @@ case 19: goto st19; tr9: #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -452,7 +450,7 @@ case 19: parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p)); } #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -461,24 +459,24 @@ case 19: #line 53 "http_request_parser.rl" {MARK(query_start, p); } #line 54 "http_request_parser.rl" - { + { if(parser->query_string != NULL) parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); } #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } goto st20; tr58: #line 54 "http_request_parser.rl" - { + { if(parser->query_string != NULL) parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); } #line 44 "http_request_parser.rl" - { + { if(parser->request_uri != NULL) parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -1134,62 +1132,62 @@ case 56: goto tr2; goto st0; } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof57: cs = 57; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof28: cs = 28; goto _test_eof; - _test_eof29: cs = 29; goto _test_eof; - _test_eof30: cs = 30; goto _test_eof; - _test_eof31: cs = 31; goto _test_eof; - _test_eof32: cs = 32; goto _test_eof; - _test_eof33: cs = 33; goto _test_eof; - _test_eof34: cs = 34; goto _test_eof; - _test_eof35: cs = 35; goto _test_eof; - _test_eof36: cs = 36; goto _test_eof; - _test_eof37: cs = 37; goto _test_eof; - _test_eof38: cs = 38; goto _test_eof; - _test_eof39: cs = 39; goto _test_eof; - _test_eof40: cs = 40; goto _test_eof; - _test_eof41: cs = 41; goto _test_eof; - _test_eof42: cs = 42; goto _test_eof; - _test_eof43: cs = 43; goto _test_eof; - _test_eof44: cs = 44; goto _test_eof; - _test_eof45: cs = 45; goto _test_eof; - _test_eof46: cs = 46; goto _test_eof; - _test_eof47: cs = 47; goto _test_eof; - _test_eof48: cs = 48; goto _test_eof; - _test_eof49: cs = 49; goto _test_eof; - _test_eof50: cs = 50; goto _test_eof; - _test_eof51: cs = 51; goto _test_eof; - _test_eof52: cs = 52; goto _test_eof; - _test_eof53: cs = 53; goto _test_eof; - _test_eof54: cs = 54; goto _test_eof; - _test_eof55: cs = 55; goto _test_eof; - _test_eof56: cs = 56; goto _test_eof; + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof57: cs = 57; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof18: cs = 18; goto _test_eof; + _test_eof19: cs = 19; goto _test_eof; + _test_eof20: cs = 20; goto _test_eof; + _test_eof21: cs = 21; goto _test_eof; + _test_eof22: cs = 22; goto _test_eof; + _test_eof23: cs = 23; goto _test_eof; + _test_eof24: cs = 24; goto _test_eof; + _test_eof25: cs = 25; goto _test_eof; + _test_eof26: cs = 26; goto _test_eof; + _test_eof27: cs = 27; goto _test_eof; + _test_eof28: cs = 28; goto _test_eof; + _test_eof29: cs = 29; goto _test_eof; + _test_eof30: cs = 30; goto _test_eof; + _test_eof31: cs = 31; goto _test_eof; + _test_eof32: cs = 32; goto _test_eof; + _test_eof33: cs = 33; goto _test_eof; + _test_eof34: cs = 34; goto _test_eof; + _test_eof35: cs = 35; goto _test_eof; + _test_eof36: cs = 36; goto _test_eof; + _test_eof37: cs = 37; goto _test_eof; + _test_eof38: cs = 38; goto _test_eof; + _test_eof39: cs = 39; goto _test_eof; + _test_eof40: cs = 40; goto _test_eof; + _test_eof41: cs = 41; goto _test_eof; + _test_eof42: cs = 42; goto _test_eof; + _test_eof43: cs = 43; goto _test_eof; + _test_eof44: cs = 44; goto _test_eof; + _test_eof45: cs = 45; goto _test_eof; + _test_eof46: cs = 46; goto _test_eof; + _test_eof47: cs = 47; goto _test_eof; + _test_eof48: cs = 48; goto _test_eof; + _test_eof49: cs = 49; goto _test_eof; + _test_eof50: cs = 50; goto _test_eof; + _test_eof51: cs = 51; goto _test_eof; + _test_eof52: cs = 52; goto _test_eof; + _test_eof53: cs = 53; goto _test_eof; + _test_eof54: cs = 54; goto _test_eof; + _test_eof55: cs = 55; goto _test_eof; + _test_eof56: cs = 56; goto _test_eof; _test_eof: {} _out: {} diff --git a/parsers/http_response_parser.c b/parsers/http_response_parser.c index 76d4c20..a001e6f 100644 --- a/parsers/http_response_parser.c +++ b/parsers/http_response_parser.c @@ -27,14 +27,12 @@ static const int http_response_parser_start = 1; static const int http_response_parser_first_final = 20; static const int http_response_parser_error = 0; -static const int http_response_parser_en_main = 1; - #line 92 "http_response_parser.rl" int http_response_parser_init(http_response_parser *parser) { int cs = 0; - + #line 39 "http_response_parser.c" { cs = http_response_parser_start; @@ -47,7 +45,7 @@ int http_response_parser_init(http_response_parser *parser) { parser->mark = 0; parser->nread = 0; parser->field_len = 0; - parser->field_start = 0; + parser->field_start = 0; return(1); } @@ -63,7 +61,7 @@ size_t http_response_parser_execute(http_response_parser *parser, const signed c p = buffer + off; pe = buffer + len; - + #line 68 "http_response_parser.c" { if ( p == pe ) @@ -144,7 +142,7 @@ case 9: goto st0; tr9: #line 36 "http_response_parser.rl" - { + { if(parser->http_version != NULL) parser->http_version(parser->data, PTR_TO(mark), LEN(mark, p)); } @@ -279,8 +277,8 @@ case 16: goto st0; tr19: #line 51 "http_response_parser.rl" - { - parser->body_start = p - buffer + 1; + { + parser->body_start = p - buffer + 1; if(parser->header_done != NULL) parser->header_done(parser->data, p + 1, pe - p - 1); {p++; cs = 20; goto _out;} @@ -327,7 +325,7 @@ case 17: goto st0; tr21: #line 24 "http_response_parser.rl" - { + { parser->field_len = LEN(field_start, p); } goto st18; @@ -358,25 +356,25 @@ case 19: goto tr26; goto st19; } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof20: cs = 20; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof18: cs = 18; goto _test_eof; + _test_eof19: cs = 19; goto _test_eof; _test_eof: {} _out: {} diff --git a/parsers/smtp_response_parser.c b/parsers/smtp_response_parser.c index c3d2016..fb20b58 100644 --- a/parsers/smtp_response_parser.c +++ b/parsers/smtp_response_parser.c @@ -26,9 +26,6 @@ static const int smtp_parser_start = 1; static const int smtp_parser_first_final = 429; static const int smtp_parser_error = 0; -static const int smtp_parser_en_main = 1; - - #line 112 "smtp_response_parser.rl" int smtp_parser_init(smtp_parser *parser) {