xref: /unit/src/nxt_http_route_addr.c (revision 1324)
1*1324Saxel.duch@nginx.com 
2*1324Saxel.duch@nginx.com /*
3*1324Saxel.duch@nginx.com  * Copyright (C) Axel Duch
4*1324Saxel.duch@nginx.com  * Copyright (C) NGINX, Inc.
5*1324Saxel.duch@nginx.com  */
6*1324Saxel.duch@nginx.com 
7*1324Saxel.duch@nginx.com #include <nxt_main.h>
8*1324Saxel.duch@nginx.com #include <nxt_http_route_addr.h>
9*1324Saxel.duch@nginx.com 
10*1324Saxel.duch@nginx.com 
11*1324Saxel.duch@nginx.com static nxt_bool_t nxt_str_looks_like_ipv6(const nxt_str_t *str);
12*1324Saxel.duch@nginx.com #if (NXT_INET6)
13*1324Saxel.duch@nginx.com static nxt_bool_t nxt_valid_ipv6_blocks(u_char *c, size_t len);
14*1324Saxel.duch@nginx.com #endif
15*1324Saxel.duch@nginx.com 
16*1324Saxel.duch@nginx.com 
17*1324Saxel.duch@nginx.com nxt_int_t
18*1324Saxel.duch@nginx.com nxt_http_route_addr_pattern_parse(nxt_mp_t *mp,
19*1324Saxel.duch@nginx.com     nxt_http_route_addr_pattern_t *pattern, nxt_conf_value_t *cv)
20*1324Saxel.duch@nginx.com {
21*1324Saxel.duch@nginx.com     u_char                       *delim, *end;
22*1324Saxel.duch@nginx.com     nxt_int_t                    ret, cidr_prefix;
23*1324Saxel.duch@nginx.com     nxt_str_t                    addr, port;
24*1324Saxel.duch@nginx.com     nxt_http_route_addr_base_t   *base;
25*1324Saxel.duch@nginx.com     nxt_http_route_addr_range_t  *inet;
26*1324Saxel.duch@nginx.com 
27*1324Saxel.duch@nginx.com     if (nxt_conf_type(cv) != NXT_CONF_STRING) {
28*1324Saxel.duch@nginx.com         return NXT_ADDR_PATTERN_CV_TYPE_ERROR;
29*1324Saxel.duch@nginx.com     }
30*1324Saxel.duch@nginx.com 
31*1324Saxel.duch@nginx.com     nxt_conf_get_string(cv, &addr);
32*1324Saxel.duch@nginx.com 
33*1324Saxel.duch@nginx.com     base = &pattern->base;
34*1324Saxel.duch@nginx.com 
35*1324Saxel.duch@nginx.com     if (addr.length > 0 && addr.start[0] == '!') {
36*1324Saxel.duch@nginx.com         addr.start++;
37*1324Saxel.duch@nginx.com         addr.length--;
38*1324Saxel.duch@nginx.com 
39*1324Saxel.duch@nginx.com         base->negative = 1;
40*1324Saxel.duch@nginx.com 
41*1324Saxel.duch@nginx.com     } else {
42*1324Saxel.duch@nginx.com         base->negative = 0;
43*1324Saxel.duch@nginx.com     }
44*1324Saxel.duch@nginx.com 
45*1324Saxel.duch@nginx.com     if (nxt_slow_path(addr.length < 2)) {
46*1324Saxel.duch@nginx.com         return NXT_ADDR_PATTERN_LENGTH_ERROR;
47*1324Saxel.duch@nginx.com     }
48*1324Saxel.duch@nginx.com 
49*1324Saxel.duch@nginx.com     nxt_str_null(&port);
50*1324Saxel.duch@nginx.com 
51*1324Saxel.duch@nginx.com     if (addr.start[0] == '*' && addr.start[1] == ':') {
52*1324Saxel.duch@nginx.com         port.start = addr.start + 2;
53*1324Saxel.duch@nginx.com         port.length = addr.length - 2;
54*1324Saxel.duch@nginx.com         base->addr_family = AF_UNSPEC;
55*1324Saxel.duch@nginx.com         base->match_type = NXT_HTTP_ROUTE_ADDR_ANY;
56*1324Saxel.duch@nginx.com 
57*1324Saxel.duch@nginx.com         goto parse_port;
58*1324Saxel.duch@nginx.com     }
59*1324Saxel.duch@nginx.com 
60*1324Saxel.duch@nginx.com     if (nxt_str_looks_like_ipv6(&addr)) {
61*1324Saxel.duch@nginx.com #if (NXT_INET6)
62*1324Saxel.duch@nginx.com         uint8_t                          i;
63*1324Saxel.duch@nginx.com         nxt_int_t                        len;
64*1324Saxel.duch@nginx.com         nxt_http_route_in6_addr_range_t  *inet6;
65*1324Saxel.duch@nginx.com 
66*1324Saxel.duch@nginx.com         base->addr_family = AF_INET6;
67*1324Saxel.duch@nginx.com 
68*1324Saxel.duch@nginx.com         if (addr.start[0] == '[') {
69*1324Saxel.duch@nginx.com             addr.start++;
70*1324Saxel.duch@nginx.com             addr.length--;
71*1324Saxel.duch@nginx.com 
72*1324Saxel.duch@nginx.com             end = addr.start + addr.length;
73*1324Saxel.duch@nginx.com 
74*1324Saxel.duch@nginx.com             port.start = nxt_rmemstrn(addr.start, end, "]:", 2);
75*1324Saxel.duch@nginx.com             if (nxt_slow_path(port.start == NULL)) {
76*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_FORMAT_ERROR;
77*1324Saxel.duch@nginx.com             }
78*1324Saxel.duch@nginx.com 
79*1324Saxel.duch@nginx.com             addr.length = port.start - addr.start;
80*1324Saxel.duch@nginx.com             port.start += nxt_length("]:");
81*1324Saxel.duch@nginx.com             port.length = end - port.start;
82*1324Saxel.duch@nginx.com         }
83*1324Saxel.duch@nginx.com 
84*1324Saxel.duch@nginx.com         inet6 = &pattern->addr.v6;
85*1324Saxel.duch@nginx.com 
86*1324Saxel.duch@nginx.com         delim = nxt_memchr(addr.start, '-', addr.length);
87*1324Saxel.duch@nginx.com         if (delim != NULL) {
88*1324Saxel.duch@nginx.com             len = delim - addr.start;
89*1324Saxel.duch@nginx.com             if (nxt_slow_path(!nxt_valid_ipv6_blocks(addr.start, len))) {
90*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_FORMAT_ERROR;
91*1324Saxel.duch@nginx.com             }
92*1324Saxel.duch@nginx.com 
93*1324Saxel.duch@nginx.com             ret = nxt_inet6_addr(&inet6->start, addr.start, len);
94*1324Saxel.duch@nginx.com             if (nxt_slow_path(ret != NXT_OK)) {
95*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_FORMAT_ERROR;
96*1324Saxel.duch@nginx.com             }
97*1324Saxel.duch@nginx.com 
98*1324Saxel.duch@nginx.com             len = addr.start + addr.length - delim - 1;
99*1324Saxel.duch@nginx.com             if (nxt_slow_path(!nxt_valid_ipv6_blocks(delim + 1, len))) {
100*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_FORMAT_ERROR;
101*1324Saxel.duch@nginx.com             }
102*1324Saxel.duch@nginx.com 
103*1324Saxel.duch@nginx.com             ret = nxt_inet6_addr(&inet6->end, delim + 1, len);
104*1324Saxel.duch@nginx.com             if (nxt_slow_path(ret != NXT_OK)) {
105*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_FORMAT_ERROR;
106*1324Saxel.duch@nginx.com             }
107*1324Saxel.duch@nginx.com 
108*1324Saxel.duch@nginx.com             if (nxt_slow_path(nxt_memcmp(&inet6->start, &inet6->end,
109*1324Saxel.duch@nginx.com                                          sizeof(struct in6_addr)) > 0))
110*1324Saxel.duch@nginx.com             {
111*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_RANGE_OVERLAP_ERROR;
112*1324Saxel.duch@nginx.com             }
113*1324Saxel.duch@nginx.com 
114*1324Saxel.duch@nginx.com             base->match_type = NXT_HTTP_ROUTE_ADDR_RANGE;
115*1324Saxel.duch@nginx.com 
116*1324Saxel.duch@nginx.com             goto parse_port;
117*1324Saxel.duch@nginx.com         }
118*1324Saxel.duch@nginx.com 
119*1324Saxel.duch@nginx.com         delim = nxt_memchr(addr.start, '/', addr.length);
120*1324Saxel.duch@nginx.com         if (delim != NULL) {
121*1324Saxel.duch@nginx.com             cidr_prefix = nxt_int_parse(delim + 1,
122*1324Saxel.duch@nginx.com                                         addr.start + addr.length - (delim + 1));
123*1324Saxel.duch@nginx.com             if (nxt_slow_path(cidr_prefix < 0 || cidr_prefix > 128)) {
124*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_CIDR_ERROR;
125*1324Saxel.duch@nginx.com             }
126*1324Saxel.duch@nginx.com 
127*1324Saxel.duch@nginx.com             addr.length = delim - addr.start;
128*1324Saxel.duch@nginx.com             if (nxt_slow_path(!nxt_valid_ipv6_blocks(addr.start,
129*1324Saxel.duch@nginx.com                                                      addr.length)))
130*1324Saxel.duch@nginx.com             {
131*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_FORMAT_ERROR;
132*1324Saxel.duch@nginx.com             }
133*1324Saxel.duch@nginx.com 
134*1324Saxel.duch@nginx.com             ret = nxt_inet6_addr(&inet6->start, addr.start, addr.length);
135*1324Saxel.duch@nginx.com             if (nxt_slow_path(ret != NXT_OK)) {
136*1324Saxel.duch@nginx.com                 return NXT_ADDR_PATTERN_FORMAT_ERROR;
137*1324Saxel.duch@nginx.com             }
138*1324Saxel.duch@nginx.com 
139*1324Saxel.duch@nginx.com             if (nxt_slow_path(cidr_prefix == 0)) {
140*1324Saxel.duch@nginx.com                 base->match_type = NXT_HTTP_ROUTE_ADDR_ANY;
141*1324Saxel.duch@nginx.com 
142*1324Saxel.duch@nginx.com                 goto parse_port;
143*1324Saxel.duch@nginx.com             }
144*1324Saxel.duch@nginx.com 
145*1324Saxel.duch@nginx.com             if (nxt_slow_path(cidr_prefix == 128)) {
146*1324Saxel.duch@nginx.com                 base->match_type = NXT_HTTP_ROUTE_ADDR_EXACT;
147*1324Saxel.duch@nginx.com 
148*1324Saxel.duch@nginx.com                 goto parse_port;
149*1324Saxel.duch@nginx.com             }
150*1324Saxel.duch@nginx.com 
151*1324Saxel.duch@nginx.com             base->match_type = NXT_HTTP_ROUTE_ADDR_CIDR;
152*1324Saxel.duch@nginx.com 
153*1324Saxel.duch@nginx.com             for (i = 0; i < sizeof(struct in6_addr); i++) {
154*1324Saxel.duch@nginx.com                 if (cidr_prefix >= 8) {
155*1324Saxel.duch@nginx.com                     inet6->end.s6_addr[i] = 0xFF;
156*1324Saxel.duch@nginx.com                     cidr_prefix -= 8;
157*1324Saxel.duch@nginx.com 
158*1324Saxel.duch@nginx.com                     continue;
159*1324Saxel.duch@nginx.com                 }
160*1324Saxel.duch@nginx.com 
161*1324Saxel.duch@nginx.com                 if (cidr_prefix > 0) {
162*1324Saxel.duch@nginx.com                     inet6->end.s6_addr[i] = 0xFF & (0xFF << (8 - cidr_prefix));
163*1324Saxel.duch@nginx.com                     inet6->start.s6_addr[i] &= inet6->end.s6_addr[i];
164*1324Saxel.duch@nginx.com                     cidr_prefix = 0;
165*1324Saxel.duch@nginx.com 
166*1324Saxel.duch@nginx.com                     continue;
167*1324Saxel.duch@nginx.com                 }
168*1324Saxel.duch@nginx.com 
169*1324Saxel.duch@nginx.com                 inet6->start.s6_addr[i] = 0;
170*1324Saxel.duch@nginx.com                 inet6->end.s6_addr[i] = 0;
171*1324Saxel.duch@nginx.com             }
172*1324Saxel.duch@nginx.com 
173*1324Saxel.duch@nginx.com             goto parse_port;
174*1324Saxel.duch@nginx.com         }
175*1324Saxel.duch@nginx.com 
176*1324Saxel.duch@nginx.com         base->match_type = NXT_HTTP_ROUTE_ADDR_EXACT;
177*1324Saxel.duch@nginx.com 
178*1324Saxel.duch@nginx.com         if (nxt_slow_path(!nxt_valid_ipv6_blocks(addr.start, addr.length))) {
179*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_FORMAT_ERROR;
180*1324Saxel.duch@nginx.com         }
181*1324Saxel.duch@nginx.com 
182*1324Saxel.duch@nginx.com         nxt_inet6_addr(&inet6->start, addr.start, addr.length);
183*1324Saxel.duch@nginx.com 
184*1324Saxel.duch@nginx.com         goto parse_port;
185*1324Saxel.duch@nginx.com #endif
186*1324Saxel.duch@nginx.com         return NXT_ADDR_PATTERN_NO_IPv6_ERROR;
187*1324Saxel.duch@nginx.com     }
188*1324Saxel.duch@nginx.com 
189*1324Saxel.duch@nginx.com     base->addr_family = AF_INET;
190*1324Saxel.duch@nginx.com 
191*1324Saxel.duch@nginx.com     delim = nxt_memchr(addr.start, ':', addr.length);
192*1324Saxel.duch@nginx.com     if (delim != NULL) {
193*1324Saxel.duch@nginx.com         port.start = delim + 1;
194*1324Saxel.duch@nginx.com         port.length = addr.start + addr.length - port.start;
195*1324Saxel.duch@nginx.com         addr.length = delim - addr.start;
196*1324Saxel.duch@nginx.com     }
197*1324Saxel.duch@nginx.com 
198*1324Saxel.duch@nginx.com     inet = &pattern->addr.v4;
199*1324Saxel.duch@nginx.com 
200*1324Saxel.duch@nginx.com     delim = nxt_memchr(addr.start, '-', addr.length);
201*1324Saxel.duch@nginx.com     if (delim != NULL) {
202*1324Saxel.duch@nginx.com         inet->start = nxt_inet_addr(addr.start, delim - addr.start);
203*1324Saxel.duch@nginx.com         if (nxt_slow_path(inet->start == INADDR_NONE)) {
204*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_FORMAT_ERROR;
205*1324Saxel.duch@nginx.com         }
206*1324Saxel.duch@nginx.com 
207*1324Saxel.duch@nginx.com         inet->end = nxt_inet_addr(delim + 1,
208*1324Saxel.duch@nginx.com                                   addr.start + addr.length - (delim + 1));
209*1324Saxel.duch@nginx.com         if (nxt_slow_path(inet->end == INADDR_NONE)) {
210*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_FORMAT_ERROR;
211*1324Saxel.duch@nginx.com         }
212*1324Saxel.duch@nginx.com 
213*1324Saxel.duch@nginx.com         if (nxt_slow_path(nxt_memcmp(&inet->start, &inet->end,
214*1324Saxel.duch@nginx.com                                      sizeof(struct in_addr)) > 0))
215*1324Saxel.duch@nginx.com         {
216*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_RANGE_OVERLAP_ERROR;
217*1324Saxel.duch@nginx.com         }
218*1324Saxel.duch@nginx.com 
219*1324Saxel.duch@nginx.com         base->match_type = NXT_HTTP_ROUTE_ADDR_RANGE;
220*1324Saxel.duch@nginx.com 
221*1324Saxel.duch@nginx.com         goto parse_port;
222*1324Saxel.duch@nginx.com     }
223*1324Saxel.duch@nginx.com 
224*1324Saxel.duch@nginx.com     delim = nxt_memchr(addr.start, '/', addr.length);
225*1324Saxel.duch@nginx.com     if (delim != NULL) {
226*1324Saxel.duch@nginx.com         cidr_prefix = nxt_int_parse(delim + 1,
227*1324Saxel.duch@nginx.com                                     addr.start + addr.length - (delim + 1));
228*1324Saxel.duch@nginx.com         if (nxt_slow_path(cidr_prefix < 0 || cidr_prefix > 32)) {
229*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_CIDR_ERROR;
230*1324Saxel.duch@nginx.com         }
231*1324Saxel.duch@nginx.com 
232*1324Saxel.duch@nginx.com         addr.length = delim - addr.start;
233*1324Saxel.duch@nginx.com         inet->end = htonl(0xFFFFFFFF & (0xFFFFFFFF << (32 - cidr_prefix)));
234*1324Saxel.duch@nginx.com 
235*1324Saxel.duch@nginx.com         inet->start = nxt_inet_addr(addr.start, addr.length) & inet->end;
236*1324Saxel.duch@nginx.com         if (nxt_slow_path(inet->start == INADDR_NONE)) {
237*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_FORMAT_ERROR;
238*1324Saxel.duch@nginx.com         }
239*1324Saxel.duch@nginx.com 
240*1324Saxel.duch@nginx.com         if (cidr_prefix == 0) {
241*1324Saxel.duch@nginx.com             base->match_type = NXT_HTTP_ROUTE_ADDR_ANY;
242*1324Saxel.duch@nginx.com 
243*1324Saxel.duch@nginx.com             goto parse_port;
244*1324Saxel.duch@nginx.com         }
245*1324Saxel.duch@nginx.com 
246*1324Saxel.duch@nginx.com         if (cidr_prefix < 32) {
247*1324Saxel.duch@nginx.com             base->match_type = NXT_HTTP_ROUTE_ADDR_CIDR;
248*1324Saxel.duch@nginx.com 
249*1324Saxel.duch@nginx.com             goto parse_port;
250*1324Saxel.duch@nginx.com         }
251*1324Saxel.duch@nginx.com     }
252*1324Saxel.duch@nginx.com 
253*1324Saxel.duch@nginx.com     inet->start = nxt_inet_addr(addr.start, addr.length);
254*1324Saxel.duch@nginx.com     if (nxt_slow_path(inet->start == INADDR_NONE)) {
255*1324Saxel.duch@nginx.com         return NXT_ADDR_PATTERN_FORMAT_ERROR;
256*1324Saxel.duch@nginx.com     }
257*1324Saxel.duch@nginx.com 
258*1324Saxel.duch@nginx.com     base->match_type = NXT_HTTP_ROUTE_ADDR_EXACT;
259*1324Saxel.duch@nginx.com 
260*1324Saxel.duch@nginx.com parse_port:
261*1324Saxel.duch@nginx.com 
262*1324Saxel.duch@nginx.com     if (port.length == 0) {
263*1324Saxel.duch@nginx.com         if (nxt_slow_path(port.start != NULL)) {
264*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_FORMAT_ERROR;
265*1324Saxel.duch@nginx.com         }
266*1324Saxel.duch@nginx.com 
267*1324Saxel.duch@nginx.com         base->port.start = 0;
268*1324Saxel.duch@nginx.com         base->port.end = 65535;
269*1324Saxel.duch@nginx.com 
270*1324Saxel.duch@nginx.com         return NXT_OK;
271*1324Saxel.duch@nginx.com     }
272*1324Saxel.duch@nginx.com 
273*1324Saxel.duch@nginx.com     delim = nxt_memchr(port.start, '-', port.length - 1);
274*1324Saxel.duch@nginx.com     if (delim != NULL) {
275*1324Saxel.duch@nginx.com         ret = nxt_int_parse(port.start, delim - port.start);
276*1324Saxel.duch@nginx.com         if (nxt_slow_path(ret < 0 || ret > 65535)) {
277*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_PORT_ERROR;
278*1324Saxel.duch@nginx.com         }
279*1324Saxel.duch@nginx.com 
280*1324Saxel.duch@nginx.com         base->port.start = ret;
281*1324Saxel.duch@nginx.com 
282*1324Saxel.duch@nginx.com         ret = nxt_int_parse(delim + 1, port.start + port.length - (delim + 1));
283*1324Saxel.duch@nginx.com         if (nxt_slow_path(ret < base->port.start || ret > 65535)) {
284*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_PORT_ERROR;
285*1324Saxel.duch@nginx.com         }
286*1324Saxel.duch@nginx.com 
287*1324Saxel.duch@nginx.com         base->port.end = ret;
288*1324Saxel.duch@nginx.com 
289*1324Saxel.duch@nginx.com     } else {
290*1324Saxel.duch@nginx.com         ret = nxt_int_parse(port.start, port.length);
291*1324Saxel.duch@nginx.com         if (nxt_slow_path(ret < 0 || ret > 65535)) {
292*1324Saxel.duch@nginx.com             return NXT_ADDR_PATTERN_PORT_ERROR;
293*1324Saxel.duch@nginx.com         }
294*1324Saxel.duch@nginx.com 
295*1324Saxel.duch@nginx.com         base->port.start = ret;
296*1324Saxel.duch@nginx.com         base->port.end = ret;
297*1324Saxel.duch@nginx.com     }
298*1324Saxel.duch@nginx.com 
299*1324Saxel.duch@nginx.com     return NXT_OK;
300*1324Saxel.duch@nginx.com }
301*1324Saxel.duch@nginx.com 
302*1324Saxel.duch@nginx.com 
303*1324Saxel.duch@nginx.com static nxt_bool_t
304*1324Saxel.duch@nginx.com nxt_str_looks_like_ipv6(const nxt_str_t *str)
305*1324Saxel.duch@nginx.com {
306*1324Saxel.duch@nginx.com     u_char  *colon, *end;
307*1324Saxel.duch@nginx.com 
308*1324Saxel.duch@nginx.com     colon = nxt_memchr(str->start, ':', str->length);
309*1324Saxel.duch@nginx.com 
310*1324Saxel.duch@nginx.com     if (colon != NULL) {
311*1324Saxel.duch@nginx.com         end = str->start + str->length;
312*1324Saxel.duch@nginx.com         colon = nxt_memchr(colon + 1, ':', end - (colon + 1));
313*1324Saxel.duch@nginx.com     }
314*1324Saxel.duch@nginx.com 
315*1324Saxel.duch@nginx.com     return (colon != NULL);
316*1324Saxel.duch@nginx.com }
317*1324Saxel.duch@nginx.com 
318*1324Saxel.duch@nginx.com 
319*1324Saxel.duch@nginx.com #if (NXT_INET6)
320*1324Saxel.duch@nginx.com 
321*1324Saxel.duch@nginx.com static nxt_bool_t
322*1324Saxel.duch@nginx.com nxt_valid_ipv6_blocks(u_char *c, size_t len)
323*1324Saxel.duch@nginx.com {
324*1324Saxel.duch@nginx.com     u_char      *end;
325*1324Saxel.duch@nginx.com     nxt_uint_t  colon_gap;
326*1324Saxel.duch@nginx.com 
327*1324Saxel.duch@nginx.com     end = c + len;
328*1324Saxel.duch@nginx.com     colon_gap = 0;
329*1324Saxel.duch@nginx.com 
330*1324Saxel.duch@nginx.com     while (c != end) {
331*1324Saxel.duch@nginx.com         if (*c == ':') {
332*1324Saxel.duch@nginx.com             colon_gap = 0;
333*1324Saxel.duch@nginx.com             c++;
334*1324Saxel.duch@nginx.com 
335*1324Saxel.duch@nginx.com             continue;
336*1324Saxel.duch@nginx.com         }
337*1324Saxel.duch@nginx.com 
338*1324Saxel.duch@nginx.com         colon_gap++;
339*1324Saxel.duch@nginx.com         c++;
340*1324Saxel.duch@nginx.com 
341*1324Saxel.duch@nginx.com         if (nxt_slow_path(colon_gap > 4)) {
342*1324Saxel.duch@nginx.com             return 0;
343*1324Saxel.duch@nginx.com         }
344*1324Saxel.duch@nginx.com     }
345*1324Saxel.duch@nginx.com 
346*1324Saxel.duch@nginx.com     return 1;
347*1324Saxel.duch@nginx.com }
348*1324Saxel.duch@nginx.com 
349*1324Saxel.duch@nginx.com #endif
350