Add some SocketAddress tests
[folly.git] / folly / test / SocketAddressTest.cpp
1 /*
2  * Copyright 2014 Facebook, Inc.
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 <folly/SocketAddress.h>
18
19 #include <gtest/gtest.h>
20 #include <iostream>
21 #include <sstream>
22
23 using namespace boost;
24 using std::string;
25 using std::cerr;
26 using std::endl;
27 using folly::SocketAddress;
28
29 TEST(SocketAddress, Size) {
30   SocketAddress addr;
31   EXPECT_EQ(sizeof(addr), 32);
32 }
33
34 TEST(SocketAddress, ConstructFromIpv4) {
35   SocketAddress addr("1.2.3.4", 4321);
36   EXPECT_EQ(addr.getFamily(), AF_INET);
37   EXPECT_EQ(addr.getAddressStr(), "1.2.3.4");
38   EXPECT_EQ(addr.getPort(), 4321);
39   sockaddr_storage addrStorage;
40   addr.getAddress(&addrStorage);
41   const sockaddr_in* inaddr = reinterpret_cast<sockaddr_in*>(&addrStorage);
42   EXPECT_EQ(inaddr->sin_addr.s_addr, htonl(0x01020304));
43   EXPECT_EQ(inaddr->sin_port, htons(4321));
44 }
45
46 TEST(SocketAddress, IPv4ToStringConversion) {
47   // testing addresses *.5.5.5, 5.*.5.5, 5.5.*.5, 5.5.5.*
48   SocketAddress addr;
49   for (int pos = 0; pos < 4; ++pos) {
50     for (int i = 0; i < 256; ++i) {
51       int fragments[] = {5,5,5,5};
52       fragments[pos] = i;
53       std::ostringstream ss;
54       ss << fragments[0] << "." << fragments[1] << "."
55          << fragments[2] << "." << fragments[3];
56       string ipString = ss.str();
57       addr.setFromIpPort(ipString, 1234);
58       EXPECT_EQ(addr.getAddressStr(), ipString);
59     }
60   }
61 }
62
63 TEST(SocketAddress, SetFromIpv4) {
64   SocketAddress addr;
65   addr.setFromIpPort("255.254.253.252", 8888);
66   EXPECT_EQ(addr.getFamily(), AF_INET);
67   EXPECT_EQ(addr.getAddressStr(), "255.254.253.252");
68   EXPECT_EQ(addr.getPort(), 8888);
69   sockaddr_storage addrStorage;
70   addr.getAddress(&addrStorage);
71   const sockaddr_in* inaddr = reinterpret_cast<sockaddr_in*>(&addrStorage);
72   EXPECT_EQ(inaddr->sin_addr.s_addr, htonl(0xfffefdfc));
73   EXPECT_EQ(inaddr->sin_port, htons(8888));
74 }
75
76 TEST(SocketAddress, ConstructFromInvalidIpv4) {
77   EXPECT_THROW(SocketAddress("1.2.3.256", 1234), std::runtime_error);
78 }
79
80 TEST(SocketAddress, SetFromInvalidIpv4) {
81   SocketAddress addr("12.34.56.78", 80);
82
83   // Try setting to an invalid value
84   // Since setFromIpPort() shouldn't allow hostname lookups, setting to
85   // "localhost" should fail, even if localhost is resolvable
86   EXPECT_THROW(addr.setFromIpPort("localhost", 1234),
87                std::runtime_error);
88
89   // Make sure the address still has the old contents
90   EXPECT_EQ(addr.getFamily(), AF_INET);
91   EXPECT_EQ(addr.getAddressStr(), "12.34.56.78");
92   EXPECT_EQ(addr.getPort(), 80);
93   sockaddr_storage addrStorage;
94   addr.getAddress(&addrStorage);
95   const sockaddr_in* inaddr = reinterpret_cast<sockaddr_in*>(&addrStorage);
96   EXPECT_EQ(inaddr->sin_addr.s_addr, htonl(0x0c22384e));
97 }
98
99 TEST(SocketAddress, SetFromHostname) {
100   // hopefully "localhost" is resolvable on any system that will run the tests
101   EXPECT_THROW(SocketAddress("localhost", 80), std::runtime_error);
102   SocketAddress addr("localhost", 80, true);
103
104   SocketAddress addr2;
105   EXPECT_THROW(addr2.setFromIpPort("localhost", 0), std::runtime_error);
106   addr2.setFromHostPort("localhost", 0);
107 }
108
109 TEST(SocketAddress, SetFromStrings) {
110   SocketAddress addr;
111
112   // Set from a numeric port string
113   addr.setFromLocalPort("1234");
114   EXPECT_EQ(addr.getPort(), 1234);
115
116   // setFromLocalPort() should not accept service names
117   EXPECT_THROW(addr.setFromLocalPort("http"), std::runtime_error);
118
119   // Call setFromLocalIpPort() with just a port, no IP
120   addr.setFromLocalIpPort("80");
121   EXPECT_EQ(addr.getPort(), 80);
122
123   // Call setFromLocalIpPort() with an IP and port.
124   addr.setFromLocalIpPort("127.0.0.1:4321");
125   EXPECT_EQ(addr.getAddressStr(), "127.0.0.1");
126   EXPECT_EQ(addr.getPort(), 4321);
127
128   // setFromIpPort() without an address should fail
129   EXPECT_THROW(addr.setFromIpPort("4321"), std::invalid_argument);
130
131   // Call setFromIpPort() with an IPv6 address and port
132   addr.setFromIpPort("2620:0:1cfe:face:b00c::3:65535");
133   EXPECT_EQ(addr.getFamily(), AF_INET6);
134   EXPECT_EQ(addr.getAddressStr(), "2620:0:1cfe:face:b00c::3");
135   EXPECT_EQ(addr.getPort(), 65535);
136
137   // Call setFromIpPort() with an IPv4 address and port
138   addr.setFromIpPort("1.2.3.4:9999");
139   EXPECT_EQ(addr.getFamily(), AF_INET);
140   EXPECT_EQ(addr.getAddressStr(), "1.2.3.4");
141   EXPECT_EQ(addr.getPort(), 9999);
142
143   // Call setFromIpPort() with a bracketed IPv6
144   addr.setFromIpPort("[::]:1234");
145   EXPECT_EQ(addr.getFamily(), AF_INET6);
146   EXPECT_EQ(addr.getAddressStr(), "::");
147   EXPECT_EQ(addr.getPort(), 1234);
148
149   // Call setFromIpPort() with a bracketed IPv6
150   addr.setFromIpPort("[9:8::2]:1234");
151   EXPECT_EQ(addr.getFamily(), AF_INET6);
152   EXPECT_EQ(addr.getAddressStr(), "9:8::2");
153   EXPECT_EQ(addr.getPort(), 1234);
154
155   // Call setFromIpPort() with a bracketed IPv6 and no port
156   EXPECT_THROW(addr.setFromIpPort("[::]"), std::system_error);
157 }
158
159 TEST(SocketAddress, EqualityAndHash) {
160   // IPv4
161   SocketAddress local1("127.0.0.1", 1234);
162   EXPECT_EQ(local1, local1);
163   EXPECT_EQ(local1.hash(), local1.hash());
164
165   SocketAddress local2("127.0.0.1", 1234);
166   EXPECT_EQ(local1, local2);
167   EXPECT_EQ(local1.hash(), local2.hash());
168
169   SocketAddress local3("127.0.0.1", 4321);
170   EXPECT_NE(local1, local3);
171   EXPECT_NE(local1.hash(), local3.hash());
172
173   SocketAddress other1("1.2.3.4", 1234);
174   EXPECT_EQ(other1, other1);
175   EXPECT_EQ(other1.hash(), other1.hash());
176   EXPECT_NE(local1, other1);
177   EXPECT_NE(local1.hash(), other1.hash());
178
179   SocketAddress other2("4.3.2.1", 1234);
180   EXPECT_NE(other1.hash(), other2.hash());
181   EXPECT_NE(other1.hash(), other2.hash());
182
183   other2.setFromIpPort("1.2.3.4", 0);
184   EXPECT_NE(other1.hash(), other2.hash());
185   EXPECT_NE(other1.hash(), other2.hash());
186   other2.setPort(1234);
187   EXPECT_EQ(other1.hash(), other2.hash());
188   EXPECT_EQ(other1.hash(), other2.hash());
189
190   // IPv6
191   SocketAddress v6_1("2620:0:1c00:face:b00c:0:0:abcd", 1234);
192   SocketAddress v6_2("2620:0:1c00:face:b00c::abcd", 1234);
193   SocketAddress v6_3("2620:0:1c00:face:b00c::bcda", 1234);
194   EXPECT_EQ(v6_1, v6_2);
195   EXPECT_EQ(v6_1.hash(), v6_2.hash());
196   EXPECT_NE(v6_1, v6_3);
197   EXPECT_NE(v6_1.hash(), v6_3.hash());
198
199   // IPv4 versus IPv6 comparison
200   SocketAddress localIPv6("::1", 1234);
201   // Even though these both refer to localhost,
202   // IPv4 and IPv6 addresses are never treated as the same address
203   EXPECT_NE(local1, localIPv6);
204   EXPECT_NE(local1.hash(), localIPv6.hash());
205
206   // IPv4-mapped IPv6 addresses are not treated as equal
207   // to the equivalent IPv4 address
208   SocketAddress v4("10.0.0.3", 99);
209   SocketAddress v6_mapped1("::ffff:10.0.0.3", 99);
210   SocketAddress v6_mapped2("::ffff:0a00:0003", 99);
211   EXPECT_NE(v4, v6_mapped1);
212   EXPECT_NE(v4, v6_mapped2);
213   EXPECT_EQ(v6_mapped1, v6_mapped2);
214
215   // However, after calling convertToIPv4(), the mapped address should now be
216   // equal to the v4 version.
217   EXPECT_TRUE(v6_mapped1.isIPv4Mapped());
218   v6_mapped1.convertToIPv4();
219   EXPECT_EQ(v6_mapped1, v4);
220   EXPECT_NE(v6_mapped1, v6_mapped2);
221
222   // Unix
223   SocketAddress unix1;
224   unix1.setFromPath("/foo");
225   SocketAddress unix2;
226   unix2.setFromPath("/foo");
227   SocketAddress unix3;
228   unix3.setFromPath("/bar");
229   SocketAddress unixAnon;
230   unixAnon.setFromPath("");
231
232   EXPECT_EQ(unix1, unix2);
233   EXPECT_EQ(unix1.hash(), unix2.hash());
234   EXPECT_NE(unix1, unix3);
235   EXPECT_NE(unix1, unixAnon);
236   EXPECT_NE(unix2, unix3);
237   EXPECT_NE(unix2, unixAnon);
238   // anonymous addresses aren't equal to any other address,
239   // including themselves
240   EXPECT_NE(unixAnon, unixAnon);
241
242   // It isn't strictly required that hashes for different addresses be
243   // different, but we should have very few collisions.  It generally indicates
244   // a problem if these collide
245   EXPECT_NE(unix1.hash(), unix3.hash());
246   EXPECT_NE(unix1.hash(), unixAnon.hash());
247   EXPECT_NE(unix3.hash(), unixAnon.hash());
248 }
249
250 TEST(SocketAddress, IsPrivate) {
251   // IPv4
252   SocketAddress addr("9.255.255.255", 0);
253   EXPECT_TRUE(!addr.isPrivateAddress());
254   addr.setFromIpPort("10.0.0.0", 0);
255   EXPECT_TRUE(addr.isPrivateAddress());
256   addr.setFromIpPort("10.255.255.255", 0);
257   EXPECT_TRUE(addr.isPrivateAddress());
258   addr.setFromIpPort("11.0.0.0", 0);
259   EXPECT_TRUE(!addr.isPrivateAddress());
260
261   addr.setFromIpPort("172.15.255.255", 0);
262   EXPECT_TRUE(!addr.isPrivateAddress());
263   addr.setFromIpPort("172.16.0.0", 0);
264   EXPECT_TRUE(addr.isPrivateAddress());
265   addr.setFromIpPort("172.31.255.255", 0);
266   EXPECT_TRUE(addr.isPrivateAddress());
267   addr.setFromIpPort("172.32.0.0", 0);
268   EXPECT_TRUE(!addr.isPrivateAddress());
269
270   addr.setFromIpPort("192.167.255.255", 0);
271   EXPECT_TRUE(!addr.isPrivateAddress());
272   addr.setFromIpPort("192.168.0.0", 0);
273   EXPECT_TRUE(addr.isPrivateAddress());
274   addr.setFromIpPort("192.168.255.255", 0);
275   EXPECT_TRUE(addr.isPrivateAddress());
276   addr.setFromIpPort("192.169.0.0", 0);
277   EXPECT_TRUE(!addr.isPrivateAddress());
278
279   addr.setFromIpPort("126.255.255.255", 0);
280   EXPECT_TRUE(!addr.isPrivateAddress());
281   addr.setFromIpPort("127.0.0.0", 0);
282   EXPECT_TRUE(addr.isPrivateAddress());
283   addr.setFromIpPort("127.0.0.1", 0);
284   EXPECT_TRUE(addr.isPrivateAddress());
285   addr.setFromIpPort("127.255.255.255", 0);
286   EXPECT_TRUE(addr.isPrivateAddress());
287   addr.setFromIpPort("128.0.0.0", 0);
288   EXPECT_TRUE(!addr.isPrivateAddress());
289
290   addr.setFromIpPort("1.2.3.4", 0);
291   EXPECT_TRUE(!addr.isPrivateAddress());
292   addr.setFromIpPort("69.171.239.10", 0);
293   EXPECT_TRUE(!addr.isPrivateAddress());
294
295   // IPv6
296   addr.setFromIpPort("fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
297   EXPECT_TRUE(!addr.isPrivateAddress());
298   addr.setFromIpPort("fc00::", 0);
299   EXPECT_TRUE(addr.isPrivateAddress());
300   addr.setFromIpPort("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
301   EXPECT_TRUE(addr.isPrivateAddress());
302   addr.setFromIpPort("fe00::", 0);
303   EXPECT_TRUE(!addr.isPrivateAddress());
304
305   addr.setFromIpPort("fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
306   EXPECT_TRUE(!addr.isPrivateAddress());
307   addr.setFromIpPort("fe80::", 0);
308   EXPECT_TRUE(addr.isPrivateAddress());
309   addr.setFromIpPort("fe80::ffff:ffff:ffff:ffff", 0);
310   EXPECT_TRUE(addr.isPrivateAddress());
311   addr.setFromIpPort("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
312   EXPECT_TRUE(addr.isPrivateAddress());
313   addr.setFromIpPort("fec0::", 0);
314   EXPECT_TRUE(!addr.isPrivateAddress());
315
316   addr.setFromIpPort("::0", 0);
317   EXPECT_TRUE(!addr.isPrivateAddress());
318   addr.setFromIpPort("2620:0:1c00:face:b00c:0:0:abcd", 0);
319   EXPECT_TRUE(!addr.isPrivateAddress());
320
321   // IPv4-mapped IPv6
322   addr.setFromIpPort("::ffff:127.0.0.1", 0);
323   EXPECT_TRUE(addr.isPrivateAddress());
324   addr.setFromIpPort("::ffff:10.1.2.3", 0);
325   EXPECT_TRUE(addr.isPrivateAddress());
326   addr.setFromIpPort("::ffff:172.24.0.115", 0);
327   EXPECT_TRUE(addr.isPrivateAddress());
328   addr.setFromIpPort("::ffff:192.168.0.1", 0);
329   EXPECT_TRUE(addr.isPrivateAddress());
330   addr.setFromIpPort("::ffff:69.171.239.10", 0);
331   EXPECT_TRUE(!addr.isPrivateAddress());
332
333   // Unix sockets are considered private addresses
334   addr.setFromPath("/tmp/mysock");
335   EXPECT_TRUE(addr.isPrivateAddress());
336 }
337
338 TEST(SocketAddress, IsLoopback) {
339   // IPv4
340   SocketAddress addr("127.0.0.1", 0);
341   EXPECT_TRUE(addr.isLoopbackAddress());
342   addr.setFromIpPort("127.0.0.0", 0xffff);
343   EXPECT_TRUE(addr.isLoopbackAddress());
344   addr.setFromIpPort("127.1.1.1", 0xffff);
345   EXPECT_TRUE(addr.isLoopbackAddress());
346   addr.setFromIpPort("127.255.255.255", 80);
347   EXPECT_TRUE(addr.isLoopbackAddress());
348
349   addr.setFromIpPort("128.0.0.0", 0);
350   EXPECT_TRUE(!addr.isLoopbackAddress());
351   addr.setFromIpPort("126.255.255.255", 0);
352   EXPECT_TRUE(!addr.isLoopbackAddress());
353   addr.setFromIpPort("10.1.2.3", 0);
354   EXPECT_TRUE(!addr.isLoopbackAddress());
355
356   // IPv6
357   addr.setFromIpPort("::1", 0);
358   EXPECT_TRUE(addr.isLoopbackAddress());
359   addr.setFromIpPort("::0", 0);
360   EXPECT_TRUE(!addr.isLoopbackAddress());
361   addr.setFromIpPort("::2", 0);
362   EXPECT_TRUE(!addr.isLoopbackAddress());
363
364   // IPv4-mapped IPv6
365   addr.setFromIpPort("::ffff:127.0.0.1", 0);
366   EXPECT_TRUE(addr.isLoopbackAddress());
367   addr.setFromIpPort("::ffff:7f0a:141e", 0);
368   EXPECT_TRUE(addr.isLoopbackAddress());
369   addr.setFromIpPort("::ffff:169.254.0.13", 0);
370   EXPECT_TRUE(!addr.isLoopbackAddress());
371
372   // Unix sockets are considered loopback addresses
373   addr.setFromPath("/tmp/mysock");
374   EXPECT_TRUE(addr.isLoopbackAddress());
375 }
376
377 void CheckPrefixMatch(const SocketAddress& first,
378     const SocketAddress& second, unsigned matchingPrefixLen) {
379   unsigned i;
380   for (i = 0; i <= matchingPrefixLen; i++) {
381     EXPECT_TRUE(first.prefixMatch(second, i));
382   }
383   unsigned addrLen = (first.getFamily() == AF_INET6) ? 128 : 32;
384   for (; i <= addrLen; i++) {
385     EXPECT_TRUE(!first.prefixMatch(second, i));
386   }
387 }
388
389 TEST(SocketAddress, PrefixMatch) {
390   // IPv4
391   SocketAddress addr1("127.0.0.1", 0);
392   SocketAddress addr2("127.0.0.1", 0);
393   CheckPrefixMatch(addr1, addr2, 32);
394
395   addr2.setFromIpPort("127.0.1.1", 0);
396   CheckPrefixMatch(addr1, addr2, 23);
397
398   addr2.setFromIpPort("1.1.0.127", 0);
399   CheckPrefixMatch(addr1, addr2, 1);
400
401   // Address family mismatch
402   addr2.setFromIpPort("::ffff:127.0.0.1", 0);
403   EXPECT_TRUE(!addr1.prefixMatch(addr2, 1));
404
405   // IPv6
406   addr1.setFromIpPort("2a03:2880:10:8f02:face:b00c:0:25", 0);
407   CheckPrefixMatch(addr1, addr2, 2);
408
409   addr2.setFromIpPort("2a03:2880:10:8f02:face:b00c:0:25", 0);
410   CheckPrefixMatch(addr1, addr2, 128);
411
412   addr2.setFromIpPort("2a03:2880:30:8f02:face:b00c:0:25", 0);
413   CheckPrefixMatch(addr1, addr2, 42);
414 }
415
416 void CheckFirstLessThanSecond(SocketAddress first, SocketAddress second) {
417   EXPECT_TRUE(!(first < first));
418   EXPECT_TRUE(!(second < second));
419   EXPECT_TRUE(first < second);
420   EXPECT_TRUE(!(first == second));
421   EXPECT_TRUE(!(second < first));
422 }
423
424 TEST(SocketAddress, CheckComparatorBehavior) {
425   SocketAddress first, second;
426   // The following comparison are strict (so if first and second were
427   // inverted that is ok.
428
429   //IP V4
430
431   // port comparisions
432   first.setFromIpPort("128.0.0.0", 0);
433   second.setFromIpPort("128.0.0.0", 0xFFFF);
434   CheckFirstLessThanSecond(first, second);
435   first.setFromIpPort("128.0.0.100", 0);
436   second.setFromIpPort("128.0.0.0", 0xFFFF);
437   CheckFirstLessThanSecond(first, second);
438
439   // Address comparisons
440   first.setFromIpPort("128.0.0.0", 10);
441   second.setFromIpPort("128.0.0.100", 10);
442   CheckFirstLessThanSecond(first, second);
443
444   // Comaprision between IPV4 and IPV6
445   first.setFromIpPort("128.0.0.0", 0);
446   second.setFromIpPort("::ffff:127.0.0.1", 0);
447   CheckFirstLessThanSecond(first, second);
448   first.setFromIpPort("128.0.0.0", 100);
449   second.setFromIpPort("::ffff:127.0.0.1", 0);
450   CheckFirstLessThanSecond(first, second);
451
452   // IPV6 comparisons
453
454   // port comparisions
455   first.setFromIpPort("::0", 0);
456   second.setFromIpPort("::0", 0xFFFF);
457   CheckFirstLessThanSecond(first, second);
458   first.setFromIpPort("::0", 0);
459   second.setFromIpPort("::1", 0xFFFF);
460   CheckFirstLessThanSecond(first, second);
461
462   // Address comparisons
463   first.setFromIpPort("::0", 10);
464   second.setFromIpPort("::1", 10);
465   CheckFirstLessThanSecond(first, second);
466
467   // Unix
468   first.setFromPath("/foo");
469   second.setFromPath("/1234");
470   // The exact comparison order doesn't really matter, as long as
471   // (a < b), (b < a), and (a == b) are consistent.
472   // This checks our current comparison rules, which checks the path length
473   // before the path contents.
474   CheckFirstLessThanSecond(first, second);
475   first.setFromPath("/1234");
476   second.setFromPath("/5678");
477   CheckFirstLessThanSecond(first, second);
478
479   // IPv4 vs Unix.
480   // We currently compare the address family values, and AF_UNIX < AF_INET
481   first.setFromPath("/foo");
482   second.setFromIpPort("127.0.0.1", 80);
483   CheckFirstLessThanSecond(first, second);
484 }
485
486 TEST(SocketAddress, Unix) {
487   SocketAddress addr;
488
489   // Test a small path
490   addr.setFromPath("foo");
491   EXPECT_EQ(addr.getFamily(), AF_UNIX);
492   EXPECT_EQ(addr.describe(), "foo");
493   EXPECT_THROW(addr.getAddressStr(), std::invalid_argument);
494   EXPECT_THROW(addr.getPort(), std::invalid_argument);
495   EXPECT_TRUE(addr.isPrivateAddress());
496   EXPECT_TRUE(addr.isLoopbackAddress());
497
498   // Test a path that is too large
499   const char longPath[] =
500     "abcdefghijklmnopqrstuvwxyz0123456789"
501     "abcdefghijklmnopqrstuvwxyz0123456789"
502     "abcdefghijklmnopqrstuvwxyz0123456789"
503     "abcdefghijklmnopqrstuvwxyz0123456789";
504   EXPECT_THROW(addr.setFromPath(longPath), std::invalid_argument);
505   // The original address should still be the same
506   EXPECT_EQ(addr.getFamily(), AF_UNIX);
507   EXPECT_EQ(addr.describe(), "foo");
508
509   // Test a path that exactly fits in sockaddr_un
510   // (not including the NUL terminator)
511   const char exactLengthPath[] =
512     "abcdefghijklmnopqrstuvwxyz0123456789"
513     "abcdefghijklmnopqrstuvwxyz0123456789"
514     "abcdefghijklmnopqrstuvwxyz0123456789";
515   addr.setFromPath(exactLengthPath);
516   EXPECT_EQ(addr.describe(), exactLengthPath);
517
518   // Test converting a unix socket address to an IPv4 one, then back
519   addr.setFromHostPort("127.0.0.1", 1234);
520   EXPECT_EQ(addr.getFamily(), AF_INET);
521   EXPECT_EQ(addr.describe(), "127.0.0.1:1234");
522   addr.setFromPath("/i/am/a/unix/address");
523   EXPECT_EQ(addr.getFamily(), AF_UNIX);
524   EXPECT_EQ(addr.describe(), "/i/am/a/unix/address");
525
526   // Test copy constructor and assignment operator
527   {
528     SocketAddress copy(addr);
529     EXPECT_EQ(copy, addr);
530     copy.setFromPath("/abc");
531     EXPECT_NE(copy, addr);
532     copy = addr;
533     EXPECT_EQ(copy, addr);
534     copy.setFromIpPort("127.0.0.1", 80);
535     EXPECT_NE(copy, addr);
536     copy = addr;
537     EXPECT_EQ(copy, addr);
538   }
539
540   {
541     SocketAddress copy(addr);
542     EXPECT_EQ(copy, addr);
543     EXPECT_EQ(copy.describe(), "/i/am/a/unix/address");
544     EXPECT_EQ(copy.getPath(), "/i/am/a/unix/address");
545
546     SocketAddress other("127.0.0.1", 80);
547     EXPECT_NE(other, addr);
548     other = copy;
549     EXPECT_EQ(other, copy);
550     EXPECT_EQ(other, addr);
551     EXPECT_EQ(copy, addr);
552   }
553
554 #if __GXX_EXPERIMENTAL_CXX0X__
555   {
556     SocketAddress copy;
557     {
558       // move a unix address into a non-unix address
559       SocketAddress tmpCopy(addr);
560       copy = std::move(tmpCopy);
561     }
562     EXPECT_EQ(copy, addr);
563
564     copy.setFromPath("/another/path");
565     {
566       // move a unix address into a unix address
567       SocketAddress tmpCopy(addr);
568       copy = std::move(tmpCopy);
569     }
570     EXPECT_EQ(copy, addr);
571
572     {
573       // move a non-unix address into a unix address
574       SocketAddress tmp("127.0.0.1", 80);
575       copy = std::move(tmp);
576     }
577     EXPECT_EQ(copy.getAddressStr(), "127.0.0.1");
578     EXPECT_EQ(copy.getPort(), 80);
579
580     copy = addr;
581     // move construct a unix address
582     SocketAddress other(std::move(copy));
583     EXPECT_EQ(other, addr);
584     EXPECT_EQ(other.getPath(), addr.getPath());
585   }
586 #endif
587 }
588
589 TEST(SocketAddress, AnonymousUnix) {
590   // Create a unix socket pair, and get the addresses.
591   int fds[2];
592   int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
593   EXPECT_EQ(rc, 0);
594
595   SocketAddress addr0;
596   SocketAddress peer0;
597   SocketAddress addr1;
598   SocketAddress peer1;
599   addr0.setFromLocalAddress(fds[0]);
600   peer0.setFromPeerAddress(fds[0]);
601   addr1.setFromLocalAddress(fds[1]);
602   peer1.setFromPeerAddress(fds[1]);
603   close(fds[0]);
604   close(fds[1]);
605
606   EXPECT_EQ(addr0.describe(), "<anonymous unix address>");
607   EXPECT_EQ(addr1.describe(), "<anonymous unix address>");
608   EXPECT_EQ(peer0.describe(), "<anonymous unix address>");
609   EXPECT_EQ(peer1.describe(), "<anonymous unix address>");
610
611   // Anonymous addresses should never compare equal
612   EXPECT_NE(addr0, addr1);
613   EXPECT_NE(peer0, peer1);
614
615   // Note that logically addr0 and peer1 are the same,
616   // but since they are both anonymous we have no way to determine this
617   EXPECT_NE(addr0, peer1);
618   // We can't even tell if an anonymous address is equal to itself
619   EXPECT_NE(addr0, addr0);
620 }
621
622 #define REQUIRE_ERRNO(cond, msg) \
623   if (!(cond)) { \
624     int _requireErrnoCopy_ = errno; \
625     std::ostringstream _requireMsg_; \
626     _requireMsg_ << (msg) << ": " << strerror(_requireErrnoCopy_); \
627     ADD_FAILURE(); \
628   }
629
630 void testSetFromSocket(const SocketAddress *serverBindAddr,
631                        const SocketAddress *clientBindAddr,
632                        SocketAddress *listenAddrRet,
633                        SocketAddress *acceptAddrRet,
634                        SocketAddress *serverAddrRet,
635                        SocketAddress *serverPeerAddrRet,
636                        SocketAddress *clientAddrRet,
637                        SocketAddress *clientPeerAddrRet) {
638   int listenSock = socket(serverBindAddr->getFamily(), SOCK_STREAM, 0);
639   REQUIRE_ERRNO(listenSock > 0, "failed to create listen socket");
640   sockaddr_storage laddr;
641   serverBindAddr->getAddress(&laddr);
642   socklen_t laddrLen = serverBindAddr->getActualSize();
643   int rc = bind(listenSock, reinterpret_cast<sockaddr*>(&laddr), laddrLen);
644   REQUIRE_ERRNO(rc == 0, "failed to bind to server socket");
645   rc = listen(listenSock, 10);
646   REQUIRE_ERRNO(rc == 0, "failed to listen");
647
648   listenAddrRet->setFromLocalAddress(listenSock);
649
650   SocketAddress listenPeerAddr;
651   EXPECT_THROW(listenPeerAddr.setFromPeerAddress(listenSock),
652                std::runtime_error);
653
654   // Note that we use the family from serverBindAddr here, since we allow
655   // clientBindAddr to be nullptr.
656   int clientSock = socket(serverBindAddr->getFamily(), SOCK_STREAM, 0);
657   REQUIRE_ERRNO(clientSock > 0, "failed to create client socket");
658   if (clientBindAddr != nullptr) {
659     sockaddr_storage clientAddr;
660     clientBindAddr->getAddress(&clientAddr);
661
662     rc = bind(clientSock, reinterpret_cast<sockaddr*>(&clientAddr),
663               clientBindAddr->getActualSize());
664     REQUIRE_ERRNO(rc == 0, "failed to bind to client socket");
665   }
666
667   sockaddr_storage listenAddr;
668   listenAddrRet->getAddress(&listenAddr);
669   rc = connect(clientSock, reinterpret_cast<sockaddr*>(&listenAddr),
670                listenAddrRet->getActualSize());
671   REQUIRE_ERRNO(rc == 0, "failed to connect");
672
673   sockaddr_storage acceptAddr;
674   socklen_t acceptAddrLen = sizeof(acceptAddr);
675   int serverSock = accept(listenSock,
676       reinterpret_cast<sockaddr*>(&acceptAddr), &acceptAddrLen);
677   REQUIRE_ERRNO(serverSock > 0, "failed to accept");
678   acceptAddrRet->setFromSockaddr(
679       reinterpret_cast<sockaddr*>(&acceptAddr), acceptAddrLen);
680
681   serverAddrRet->setFromLocalAddress(serverSock);
682   serverPeerAddrRet->setFromPeerAddress(serverSock);
683   clientAddrRet->setFromLocalAddress(clientSock);
684   clientPeerAddrRet->setFromPeerAddress(clientSock);
685
686   close(clientSock);
687   close(serverSock);
688   close(listenSock);
689 }
690
691 TEST(SocketAddress, SetFromSocketIPv4) {
692   SocketAddress serverBindAddr("0.0.0.0", 0);
693   SocketAddress clientBindAddr("0.0.0.0", 0);
694   SocketAddress listenAddr;
695   SocketAddress acceptAddr;
696   SocketAddress serverAddr;
697   SocketAddress serverPeerAddr;
698   SocketAddress clientAddr;
699   SocketAddress clientPeerAddr;
700
701   testSetFromSocket(&serverBindAddr, &clientBindAddr,
702                     &listenAddr, &acceptAddr,
703                     &serverAddr, &serverPeerAddr,
704                     &clientAddr, &clientPeerAddr);
705
706   // The server socket's local address should have the same port as the listen
707   // address.  The IP will be different, since the listening socket is
708   // listening on INADDR_ANY, but the server socket will have a concrete IP
709   // address assigned to it.
710   EXPECT_EQ(serverAddr.getPort(), listenAddr.getPort());
711
712   // The client's peer address should always be the same as the server
713   // socket's address.
714   EXPECT_EQ(clientPeerAddr, serverAddr);
715   // The address returned by getpeername() on the server socket should
716   // be the same as the address returned by accept()
717   EXPECT_EQ(serverPeerAddr, acceptAddr);
718   EXPECT_EQ(serverPeerAddr, clientAddr);
719   EXPECT_EQ(acceptAddr, clientAddr);
720 }
721
722 /*
723  * Note this test exercises Linux-specific Unix socket behavior
724  */
725 TEST(SocketAddress, SetFromSocketUnixAbstract) {
726   // Explicitly binding to an empty path results in an abstract socket
727   // name being picked for us automatically.
728   SocketAddress serverBindAddr;
729   string path(1, 0);
730   path.append("test address");
731   serverBindAddr.setFromPath(path);
732   SocketAddress clientBindAddr;
733   clientBindAddr.setFromPath("");
734
735   SocketAddress listenAddr;
736   SocketAddress acceptAddr;
737   SocketAddress serverAddr;
738   SocketAddress serverPeerAddr;
739   SocketAddress clientAddr;
740   SocketAddress clientPeerAddr;
741
742   testSetFromSocket(&serverBindAddr, &clientBindAddr,
743                     &listenAddr, &acceptAddr,
744                     &serverAddr, &serverPeerAddr,
745                     &clientAddr, &clientPeerAddr);
746
747   // The server socket's local address should be the same as the listen
748   // address.
749   EXPECT_EQ(serverAddr, listenAddr);
750
751   // The client's peer address should always be the same as the server
752   // socket's address.
753   EXPECT_EQ(clientPeerAddr, serverAddr);
754
755   EXPECT_EQ(serverPeerAddr, clientAddr);
756   // Oddly, the address returned by accept() does not seem to match the address
757   // returned by getpeername() on the server socket or getsockname() on the
758   // client socket.
759   // EXPECT_EQ(serverPeerAddr, acceptAddr);
760   // EXPECT_EQ(acceptAddr, clientAddr);
761 }
762
763 TEST(SocketAddress, SetFromSocketUnixExplicit) {
764   // Pick two temporary path names.
765   // We use mkstemp() just to avoid warnings about mktemp,
766   // but we need to remove the file to let the socket code bind to it.
767   char serverPath[] = "/tmp/SocketAddressTest.server.XXXXXX";
768   int serverPathFd = mkstemp(serverPath);
769   EXPECT_GE(serverPathFd, 0);
770   char clientPath[] = "/tmp/SocketAddressTest.client.XXXXXX";
771   int clientPathFd = mkstemp(clientPath);
772   EXPECT_GE(clientPathFd, 0);
773
774   int rc = unlink(serverPath);
775   EXPECT_EQ(rc, 0);
776   rc = unlink(clientPath);
777   EXPECT_EQ(rc, 0);
778
779   SocketAddress serverBindAddr;
780   SocketAddress clientBindAddr;
781   SocketAddress listenAddr;
782   SocketAddress acceptAddr;
783   SocketAddress serverAddr;
784   SocketAddress serverPeerAddr;
785   SocketAddress clientAddr;
786   SocketAddress clientPeerAddr;
787   try {
788     serverBindAddr.setFromPath(serverPath);
789     clientBindAddr.setFromPath(clientPath);
790
791     testSetFromSocket(&serverBindAddr, &clientBindAddr,
792                       &listenAddr, &acceptAddr,
793                       &serverAddr, &serverPeerAddr,
794                       &clientAddr, &clientPeerAddr);
795   } catch (...) {
796     // Remove the socket files after we are done
797     unlink(serverPath);
798     unlink(clientPath);
799     throw;
800   }
801   unlink(serverPath);
802   unlink(clientPath);
803
804   // The server socket's local address should be the same as the listen
805   // address.
806   EXPECT_EQ(serverAddr, listenAddr);
807
808   // The client's peer address should always be the same as the server
809   // socket's address.
810   EXPECT_EQ(clientPeerAddr, serverAddr);
811
812   EXPECT_EQ(serverPeerAddr, clientAddr);
813   EXPECT_EQ(serverPeerAddr, acceptAddr);
814   EXPECT_EQ(acceptAddr, clientAddr);
815 }
816
817 TEST(SocketAddress, SetFromSocketUnixAnonymous) {
818   // Test an anonymous client talking to a fixed-path unix socket.
819   char serverPath[] = "/tmp/SocketAddressTest.server.XXXXXX";
820   int serverPathFd = mkstemp(serverPath);
821   EXPECT_GE(serverPathFd, 0);
822   int rc = unlink(serverPath);
823   EXPECT_EQ(rc, 0);
824
825   SocketAddress serverBindAddr;
826   SocketAddress listenAddr;
827   SocketAddress acceptAddr;
828   SocketAddress serverAddr;
829   SocketAddress serverPeerAddr;
830   SocketAddress clientAddr;
831   SocketAddress clientPeerAddr;
832   try {
833     serverBindAddr.setFromPath(serverPath);
834
835     testSetFromSocket(&serverBindAddr, nullptr,
836                       &listenAddr, &acceptAddr,
837                       &serverAddr, &serverPeerAddr,
838                       &clientAddr, &clientPeerAddr);
839   } catch (...) {
840     // Remove the socket file after we are done
841     unlink(serverPath);
842     throw;
843   }
844   unlink(serverPath);
845
846   // The server socket's local address should be the same as the listen
847   // address.
848   EXPECT_EQ(serverAddr, listenAddr);
849
850   // The client's peer address should always be the same as the server
851   // socket's address.
852   EXPECT_EQ(clientPeerAddr, serverAddr);
853
854   // Since the client is using an anonymous address, it won't compare equal to
855   // any other anonymous addresses.  Make sure the addresses are anonymous.
856   EXPECT_EQ(serverPeerAddr.getPath(), "");
857   EXPECT_EQ(clientAddr.getPath(), "");
858   EXPECT_EQ(acceptAddr.getPath(), "");
859 }
860
861 TEST(SocketAddress, ResetUnixAddress) {
862   SocketAddress addy;
863   addy.setFromPath("/foo");
864
865   addy.reset();
866   EXPECT_EQ(addy.getFamily(), AF_UNSPEC);
867 }