Mercurial > hg > nginx
comparison src/core/ngx_inet.c @ 2197:74477ea8074f
*) remove zero termination in ngx_inet_ntop() and ngx_sock_ntop()
*) use ngx_snprintf() in ngx_inet_ntop() and ngx_sock_ntop()
as they are called just once per connection
*) NGX_INET_ADDRSTRLEN
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 21 Aug 2008 18:47:23 +0000 |
parents | 2a92804f4109 |
children | 5975975eedc0 |
comparison
equal
deleted
inserted
replaced
2196:fab3fa7339ff | 2197:74477ea8074f |
---|---|
4 */ | 4 */ |
5 | 5 |
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 | |
10 | |
11 static size_t ngx_sprint_uchar(u_char *text, u_char c, size_t len); | |
12 | 9 |
13 | 10 |
14 /* AF_INET only */ | 11 /* AF_INET only */ |
15 | 12 |
16 in_addr_t | 13 in_addr_t |
54 | 51 |
55 return INADDR_NONE; | 52 return INADDR_NONE; |
56 } | 53 } |
57 | 54 |
58 | 55 |
59 /* | |
60 * ngx_sock_ntop() and ngx_inet_ntop() may be implemented as | |
61 * "ngx_sprintf(text, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3])", however, | |
62 * they had been implemented long before the ngx_sprintf() had appeared | |
63 * and they are faster by 1.5-2.5 times, so it is worth to keep them. | |
64 * | |
65 * By the way, the implementation using ngx_sprintf() is faster by 2.5-3 times | |
66 * than using FreeBSD libc's snprintf(). | |
67 */ | |
68 | |
69 /* AF_INET only */ | 56 /* AF_INET only */ |
70 | 57 |
71 size_t | 58 size_t |
72 ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len) | 59 ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len) |
73 { | 60 { |
74 u_char *p; | 61 u_char *p; |
75 size_t n; | |
76 ngx_uint_t i; | |
77 struct sockaddr_in *sin; | 62 struct sockaddr_in *sin; |
78 | 63 |
79 if (len == 0) { | 64 if (family == AF_INET) { |
80 return 0; | 65 |
81 } | 66 sin = (struct sockaddr_in *) sa; |
82 | 67 p = (u_char *) &sin->sin_addr; |
83 if (family != AF_INET) { | 68 |
84 return 0; | 69 return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud", |
85 } | 70 p[0], p[1], p[2], p[3]) |
86 | 71 - text; |
87 sin = (struct sockaddr_in *) sa; | 72 } |
88 p = (u_char *) &sin->sin_addr; | 73 |
89 | 74 return 0; |
90 if (len > INET_ADDRSTRLEN) { | |
91 len = INET_ADDRSTRLEN; | |
92 } | |
93 | |
94 n = ngx_sprint_uchar(text, p[0], len); | |
95 | |
96 i = 1; | |
97 | |
98 do { | |
99 if (len == n) { | |
100 text[n - 1] = '\0'; | |
101 return n; | |
102 } | |
103 | |
104 text[n++] = '.'; | |
105 | |
106 if (len == n) { | |
107 text[n - 1] = '\0'; | |
108 return n; | |
109 } | |
110 | |
111 n += ngx_sprint_uchar(&text[n], p[i++], len - n); | |
112 | |
113 } while (i < 4); | |
114 | |
115 if (len == n) { | |
116 text[n] = '\0'; | |
117 return n; | |
118 } | |
119 | |
120 text[n] = '\0'; | |
121 | |
122 return n; | |
123 } | 75 } |
124 | 76 |
125 | 77 |
126 size_t | 78 size_t |
127 ngx_inet_ntop(int family, void *addr, u_char *text, size_t len) | 79 ngx_inet_ntop(int family, void *addr, u_char *text, size_t len) |
128 { | 80 { |
129 u_char *p; | 81 u_char *p; |
130 size_t n; | 82 |
131 ngx_uint_t i; | 83 if (family == AF_INET) { |
132 | 84 |
133 if (len == 0) { | 85 p = (u_char *) addr; |
134 return 0; | 86 |
135 } | 87 return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud", |
136 | 88 p[0], p[1], p[2], p[3]) |
137 if (family != AF_INET) { | 89 - text; |
138 return 0; | 90 } |
139 } | 91 |
140 | 92 return 0; |
141 p = (u_char *) addr; | |
142 | |
143 if (len > INET_ADDRSTRLEN) { | |
144 len = INET_ADDRSTRLEN; | |
145 } | |
146 | |
147 n = ngx_sprint_uchar(text, p[0], len); | |
148 | |
149 i = 1; | |
150 | |
151 do { | |
152 if (len == n) { | |
153 text[n - 1] = '\0'; | |
154 return n; | |
155 } | |
156 | |
157 text[n++] = '.'; | |
158 | |
159 if (len == n) { | |
160 text[n - 1] = '\0'; | |
161 return n; | |
162 } | |
163 | |
164 n += ngx_sprint_uchar(&text[n], p[i++], len - n); | |
165 | |
166 } while (i < 4); | |
167 | |
168 if (len == n) { | |
169 text[n] = '\0'; | |
170 return n; | |
171 } | |
172 | |
173 text[n] = '\0'; | |
174 | |
175 return n; | |
176 } | |
177 | |
178 | |
179 static size_t | |
180 ngx_sprint_uchar(u_char *text, u_char c, size_t len) | |
181 { | |
182 size_t n; | |
183 ngx_uint_t c1, c2; | |
184 | |
185 n = 0; | |
186 | |
187 if (len == n) { | |
188 return n; | |
189 } | |
190 | |
191 c1 = c / 100; | |
192 | |
193 if (c1) { | |
194 *text++ = (u_char) (c1 + '0'); | |
195 n++; | |
196 | |
197 if (len == n) { | |
198 return n; | |
199 } | |
200 } | |
201 | |
202 c2 = (c % 100) / 10; | |
203 | |
204 if (c1 || c2) { | |
205 *text++ = (u_char) (c2 + '0'); | |
206 n++; | |
207 | |
208 if (len == n) { | |
209 return n; | |
210 } | |
211 } | |
212 | |
213 c2 = c % 10; | |
214 | |
215 *text = (u_char) (c2 + '0'); | |
216 n++; | |
217 | |
218 return n; | |
219 } | 93 } |
220 | 94 |
221 | 95 |
222 /* AF_INET only */ | 96 /* AF_INET only */ |
223 | 97 |
574 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]); | 448 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]); |
575 | 449 |
576 u->addrs[i].sockaddr = (struct sockaddr *) sin; | 450 u->addrs[i].sockaddr = (struct sockaddr *) sin; |
577 u->addrs[i].socklen = sizeof(struct sockaddr_in); | 451 u->addrs[i].socklen = sizeof(struct sockaddr_in); |
578 | 452 |
579 len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1; | 453 len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; |
580 | 454 |
581 p = ngx_pnalloc(pool, len); | 455 p = ngx_pnalloc(pool, len); |
582 if (p == NULL) { | 456 if (p == NULL) { |
583 return NGX_ERROR; | 457 return NGX_ERROR; |
584 } | 458 } |