netdb_test.cpp revision c62a4b5a7aede760b06298f4b641b5a9768f5744
1/* 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 17#include <netdb.h> 18 19#include <gtest/gtest.h> 20 21#include <arpa/inet.h> 22#include <sys/types.h> 23#include <sys/socket.h> 24#include <netinet/in.h> 25 26// https://code.google.com/p/android/issues/detail?id=13228 27TEST(netdb, freeaddrinfo_NULL) { 28 freeaddrinfo(NULL); 29} 30 31TEST(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 48TEST(netdb, getaddrinfo_NULL_hints) { 49 addrinfo* ai = NULL; 50 ASSERT_EQ(0, getaddrinfo("localhost", "9999", NULL, &ai)); 51 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); 92 freeaddrinfo(ai); 93} 94 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} 123 124void VerifyLocalhost(hostent *hent) { 125 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} 132 133TEST(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 252TEST(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} 275