13
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
27
typedef struct {
@@ -40,12 +48,52 @@ typedef struct {
40
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
69
static u_char * ngx_proxy_protocol_read_addr (ngx_connection_t * c , u_char * p ,
44
70
u_char * last , ngx_str_t * addr );
45
71
static u_char * ngx_proxy_protocol_read_port (u_char * p , u_char * last ,
46
72
in_port_t * port , u_char sep );
47
73
static u_char * ngx_proxy_protocol_v2_read (ngx_connection_t * c , u_char * buf ,
48
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
99
u_char *
@@ -139,8 +187,14 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)
139
187
140
188
invalid :
141
189
190
+ for (p = buf ; p < last ; p ++ ) {
191
+ if (* p == CR || * p == LF ) {
192
+ break ;
193
+ }
194
+ }
195
+
142
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
199
return NULL ;
146
200
}
@@ -412,11 +466,147 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last)
412
466
& pp -> src_addr , pp -> src_port , & pp -> dst_addr , pp -> dst_port );
413
467
414
468
if (buf < end ) {
415
- ngx_log_debug1 (NGX_LOG_DEBUG_CORE , c -> log , 0 ,
416
- "PROXY protocol v2 %z bytes of tlv ignored" , end - buf );
469
+ pp -> tlvs .data = ngx_pnalloc (c -> pool , 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
478
c -> proxy_protocol = pp ;
420
479
421
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
+ }
0 commit comments