1616
1717
1818typedef  struct  {
19-     ngx_array_t        * from ;     /* array of ngx_in_cidr_t  */ 
19+     ngx_array_t        * from ;     /* array of ngx_cidr_t  */ 
2020    ngx_uint_t          type ;
2121    ngx_uint_t          hash ;
2222    ngx_str_t           header ;
23- #if  (NGX_HAVE_UNIX_DOMAIN )
24-     ngx_uint_t          unixsock ; /* unsigned  unixsock:2; */ 
25- #endif 
23+     ngx_flag_t          recursive ;
2624} ngx_http_realip_loc_conf_t ;
2725
2826
@@ -35,8 +33,8 @@ typedef struct {
3533
3634
3735static  ngx_int_t  ngx_http_realip_handler (ngx_http_request_t  * r );
38- static  ngx_int_t  ngx_http_realip_set_addr (ngx_http_request_t  * r ,  u_char   * ip , 
39-     size_t   len );
36+ static  ngx_int_t  ngx_http_realip_set_addr (ngx_http_request_t  * r ,
37+     ngx_addr_t   * addr );
4038static  void  ngx_http_realip_cleanup (void  * data );
4139static  char  * ngx_http_realip_from (ngx_conf_t  * cf , ngx_command_t  * cmd ,
4240    void  * conf );
@@ -63,6 +61,13 @@ static ngx_command_t  ngx_http_realip_commands[] = {
6361      0 ,
6462      NULL  },
6563
64+     { ngx_string ("real_ip_recursive" ),
65+       NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_FLAG ,
66+       ngx_conf_set_flag_slot ,
67+       NGX_HTTP_LOC_CONF_OFFSET ,
68+       offsetof(ngx_http_realip_loc_conf_t , recursive ),
69+       NULL  },
70+ 
6671      ngx_null_command 
6772};
6873
@@ -105,10 +110,9 @@ ngx_http_realip_handler(ngx_http_request_t *r)
105110    u_char                       * ip , * p ;
106111    size_t                        len ;
107112    ngx_uint_t                    i , hash ;
113+     ngx_addr_t                    addr ;
108114    ngx_list_part_t              * part ;
109115    ngx_table_elt_t              * header ;
110-     struct  sockaddr_in           * sin ;
111-     ngx_in_cidr_t                * from ;
112116    ngx_connection_t             * c ;
113117    ngx_http_realip_ctx_t        * ctx ;
114118    ngx_http_realip_loc_conf_t   * rlcf ;
@@ -121,12 +125,7 @@ ngx_http_realip_handler(ngx_http_request_t *r)
121125
122126    rlcf  =  ngx_http_get_module_loc_conf (r , ngx_http_realip_module );
123127
124-     if  (rlcf -> from  ==  NULL 
125- #if  (NGX_HAVE_UNIX_DOMAIN )
126-         &&  !rlcf -> unixsock 
127- #endif 
128-        )
129-     {
128+     if  (rlcf -> from  ==  NULL ) {
130129        return  NGX_DECLINED ;
131130    }
132131
@@ -152,15 +151,6 @@ ngx_http_realip_handler(ngx_http_request_t *r)
152151        len  =  r -> headers_in .x_forwarded_for -> value .len ;
153152        ip  =  r -> headers_in .x_forwarded_for -> value .data ;
154153
155-         for  (p  =  ip  +  len  -  1 ; p  >  ip ; p -- ) {
156-             if  (* p  ==  ' '  ||  * p  ==  ',' ) {
157-                 p ++ ;
158-                 len  -=  p  -  ip ;
159-                 ip  =  p ;
160-                 break ;
161-             }
162-         }
163- 
164154        break ;
165155
166156    default : /* NGX_HTTP_REALIP_HEADER */ 
@@ -204,42 +194,27 @@ ngx_http_realip_handler(ngx_http_request_t *r)
204194
205195    ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , c -> log , 0 , "realip: \"%s\"" , ip );
206196
207-     /* AF_INET only */ 
208- 
209-     if  (c -> sockaddr -> sa_family  ==  AF_INET ) {
210-         sin  =  (struct  sockaddr_in  * ) c -> sockaddr ;
211- 
212-         from  =  rlcf -> from -> elts ;
213-         for  (i  =  0 ; i  <  rlcf -> from -> nelts ; i ++ ) {
197+     addr .sockaddr  =  c -> sockaddr ;
198+     addr .socklen  =  c -> socklen ;
199+     /* addr.name = c->addr_text; */ 
214200
215-             ngx_log_debug3 (NGX_LOG_DEBUG_HTTP , c -> log , 0 ,
216-                            "realip: %08XD %08XD %08XD" ,
217-                            sin -> sin_addr .s_addr , from [i ].mask , from [i ].addr );
218- 
219-             if  ((sin -> sin_addr .s_addr  &  from [i ].mask ) ==  from [i ].addr ) {
220-                 return  ngx_http_realip_set_addr (r , ip , len );
221-             }
222-         }
223-     }
224- 
225- #if  (NGX_HAVE_UNIX_DOMAIN )
226- 
227-     if  (c -> sockaddr -> sa_family  ==  AF_UNIX  &&  rlcf -> unixsock ) {
228-         return  ngx_http_realip_set_addr (r , ip , len );
201+     if  (ngx_http_get_forwarded_addr (r , & addr , ip , len , rlcf -> from ,
202+                                     rlcf -> recursive )
203+         ==  NGX_OK )
204+     {
205+         return  ngx_http_realip_set_addr (r , & addr );
229206    }
230207
231- #endif 
232- 
233208    return  NGX_DECLINED ;
234209}
235210
236211
237212static  ngx_int_t 
238- ngx_http_realip_set_addr (ngx_http_request_t  * r , u_char   * ip ,  size_t   len )
213+ ngx_http_realip_set_addr (ngx_http_request_t  * r , ngx_addr_t   * addr )
239214{
215+     size_t                   len ;
240216    u_char                  * p ;
241-     ngx_int_t                rc ;
242-     ngx_addr_t               addr ;
217+     u_char                   text [NGX_SOCKADDR_STRLEN ];
243218    ngx_connection_t        * c ;
244219    ngx_pool_cleanup_t      * cln ;
245220    ngx_http_realip_ctx_t   * ctx ;
@@ -254,23 +229,17 @@ ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
254229
255230    c  =  r -> connection ;
256231
257-     rc  =  ngx_parse_addr (c -> pool , & addr , ip , len );
258- 
259-     switch  (rc ) {
260-     case  NGX_DECLINED :
261-         return  NGX_DECLINED ;
262-     case  NGX_ERROR :
232+     len  =  ngx_sock_ntop (addr -> sockaddr , text , NGX_SOCKADDR_STRLEN , 0 );
233+     if  (len  ==  0 ) {
263234        return  NGX_HTTP_INTERNAL_SERVER_ERROR ;
264-     default : /* NGX_OK */ 
265-         break ;
266235    }
267236
268237    p  =  ngx_pnalloc (c -> pool , len );
269238    if  (p  ==  NULL ) {
270239        return  NGX_HTTP_INTERNAL_SERVER_ERROR ;
271240    }
272241
273-     ngx_memcpy (p , ip , len );
242+     ngx_memcpy (p , text , len );
274243
275244    cln -> handler  =  ngx_http_realip_cleanup ;
276245
@@ -279,8 +248,8 @@ ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
279248    ctx -> socklen  =  c -> socklen ;
280249    ctx -> addr_text  =  c -> addr_text ;
281250
282-     c -> sockaddr  =  addr . sockaddr ;
283-     c -> socklen  =  addr . socklen ;
251+     c -> sockaddr  =  addr -> sockaddr ;
252+     c -> socklen  =  addr -> socklen ;
284253    c -> addr_text .len  =  len ;
285254    c -> addr_text .data  =  p ;
286255
@@ -310,55 +279,45 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
310279
311280    ngx_int_t                 rc ;
312281    ngx_str_t                * value ;
313-     ngx_cidr_t                cidr ;
314-     ngx_in_cidr_t            * from ;
282+     ngx_cidr_t               * cidr ;
315283
316284    value  =  cf -> args -> elts ;
317285
318- #if  (NGX_HAVE_UNIX_DOMAIN )
319- 
320-     if  (ngx_strcmp (value [1 ].data , "unix:" ) ==  0 ) {
321-          rlcf -> unixsock  =  1 ;
322-          return  NGX_CONF_OK ;
323-     }
324- 
325- #endif 
326- 
327286    if  (rlcf -> from  ==  NULL ) {
328287        rlcf -> from  =  ngx_array_create (cf -> pool , 2 ,
329-                                       sizeof (ngx_in_cidr_t ));
288+                                       sizeof (ngx_cidr_t ));
330289        if  (rlcf -> from  ==  NULL ) {
331290            return  NGX_CONF_ERROR ;
332291        }
333292    }
334293
335-     from  =  ngx_array_push (rlcf -> from );
336-     if  (from  ==  NULL ) {
294+     cidr  =  ngx_array_push (rlcf -> from );
295+     if  (cidr  ==  NULL ) {
337296        return  NGX_CONF_ERROR ;
338297    }
339298
340-     rc  =  ngx_ptocidr (& value [1 ], & cidr );
299+ #if  (NGX_HAVE_UNIX_DOMAIN )
300+ 
301+     if  (ngx_strcmp (value [1 ].data , "unix:" ) ==  0 ) {
302+          cidr -> family  =  AF_UNIX ;
303+          return  NGX_CONF_OK ;
304+     }
305+ 
306+ #endif 
307+ 
308+     rc  =  ngx_ptocidr (& value [1 ], cidr );
341309
342310    if  (rc  ==  NGX_ERROR ) {
343311        ngx_conf_log_error (NGX_LOG_EMERG , cf , 0 , "invalid parameter \"%V\"" ,
344312                           & value [1 ]);
345313        return  NGX_CONF_ERROR ;
346314    }
347315
348-     if  (cidr .family  !=  AF_INET ) {
349-         ngx_conf_log_error (NGX_LOG_EMERG , cf , 0 ,
350-                            "\"set_real_ip_from\" supports IPv4 only" );
351-         return  NGX_CONF_ERROR ;
352-     }
353- 
354316    if  (rc  ==  NGX_DONE ) {
355317        ngx_conf_log_error (NGX_LOG_WARN , cf , 0 ,
356318                           "low address bits of %V are meaningless" , & value [1 ]);
357319    }
358320
359-     from -> mask  =  cidr .u .in .mask ;
360-     from -> addr  =  cidr .u .in .addr ;
361- 
362321    return  NGX_CONF_OK ;
363322}
364323
@@ -409,9 +368,7 @@ ngx_http_realip_create_loc_conf(ngx_conf_t *cf)
409368     */ 
410369
411370    conf -> type  =  NGX_CONF_UNSET_UINT ;
412- #if  (NGX_HAVE_UNIX_DOMAIN )
413-     conf -> unixsock  =  2 ;
414- #endif 
371+     conf -> recursive  =  NGX_CONF_UNSET ;
415372
416373    return  conf ;
417374}
@@ -427,13 +384,8 @@ ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
427384        conf -> from  =  prev -> from ;
428385    }
429386
430- #if  (NGX_HAVE_UNIX_DOMAIN )
431-     if  (conf -> unixsock  ==  2 ) {
432-         conf -> unixsock  =  (prev -> unixsock  ==  2 ) ? 0  : prev -> unixsock ;
433-     }
434- #endif 
435- 
436387    ngx_conf_merge_uint_value (conf -> type , prev -> type , NGX_HTTP_REALIP_XREALIP );
388+     ngx_conf_merge_value (conf -> recursive , prev -> recursive , 0 );
437389
438390    if  (conf -> header .len  ==  0 ) {
439391        conf -> hash  =  prev -> hash ;
0 commit comments