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 }