blob: 5660bbdaa67584eb8e0b9a7bcdd3d59e9b62ffe7 [file] [log] [blame]
Elliott Hughesd3b9d112013-02-13 08:22:07 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yabin Cui58d33a52014-12-16 17:03:44 -080017#include <netdb.h>
18
Elliott Hughesd3b9d112013-02-13 08:22:07 -080019#include <gtest/gtest.h>
20
Yabin Cui58d33a52014-12-16 17:03:44 -080021#include <arpa/inet.h>
Elliott Hughesd3b9d112013-02-13 08:22:07 -080022#include <sys/types.h>
23#include <sys/socket.h>
Elliott Hughesd8213bb2013-02-13 09:49:33 -080024#include <netinet/in.h>
Elliott Hughesd3b9d112013-02-13 08:22:07 -080025
Elliott Hughesc62a4b52015-01-08 17:28:46 -080026// https://code.google.com/p/android/issues/detail?id=13228
27TEST(netdb, freeaddrinfo_NULL) {
28 freeaddrinfo(NULL);
29}
30
Elliott Hughes32fea142014-11-16 10:14:54 -080031TEST(netdb, getaddrinfo_NULL_host) {
32 // It's okay for the host argument to be NULL, as long as service isn't.
33 addrinfo* ai = NULL;
34 ASSERT_EQ(0, getaddrinfo(NULL, "smtp", NULL, &ai));
35 // (sockaddr_in::sin_port and sockaddr_in6::sin6_port overlap.)
36 ASSERT_EQ(25U, ntohs(reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_port));
37 freeaddrinfo(ai);
38}
39
40TEST(netdb, getaddrinfo_NULL_service) {
41 // It's okay for the service argument to be NULL, as long as host isn't.
42 addrinfo* ai = NULL;
43 ASSERT_EQ(0, getaddrinfo("localhost", NULL, NULL, &ai));
44 ASSERT_TRUE(ai != NULL);
45 freeaddrinfo(ai);
46}
47
Elliott Hughesd3b9d112013-02-13 08:22:07 -080048TEST(netdb, getaddrinfo_NULL_hints) {
49 addrinfo* ai = NULL;
50 ASSERT_EQ(0, getaddrinfo("localhost", "9999", NULL, &ai));
Derek Xueba811122014-08-13 14:19:17 +010051
52 bool saw_tcp = false;
53 bool saw_udp = false;
54 for (addrinfo* p = ai; p != NULL; p = p->ai_next) {
55 ASSERT_TRUE(p->ai_family == AF_INET || p->ai_family == AF_INET6);
56 if (p->ai_socktype == SOCK_STREAM) {
57 ASSERT_EQ(IPPROTO_TCP, p->ai_protocol);
58 saw_tcp = true;
59 } else if (p->ai_socktype == SOCK_DGRAM) {
60 ASSERT_EQ(IPPROTO_UDP, p->ai_protocol);
61 saw_udp = true;
62 }
63 }
64 ASSERT_TRUE(saw_tcp);
65 ASSERT_TRUE(saw_udp);
66
67 freeaddrinfo(ai);
68}
69
70TEST(netdb, getaddrinfo_service_lookup) {
71 addrinfo* ai = NULL;
72 ASSERT_EQ(0, getaddrinfo("localhost", "smtp", NULL, &ai));
73 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
74 ASSERT_EQ(IPPROTO_TCP, ai->ai_protocol);
75 ASSERT_EQ(25, ntohs(reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_port));
76 freeaddrinfo(ai);
77}
78
79TEST(netdb, getaddrinfo_hints) {
80 addrinfo hints;
81 memset(&hints, 0, sizeof(hints));
82 hints.ai_family = AF_UNSPEC;
83 hints.ai_socktype = SOCK_STREAM;
84 hints.ai_protocol = IPPROTO_TCP;
85
86 addrinfo* ai = NULL;
87 ASSERT_EQ(0, getaddrinfo( "localhost", "9999", &hints, &ai));
88 ASSERT_EQ(AF_INET, ai->ai_family);
89 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
90 ASSERT_EQ(IPPROTO_TCP, ai->ai_protocol);
91 ASSERT_TRUE(ai->ai_next == NULL);
Elliott Hughesd3b9d112013-02-13 08:22:07 -080092 freeaddrinfo(ai);
93}
Elliott Hughesd8213bb2013-02-13 09:49:33 -080094
95TEST(netdb, getnameinfo_salen) {
96 sockaddr_storage ss;
97 memset(&ss, 0, sizeof(ss));
98 sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
99 char tmp[16];
100
101 ss.ss_family = AF_INET;
102 socklen_t too_much = sizeof(ss);
103 socklen_t just_right = sizeof(sockaddr_in);
104 socklen_t too_little = sizeof(sockaddr_in) - 1;
105
106 ASSERT_EQ(0, getnameinfo(sa, too_much, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
107 ASSERT_STREQ("0.0.0.0", tmp);
108 ASSERT_EQ(0, getnameinfo(sa, just_right, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
109 ASSERT_STREQ("0.0.0.0", tmp);
110 ASSERT_EQ(EAI_FAMILY, getnameinfo(sa, too_little, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
111
112 ss.ss_family = AF_INET6;
113 just_right = sizeof(sockaddr_in6);
114 too_little = sizeof(sockaddr_in6) - 1;
115 too_much = just_right + 1;
116
117 ASSERT_EQ(0, getnameinfo(sa, too_much, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
118 ASSERT_STREQ("::", tmp);
119 ASSERT_EQ(0, getnameinfo(sa, just_right, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
120 ASSERT_STREQ("::", tmp);
121 ASSERT_EQ(EAI_FAMILY, getnameinfo(sa, too_little, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
122}
Derek Xue4912fc72014-08-13 14:19:17 +0100123
Yabin Cui58d33a52014-12-16 17:03:44 -0800124void VerifyLocalhost(hostent *hent) {
Derek Xue4912fc72014-08-13 14:19:17 +0100125 ASSERT_TRUE(hent != NULL);
126 ASSERT_EQ(hent->h_addrtype, AF_INET);
127 ASSERT_EQ(hent->h_addr[0], 127);
128 ASSERT_EQ(hent->h_addr[1], 0);
129 ASSERT_EQ(hent->h_addr[2], 0);
130 ASSERT_EQ(hent->h_addr[3], 1);
131}
Derek Xueba811122014-08-13 14:19:17 +0100132
Yabin Cui58d33a52014-12-16 17:03:44 -0800133TEST(netdb, gethostbyname) {
134 hostent* hp = gethostbyname("localhost");
135 VerifyLocalhost(hp);
136}
137
138TEST(netdb, gethostbyname2) {
139 hostent* hp = gethostbyname2("localhost", AF_INET);
140 VerifyLocalhost(hp);
141}
142
143TEST(netdb, gethostbyname_r) {
144 hostent hent;
145 hostent *hp;
146 char buf[512];
147 int err;
148 int result = gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &err);
149 ASSERT_EQ(0, result);
150 VerifyLocalhost(hp);
151
152 // Change hp->h_addr to test reentrancy.
153 hp->h_addr[0] = 0;
154
155 hostent hent2;
156 hostent *hp2;
157 char buf2[512];
158 result = gethostbyname_r("localhost", &hent2, buf2, sizeof(buf2), &hp2, &err);
159 ASSERT_EQ(0, result);
160 VerifyLocalhost(hp2);
161
162 ASSERT_EQ(0, hp->h_addr[0]);
163}
164
165TEST(netdb, gethostbyname2_r) {
166 hostent hent;
167 hostent *hp;
168 char buf[512];
169 int err;
170 int result = gethostbyname2_r("localhost", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
171 ASSERT_EQ(0, result);
172 VerifyLocalhost(hp);
173
174 // Change hp->h_addr to test reentrancy.
175 hp->h_addr[0] = 0;
176
177 hostent hent2;
178 hostent *hp2;
179 char buf2[512];
180 result = gethostbyname2_r("localhost", AF_INET, &hent2, buf2, sizeof(buf2), &hp2, &err);
181 ASSERT_EQ(0, result);
182 VerifyLocalhost(hp2);
183
184 ASSERT_EQ(0, hp->h_addr[0]);
185}
186
187TEST(netdb, gethostbyaddr) {
188 char addr[4];
189 ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", addr));
190 hostent *hp = gethostbyaddr(addr, sizeof(addr), AF_INET);
191 VerifyLocalhost(hp);
192}
193
194TEST(netdb, gethostbyaddr_r) {
195 char addr[4];
196 ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", addr));
197
198 hostent hent;
199 hostent *hp;
200 char buf[512];
201 int err;
202 int result = gethostbyaddr_r(addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
203 ASSERT_EQ(0, result);
204 VerifyLocalhost(hp);
205
206 // Change hp->h_addr to test reentrancy.
207 hp->h_addr[0] = 0;
208
209 hostent hent2;
210 hostent *hp2;
211 char buf2[512];
212 result = gethostbyaddr_r(addr, sizeof(addr), AF_INET, &hent2, buf2, sizeof(buf2), &hp2, &err);
213 ASSERT_EQ(0, result);
214 VerifyLocalhost(hp2);
215
216 ASSERT_EQ(0, hp->h_addr[0]);
217}
218
219TEST(netdb, gethostbyname_r_ERANGE) {
220 hostent hent;
221 hostent *hp;
222 char buf[4]; // Use too small buffer.
223 int err;
224 int result = gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &err);
225 ASSERT_EQ(ERANGE, result);
226 ASSERT_EQ(NULL, hp);
227}
228
229TEST(netdb, gethostbyname2_r_ERANGE) {
230 hostent hent;
231 hostent *hp;
232 char buf[4]; // Use too small buffer.
233 int err;
234 int result = gethostbyname2_r("localhost", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
235 ASSERT_EQ(ERANGE, result);
236 ASSERT_EQ(NULL, hp);
237}
238
239TEST(netdb, gethostbyaddr_r_ERANGE) {
240 char addr[4];
241 ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", addr));
242
243 hostent hent;
244 hostent *hp;
245 char buf[4]; // Use too small buffer.
246 int err;
247 int result = gethostbyaddr_r(addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
248 ASSERT_EQ(ERANGE, result);
249 ASSERT_EQ(NULL, hp);
250}
251
Derek Xueba811122014-08-13 14:19:17 +0100252TEST(netdb, getservbyname) {
253 // smtp is TCP-only, so we know we'll get 25/tcp back.
254 servent* s = getservbyname("smtp", NULL);
255 ASSERT_TRUE(s != NULL);
256 ASSERT_EQ(25, ntohs(s->s_port));
257 ASSERT_STREQ("tcp", s->s_proto);
258
259 // We get the same result by explicitly asking for tcp.
260 s = getservbyname("smtp", "tcp");
261 ASSERT_TRUE(s != NULL);
262 ASSERT_EQ(25, ntohs(s->s_port));
263 ASSERT_STREQ("tcp", s->s_proto);
264
265 // And we get a failure if we explicitly ask for udp.
266 s = getservbyname("smtp", "udp");
267 ASSERT_TRUE(s == NULL);
268
269 // But there are actually udp services.
270 s = getservbyname("echo", "udp");
271 ASSERT_TRUE(s != NULL);
272 ASSERT_EQ(7, ntohs(s->s_port));
273 ASSERT_STREQ("udp", s->s_proto);
274}