netdb_test.cpp revision 58d33a51f336d6823ef1ec915949a5884699ff5f
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 26TEST(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 43TEST(netdb, getaddrinfo_NULL_hints) { 44 addrinfo* ai = NULL; 45 ASSERT_EQ(0, getaddrinfo("localhost", "9999", NULL, &ai)); 46 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); 87 freeaddrinfo(ai); 88} 89 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} 118 119void VerifyLocalhost(hostent *hent) { 120 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} 127 128TEST(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 247TEST(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} 270