blob: ab5b48755453cb2e00829fc5caa73b04f62fe4f5 [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 Hughes32fea142014-11-16 10:14:54 -080026TEST(netdb, getaddrinfo_NULL_host) {
27 // It's okay for the host argument to be NULL, as long as service isn't.
28 addrinfo* ai = NULL;
29 ASSERT_EQ(0, getaddrinfo(NULL, "smtp", NULL, &ai));
30 // (sockaddr_in::sin_port and sockaddr_in6::sin6_port overlap.)
31 ASSERT_EQ(25U, ntohs(reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_port));
32 freeaddrinfo(ai);
33}
34
35TEST(netdb, getaddrinfo_NULL_service) {
36 // It's okay for the service argument to be NULL, as long as host isn't.
37 addrinfo* ai = NULL;
38 ASSERT_EQ(0, getaddrinfo("localhost", NULL, NULL, &ai));
39 ASSERT_TRUE(ai != NULL);
40 freeaddrinfo(ai);
41}
42
Elliott Hughesd3b9d112013-02-13 08:22:07 -080043TEST(netdb, getaddrinfo_NULL_hints) {
44 addrinfo* ai = NULL;
45 ASSERT_EQ(0, getaddrinfo("localhost", "9999", NULL, &ai));
Derek Xueba811122014-08-13 14:19:17 +010046
47 bool saw_tcp = false;
48 bool saw_udp = false;
49 for (addrinfo* p = ai; p != NULL; p = p->ai_next) {
50 ASSERT_TRUE(p->ai_family == AF_INET || p->ai_family == AF_INET6);
51 if (p->ai_socktype == SOCK_STREAM) {
52 ASSERT_EQ(IPPROTO_TCP, p->ai_protocol);
53 saw_tcp = true;
54 } else if (p->ai_socktype == SOCK_DGRAM) {
55 ASSERT_EQ(IPPROTO_UDP, p->ai_protocol);
56 saw_udp = true;
57 }
58 }
59 ASSERT_TRUE(saw_tcp);
60 ASSERT_TRUE(saw_udp);
61
62 freeaddrinfo(ai);
63}
64
65TEST(netdb, getaddrinfo_service_lookup) {
66 addrinfo* ai = NULL;
67 ASSERT_EQ(0, getaddrinfo("localhost", "smtp", NULL, &ai));
68 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
69 ASSERT_EQ(IPPROTO_TCP, ai->ai_protocol);
70 ASSERT_EQ(25, ntohs(reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_port));
71 freeaddrinfo(ai);
72}
73
74TEST(netdb, getaddrinfo_hints) {
75 addrinfo hints;
76 memset(&hints, 0, sizeof(hints));
77 hints.ai_family = AF_UNSPEC;
78 hints.ai_socktype = SOCK_STREAM;
79 hints.ai_protocol = IPPROTO_TCP;
80
81 addrinfo* ai = NULL;
82 ASSERT_EQ(0, getaddrinfo( "localhost", "9999", &hints, &ai));
83 ASSERT_EQ(AF_INET, ai->ai_family);
84 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
85 ASSERT_EQ(IPPROTO_TCP, ai->ai_protocol);
86 ASSERT_TRUE(ai->ai_next == NULL);
Elliott Hughesd3b9d112013-02-13 08:22:07 -080087 freeaddrinfo(ai);
88}
Elliott Hughesd8213bb2013-02-13 09:49:33 -080089
90TEST(netdb, getnameinfo_salen) {
91 sockaddr_storage ss;
92 memset(&ss, 0, sizeof(ss));
93 sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
94 char tmp[16];
95
96 ss.ss_family = AF_INET;
97 socklen_t too_much = sizeof(ss);
98 socklen_t just_right = sizeof(sockaddr_in);
99 socklen_t too_little = sizeof(sockaddr_in) - 1;
100
101 ASSERT_EQ(0, getnameinfo(sa, too_much, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
102 ASSERT_STREQ("0.0.0.0", tmp);
103 ASSERT_EQ(0, getnameinfo(sa, just_right, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
104 ASSERT_STREQ("0.0.0.0", tmp);
105 ASSERT_EQ(EAI_FAMILY, getnameinfo(sa, too_little, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
106
107 ss.ss_family = AF_INET6;
108 just_right = sizeof(sockaddr_in6);
109 too_little = sizeof(sockaddr_in6) - 1;
110 too_much = just_right + 1;
111
112 ASSERT_EQ(0, getnameinfo(sa, too_much, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
113 ASSERT_STREQ("::", tmp);
114 ASSERT_EQ(0, getnameinfo(sa, just_right, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
115 ASSERT_STREQ("::", tmp);
116 ASSERT_EQ(EAI_FAMILY, getnameinfo(sa, too_little, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
117}
Derek Xue4912fc72014-08-13 14:19:17 +0100118
Yabin Cui58d33a52014-12-16 17:03:44 -0800119void VerifyLocalhost(hostent *hent) {
Derek Xue4912fc72014-08-13 14:19:17 +0100120 ASSERT_TRUE(hent != NULL);
121 ASSERT_EQ(hent->h_addrtype, AF_INET);
122 ASSERT_EQ(hent->h_addr[0], 127);
123 ASSERT_EQ(hent->h_addr[1], 0);
124 ASSERT_EQ(hent->h_addr[2], 0);
125 ASSERT_EQ(hent->h_addr[3], 1);
126}
Derek Xueba811122014-08-13 14:19:17 +0100127
Yabin Cui58d33a52014-12-16 17:03:44 -0800128TEST(netdb, gethostbyname) {
129 hostent* hp = gethostbyname("localhost");
130 VerifyLocalhost(hp);
131}
132
133TEST(netdb, gethostbyname2) {
134 hostent* hp = gethostbyname2("localhost", AF_INET);
135 VerifyLocalhost(hp);
136}
137
138TEST(netdb, gethostbyname_r) {
139 hostent hent;
140 hostent *hp;
141 char buf[512];
142 int err;
143 int result = gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &err);
144 ASSERT_EQ(0, result);
145 VerifyLocalhost(hp);
146
147 // Change hp->h_addr to test reentrancy.
148 hp->h_addr[0] = 0;
149
150 hostent hent2;
151 hostent *hp2;
152 char buf2[512];
153 result = gethostbyname_r("localhost", &hent2, buf2, sizeof(buf2), &hp2, &err);
154 ASSERT_EQ(0, result);
155 VerifyLocalhost(hp2);
156
157 ASSERT_EQ(0, hp->h_addr[0]);
158}
159
160TEST(netdb, gethostbyname2_r) {
161 hostent hent;
162 hostent *hp;
163 char buf[512];
164 int err;
165 int result = gethostbyname2_r("localhost", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
166 ASSERT_EQ(0, result);
167 VerifyLocalhost(hp);
168
169 // Change hp->h_addr to test reentrancy.
170 hp->h_addr[0] = 0;
171
172 hostent hent2;
173 hostent *hp2;
174 char buf2[512];
175 result = gethostbyname2_r("localhost", AF_INET, &hent2, buf2, sizeof(buf2), &hp2, &err);
176 ASSERT_EQ(0, result);
177 VerifyLocalhost(hp2);
178
179 ASSERT_EQ(0, hp->h_addr[0]);
180}
181
182TEST(netdb, gethostbyaddr) {
183 char addr[4];
184 ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", addr));
185 hostent *hp = gethostbyaddr(addr, sizeof(addr), AF_INET);
186 VerifyLocalhost(hp);
187}
188
189TEST(netdb, gethostbyaddr_r) {
190 char addr[4];
191 ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", addr));
192
193 hostent hent;
194 hostent *hp;
195 char buf[512];
196 int err;
197 int result = gethostbyaddr_r(addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
198 ASSERT_EQ(0, result);
199 VerifyLocalhost(hp);
200
201 // Change hp->h_addr to test reentrancy.
202 hp->h_addr[0] = 0;
203
204 hostent hent2;
205 hostent *hp2;
206 char buf2[512];
207 result = gethostbyaddr_r(addr, sizeof(addr), AF_INET, &hent2, buf2, sizeof(buf2), &hp2, &err);
208 ASSERT_EQ(0, result);
209 VerifyLocalhost(hp2);
210
211 ASSERT_EQ(0, hp->h_addr[0]);
212}
213
214TEST(netdb, gethostbyname_r_ERANGE) {
215 hostent hent;
216 hostent *hp;
217 char buf[4]; // Use too small buffer.
218 int err;
219 int result = gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &err);
220 ASSERT_EQ(ERANGE, result);
221 ASSERT_EQ(NULL, hp);
222}
223
224TEST(netdb, gethostbyname2_r_ERANGE) {
225 hostent hent;
226 hostent *hp;
227 char buf[4]; // Use too small buffer.
228 int err;
229 int result = gethostbyname2_r("localhost", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
230 ASSERT_EQ(ERANGE, result);
231 ASSERT_EQ(NULL, hp);
232}
233
234TEST(netdb, gethostbyaddr_r_ERANGE) {
235 char addr[4];
236 ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", addr));
237
238 hostent hent;
239 hostent *hp;
240 char buf[4]; // Use too small buffer.
241 int err;
242 int result = gethostbyaddr_r(addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
243 ASSERT_EQ(ERANGE, result);
244 ASSERT_EQ(NULL, hp);
245}
246
Derek Xueba811122014-08-13 14:19:17 +0100247TEST(netdb, getservbyname) {
248 // smtp is TCP-only, so we know we'll get 25/tcp back.
249 servent* s = getservbyname("smtp", NULL);
250 ASSERT_TRUE(s != NULL);
251 ASSERT_EQ(25, ntohs(s->s_port));
252 ASSERT_STREQ("tcp", s->s_proto);
253
254 // We get the same result by explicitly asking for tcp.
255 s = getservbyname("smtp", "tcp");
256 ASSERT_TRUE(s != NULL);
257 ASSERT_EQ(25, ntohs(s->s_port));
258 ASSERT_STREQ("tcp", s->s_proto);
259
260 // And we get a failure if we explicitly ask for udp.
261 s = getservbyname("smtp", "udp");
262 ASSERT_TRUE(s == NULL);
263
264 // But there are actually udp services.
265 s = getservbyname("echo", "udp");
266 ASSERT_TRUE(s != NULL);
267 ASSERT_EQ(7, ntohs(s->s_port));
268 ASSERT_STREQ("udp", s->s_proto);
269}