Mercurial > hg > nginx-quic
comparison src/core/ngx_proxy_protocol.c @ 8957:3be953161026 quic
Merged with the default branch.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 20 Oct 2022 16:41:36 +0400 |
parents | aa663cc2a77d |
children | 17d6a537fb1b |
comparison
equal
deleted
inserted
replaced
8956:79cd6993a3e3 | 8957:3be953161026 |
---|---|
11 | 11 |
12 #define NGX_PROXY_PROTOCOL_AF_INET 1 | 12 #define NGX_PROXY_PROTOCOL_AF_INET 1 |
13 #define NGX_PROXY_PROTOCOL_AF_INET6 2 | 13 #define NGX_PROXY_PROTOCOL_AF_INET6 2 |
14 | 14 |
15 | 15 |
16 #define ngx_proxy_protocol_parse_uint16(p) ((p)[0] << 8 | (p)[1]) | 16 #define ngx_proxy_protocol_parse_uint16(p) \ |
17 ( ((uint16_t) (p)[0] << 8) \ | |
18 + ( (p)[1]) ) | |
19 | |
20 #define ngx_proxy_protocol_parse_uint32(p) \ | |
21 ( ((uint32_t) (p)[0] << 24) \ | |
22 + ( (p)[1] << 16) \ | |
23 + ( (p)[2] << 8) \ | |
24 + ( (p)[3]) ) | |
17 | 25 |
18 | 26 |
19 typedef struct { | 27 typedef struct { |
20 u_char signature[12]; | 28 u_char signature[12]; |
21 u_char version_command; | 29 u_char version_command; |
38 u_char src_port[2]; | 46 u_char src_port[2]; |
39 u_char dst_port[2]; | 47 u_char dst_port[2]; |
40 } ngx_proxy_protocol_inet6_addrs_t; | 48 } ngx_proxy_protocol_inet6_addrs_t; |
41 | 49 |
42 | 50 |
51 typedef struct { | |
52 u_char type; | |
53 u_char len[2]; | |
54 } ngx_proxy_protocol_tlv_t; | |
55 | |
56 | |
57 typedef struct { | |
58 u_char client; | |
59 u_char verify[4]; | |
60 } ngx_proxy_protocol_tlv_ssl_t; | |
61 | |
62 | |
63 typedef struct { | |
64 ngx_str_t name; | |
65 ngx_uint_t type; | |
66 } ngx_proxy_protocol_tlv_entry_t; | |
67 | |
68 | |
43 static u_char *ngx_proxy_protocol_read_addr(ngx_connection_t *c, u_char *p, | 69 static u_char *ngx_proxy_protocol_read_addr(ngx_connection_t *c, u_char *p, |
44 u_char *last, ngx_str_t *addr); | 70 u_char *last, ngx_str_t *addr); |
45 static u_char *ngx_proxy_protocol_read_port(u_char *p, u_char *last, | 71 static u_char *ngx_proxy_protocol_read_port(u_char *p, u_char *last, |
46 in_port_t *port, u_char sep); | 72 in_port_t *port, u_char sep); |
47 static u_char *ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, | 73 static u_char *ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, |
48 u_char *last); | 74 u_char *last); |
75 static ngx_int_t ngx_proxy_protocol_lookup_tlv(ngx_connection_t *c, | |
76 ngx_str_t *tlvs, ngx_uint_t type, ngx_str_t *value); | |
77 | |
78 | |
79 static ngx_proxy_protocol_tlv_entry_t ngx_proxy_protocol_tlv_entries[] = { | |
80 { ngx_string("alpn"), 0x01 }, | |
81 { ngx_string("authority"), 0x02 }, | |
82 { ngx_string("unique_id"), 0x05 }, | |
83 { ngx_string("ssl"), 0x20 }, | |
84 { ngx_string("netns"), 0x30 }, | |
85 { ngx_null_string, 0x00 } | |
86 }; | |
87 | |
88 | |
89 static ngx_proxy_protocol_tlv_entry_t ngx_proxy_protocol_tlv_ssl_entries[] = { | |
90 { ngx_string("version"), 0x21 }, | |
91 { ngx_string("cn"), 0x22 }, | |
92 { ngx_string("cipher"), 0x23 }, | |
93 { ngx_string("sig_alg"), 0x24 }, | |
94 { ngx_string("key_alg"), 0x25 }, | |
95 { ngx_null_string, 0x00 } | |
96 }; | |
49 | 97 |
50 | 98 |
51 u_char * | 99 u_char * |
52 ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) | 100 ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) |
53 { | 101 { |
137 } | 185 } |
138 } | 186 } |
139 | 187 |
140 invalid: | 188 invalid: |
141 | 189 |
190 for (p = buf; p < last; p++) { | |
191 if (*p == CR || *p == LF) { | |
192 break; | |
193 } | |
194 } | |
195 | |
142 ngx_log_error(NGX_LOG_ERR, c->log, 0, | 196 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
143 "broken header: \"%*s\"", (size_t) (last - buf), buf); | 197 "broken header: \"%*s\"", (size_t) (p - buf), buf); |
144 | 198 |
145 return NULL; | 199 return NULL; |
146 } | 200 } |
147 | 201 |
148 | 202 |
410 ngx_log_debug4(NGX_LOG_DEBUG_CORE, c->log, 0, | 464 ngx_log_debug4(NGX_LOG_DEBUG_CORE, c->log, 0, |
411 "PROXY protocol v2 src: %V %d, dst: %V %d", | 465 "PROXY protocol v2 src: %V %d, dst: %V %d", |
412 &pp->src_addr, pp->src_port, &pp->dst_addr, pp->dst_port); | 466 &pp->src_addr, pp->src_port, &pp->dst_addr, pp->dst_port); |
413 | 467 |
414 if (buf < end) { | 468 if (buf < end) { |
415 ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, | 469 pp->tlvs.data = ngx_pnalloc(c->pool, end - buf); |
416 "PROXY protocol v2 %z bytes of tlv ignored", end - buf); | 470 if (pp->tlvs.data == NULL) { |
471 return NULL; | |
472 } | |
473 | |
474 ngx_memcpy(pp->tlvs.data, buf, end - buf); | |
475 pp->tlvs.len = end - buf; | |
417 } | 476 } |
418 | 477 |
419 c->proxy_protocol = pp; | 478 c->proxy_protocol = pp; |
420 | 479 |
421 return end; | 480 return end; |
422 } | 481 } |
482 | |
483 | |
484 ngx_int_t | |
485 ngx_proxy_protocol_get_tlv(ngx_connection_t *c, ngx_str_t *name, | |
486 ngx_str_t *value) | |
487 { | |
488 u_char *p; | |
489 size_t n; | |
490 uint32_t verify; | |
491 ngx_str_t ssl, *tlvs; | |
492 ngx_int_t rc, type; | |
493 ngx_proxy_protocol_tlv_ssl_t *tlv_ssl; | |
494 ngx_proxy_protocol_tlv_entry_t *te; | |
495 | |
496 if (c->proxy_protocol == NULL) { | |
497 return NGX_DECLINED; | |
498 } | |
499 | |
500 ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, | |
501 "PROXY protocol v2 get tlv \"%V\"", name); | |
502 | |
503 te = ngx_proxy_protocol_tlv_entries; | |
504 tlvs = &c->proxy_protocol->tlvs; | |
505 | |
506 p = name->data; | |
507 n = name->len; | |
508 | |
509 if (n >= 4 && p[0] == 's' && p[1] == 's' && p[2] == 'l' && p[3] == '_') { | |
510 | |
511 rc = ngx_proxy_protocol_lookup_tlv(c, tlvs, 0x20, &ssl); | |
512 if (rc != NGX_OK) { | |
513 return rc; | |
514 } | |
515 | |
516 if (ssl.len < sizeof(ngx_proxy_protocol_tlv_ssl_t)) { | |
517 return NGX_ERROR; | |
518 } | |
519 | |
520 p += 4; | |
521 n -= 4; | |
522 | |
523 if (n == 6 && ngx_strncmp(p, "verify", 6) == 0) { | |
524 | |
525 tlv_ssl = (ngx_proxy_protocol_tlv_ssl_t *) ssl.data; | |
526 verify = ngx_proxy_protocol_parse_uint32(tlv_ssl->verify); | |
527 | |
528 value->data = ngx_pnalloc(c->pool, NGX_INT32_LEN); | |
529 if (value->data == NULL) { | |
530 return NGX_ERROR; | |
531 } | |
532 | |
533 value->len = ngx_sprintf(value->data, "%uD", verify) | |
534 - value->data; | |
535 return NGX_OK; | |
536 } | |
537 | |
538 ssl.data += sizeof(ngx_proxy_protocol_tlv_ssl_t); | |
539 ssl.len -= sizeof(ngx_proxy_protocol_tlv_ssl_t); | |
540 | |
541 te = ngx_proxy_protocol_tlv_ssl_entries; | |
542 tlvs = &ssl; | |
543 } | |
544 | |
545 if (n >= 2 && p[0] == '0' && p[1] == 'x') { | |
546 | |
547 type = ngx_hextoi(p + 2, n - 2); | |
548 if (type == NGX_ERROR) { | |
549 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
550 "invalid PROXY protocol TLV \"%V\"", name); | |
551 return NGX_ERROR; | |
552 } | |
553 | |
554 return ngx_proxy_protocol_lookup_tlv(c, tlvs, type, value); | |
555 } | |
556 | |
557 for ( /* void */ ; te->type; te++) { | |
558 if (te->name.len == n && ngx_strncmp(te->name.data, p, n) == 0) { | |
559 return ngx_proxy_protocol_lookup_tlv(c, tlvs, te->type, value); | |
560 } | |
561 } | |
562 | |
563 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
564 "unknown PROXY protocol TLV \"%V\"", name); | |
565 | |
566 return NGX_DECLINED; | |
567 } | |
568 | |
569 | |
570 static ngx_int_t | |
571 ngx_proxy_protocol_lookup_tlv(ngx_connection_t *c, ngx_str_t *tlvs, | |
572 ngx_uint_t type, ngx_str_t *value) | |
573 { | |
574 u_char *p; | |
575 size_t n, len; | |
576 ngx_proxy_protocol_tlv_t *tlv; | |
577 | |
578 ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, | |
579 "PROXY protocol v2 lookup tlv:%02xi", type); | |
580 | |
581 p = tlvs->data; | |
582 n = tlvs->len; | |
583 | |
584 while (n) { | |
585 if (n < sizeof(ngx_proxy_protocol_tlv_t)) { | |
586 ngx_log_error(NGX_LOG_ERR, c->log, 0, "broken PROXY protocol TLV"); | |
587 return NGX_ERROR; | |
588 } | |
589 | |
590 tlv = (ngx_proxy_protocol_tlv_t *) p; | |
591 len = ngx_proxy_protocol_parse_uint16(tlv->len); | |
592 | |
593 p += sizeof(ngx_proxy_protocol_tlv_t); | |
594 n -= sizeof(ngx_proxy_protocol_tlv_t); | |
595 | |
596 if (n < len) { | |
597 ngx_log_error(NGX_LOG_ERR, c->log, 0, "broken PROXY protocol TLV"); | |
598 return NGX_ERROR; | |
599 } | |
600 | |
601 if (tlv->type == type) { | |
602 value->data = p; | |
603 value->len = len; | |
604 return NGX_OK; | |
605 } | |
606 | |
607 p += len; | |
608 n -= len; | |
609 } | |
610 | |
611 return NGX_DECLINED; | |
612 } |