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 }