@@ -49,7 +49,7 @@ static char ipaddr_buf[100];
49
49
50
50
static void client_sockaddr (int fd , struct sockaddr_storage * ss , socklen_t * ss_len );
51
51
static int check_name (const char * ipaddr , const struct sockaddr_storage * ss , char * name_buf , size_t name_buf_size );
52
- static int valid_ipaddr (const char * s );
52
+ static int valid_ipaddr (const char * s , int allow_scope );
53
53
54
54
/* Return the IP addr of the client as a string. */
55
55
char * client_addr (int fd )
@@ -73,7 +73,7 @@ char *client_addr(int fd)
73
73
if ((p = strchr (ipaddr_buf , ' ' )) != NULL )
74
74
* p = '\0' ;
75
75
}
76
- if (valid_ipaddr (ipaddr_buf ))
76
+ if (valid_ipaddr (ipaddr_buf , True ))
77
77
return ipaddr_buf ;
78
78
}
79
79
@@ -213,13 +213,13 @@ int read_proxy_protocol_header(int fd)
213
213
if (size != sizeof hdr .v2 .addr .ip4 )
214
214
return 0 ;
215
215
inet_ntop (AF_INET , hdr .v2 .addr .ip4 .src_addr , ipaddr_buf , sizeof ipaddr_buf );
216
- return valid_ipaddr (ipaddr_buf );
216
+ return valid_ipaddr (ipaddr_buf , False );
217
217
#ifdef INET6
218
218
case PROXY_FAM_TCPv6 :
219
219
if (size != sizeof hdr .v2 .addr .ip6 )
220
220
return 0 ;
221
221
inet_ntop (AF_INET6 , hdr .v2 .addr .ip6 .src_addr , ipaddr_buf , sizeof ipaddr_buf );
222
- return valid_ipaddr (ipaddr_buf );
222
+ return valid_ipaddr (ipaddr_buf , False );
223
223
#endif
224
224
default :
225
225
break ;
@@ -276,15 +276,15 @@ int read_proxy_protocol_header(int fd)
276
276
if ((sp = strchr (p , ' ' )) == NULL )
277
277
return 0 ;
278
278
* sp = '\0' ;
279
- if (!valid_ipaddr (p ))
279
+ if (!valid_ipaddr (p , False ))
280
280
return 0 ;
281
281
strlcpy (ipaddr_buf , p , sizeof ipaddr_buf ); /* It will always fit when valid. */
282
282
283
283
p = sp + 1 ;
284
284
if ((sp = strchr (p , ' ' )) == NULL )
285
285
return 0 ;
286
286
* sp = '\0' ;
287
- if (!valid_ipaddr (p ))
287
+ if (!valid_ipaddr (p , False ))
288
288
return 0 ;
289
289
/* Ignore destination address. */
290
290
@@ -466,7 +466,7 @@ static int check_name(const char *ipaddr, const struct sockaddr_storage *ss, cha
466
466
}
467
467
468
468
/* Returns 1 for a valid IPv4 or IPv6 addr, or 0 for a bad one. */
469
- static int valid_ipaddr (const char * s )
469
+ static int valid_ipaddr (const char * s , int allow_scope )
470
470
{
471
471
int i ;
472
472
@@ -484,6 +484,11 @@ static int valid_ipaddr(const char *s)
484
484
for (count = 0 ; count < 8 ; count ++ ) {
485
485
if (!* s )
486
486
return saw_double_colon ;
487
+ if (allow_scope && * s == '%' ) {
488
+ if (saw_double_colon )
489
+ break ;
490
+ return 0 ;
491
+ }
487
492
488
493
if (strchr (s , ':' ) == NULL && strchr (s , '.' ) != NULL ) {
489
494
if ((!saw_double_colon && count != 6 ) || (saw_double_colon && count > 6 ))
@@ -509,8 +514,11 @@ static int valid_ipaddr(const char *s)
509
514
}
510
515
}
511
516
512
- if (!ipv4_at_end )
513
- return !* s ;
517
+ if (!ipv4_at_end ) {
518
+ if (allow_scope && * s == '%' )
519
+ for (s ++ ; isAlNum (s ); s ++ ) { }
520
+ return !* s && s [-1 ] != '%' ;
521
+ }
514
522
}
515
523
516
524
/* IPv4 */
0 commit comments