xref: /aosp_15_r20/system/netd/server/SockDiagTest.cpp (revision 8542734a0dd1db395a4d42aae09c37f3c3c3e7a1)
1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker  * Copyright 2016 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker  *
4*8542734aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker  *
8*8542734aSAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker  *
10*8542734aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker  * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker  *
16*8542734aSAndroid Build Coastguard Worker  * sock_diag_test.cpp - unit tests for SockDiag.cpp
17*8542734aSAndroid Build Coastguard Worker  */
18*8542734aSAndroid Build Coastguard Worker 
19*8542734aSAndroid Build Coastguard Worker #include <sys/socket.h>
20*8542734aSAndroid Build Coastguard Worker #include <netdb.h>
21*8542734aSAndroid Build Coastguard Worker #include <arpa/inet.h>
22*8542734aSAndroid Build Coastguard Worker #include <netinet/in.h>
23*8542734aSAndroid Build Coastguard Worker #include <netinet/tcp.h>
24*8542734aSAndroid Build Coastguard Worker #include <linux/inet_diag.h>
25*8542734aSAndroid Build Coastguard Worker 
26*8542734aSAndroid Build Coastguard Worker #include <gtest/gtest.h>
27*8542734aSAndroid Build Coastguard Worker #include <netdutils/NetNativeTestBase.h>
28*8542734aSAndroid Build Coastguard Worker 
29*8542734aSAndroid Build Coastguard Worker #include "Fwmark.h"
30*8542734aSAndroid Build Coastguard Worker #include "NetdConstants.h"
31*8542734aSAndroid Build Coastguard Worker #include "SockDiag.h"
32*8542734aSAndroid Build Coastguard Worker #include "UidRanges.h"
33*8542734aSAndroid Build Coastguard Worker 
34*8542734aSAndroid Build Coastguard Worker namespace android {
35*8542734aSAndroid Build Coastguard Worker namespace net {
36*8542734aSAndroid Build Coastguard Worker 
37*8542734aSAndroid Build Coastguard Worker class SockDiagTest : public NetNativeTestBase {
38*8542734aSAndroid Build Coastguard Worker protected:
isLoopbackSocket(const inet_diag_msg * msg)39*8542734aSAndroid Build Coastguard Worker     static bool isLoopbackSocket(const inet_diag_msg *msg) {
40*8542734aSAndroid Build Coastguard Worker         return SockDiag::isLoopbackSocket(msg);
41*8542734aSAndroid Build Coastguard Worker     };
42*8542734aSAndroid Build Coastguard Worker };
43*8542734aSAndroid Build Coastguard Worker 
bindAndListen(int s)44*8542734aSAndroid Build Coastguard Worker uint16_t bindAndListen(int s) {
45*8542734aSAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++) {
46*8542734aSAndroid Build Coastguard Worker         uint16_t port = 1024 + arc4random_uniform(0xffff - 1024);
47*8542734aSAndroid Build Coastguard Worker         sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
48*8542734aSAndroid Build Coastguard Worker         if (bind(s, (sockaddr *) &sin6, sizeof(sin6)) == 0) {
49*8542734aSAndroid Build Coastguard Worker             listen(s, 1);
50*8542734aSAndroid Build Coastguard Worker             return port;
51*8542734aSAndroid Build Coastguard Worker         }
52*8542734aSAndroid Build Coastguard Worker     }
53*8542734aSAndroid Build Coastguard Worker     close(s);
54*8542734aSAndroid Build Coastguard Worker     return 0;
55*8542734aSAndroid Build Coastguard Worker }
56*8542734aSAndroid Build Coastguard Worker 
tcpStateName(uint8_t state)57*8542734aSAndroid Build Coastguard Worker const char *tcpStateName(uint8_t state) {
58*8542734aSAndroid Build Coastguard Worker     static const char *states[] = {
59*8542734aSAndroid Build Coastguard Worker         "???",
60*8542734aSAndroid Build Coastguard Worker         "TCP_ESTABLISHED",
61*8542734aSAndroid Build Coastguard Worker         "TCP_SYN_SENT",
62*8542734aSAndroid Build Coastguard Worker         "TCP_SYN_RECV",
63*8542734aSAndroid Build Coastguard Worker         "TCP_FIN_WAIT1",
64*8542734aSAndroid Build Coastguard Worker         "TCP_FIN_WAIT2",
65*8542734aSAndroid Build Coastguard Worker         "TCP_TIME_WAIT",
66*8542734aSAndroid Build Coastguard Worker         "TCP_CLOSE",
67*8542734aSAndroid Build Coastguard Worker         "TCP_CLOSE_WAIT",
68*8542734aSAndroid Build Coastguard Worker         "TCP_LAST_ACK",
69*8542734aSAndroid Build Coastguard Worker         "TCP_LISTEN",
70*8542734aSAndroid Build Coastguard Worker         "TCP_CLOSING",
71*8542734aSAndroid Build Coastguard Worker         "TCP_NEW_SYN_RECV",
72*8542734aSAndroid Build Coastguard Worker     };
73*8542734aSAndroid Build Coastguard Worker     return states[(state < ARRAY_SIZE(states)) ? state : 0];
74*8542734aSAndroid Build Coastguard Worker }
75*8542734aSAndroid Build Coastguard Worker 
TEST_F(SockDiagTest,TestDump)76*8542734aSAndroid Build Coastguard Worker TEST_F(SockDiagTest, TestDump) {
77*8542734aSAndroid Build Coastguard Worker     int v4socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
78*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(-1, v4socket) << "Failed to open IPv4 socket: " << strerror(errno);
79*8542734aSAndroid Build Coastguard Worker     int v6socket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
80*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(-1, v6socket) << "Failed to open IPv6 socket: " << strerror(errno);
81*8542734aSAndroid Build Coastguard Worker     int listensocket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
82*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(-1, listensocket) << "Failed to open listen socket: " << strerror(errno);
83*8542734aSAndroid Build Coastguard Worker 
84*8542734aSAndroid Build Coastguard Worker     uint16_t port = bindAndListen(listensocket);
85*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(0, port) << "Can't bind to server port";
86*8542734aSAndroid Build Coastguard Worker 
87*8542734aSAndroid Build Coastguard Worker     // Connect to loopback.
88*8542734aSAndroid Build Coastguard Worker     sockaddr_in server4 = { .sin_family = AF_INET, .sin_port = htons(port) };
89*8542734aSAndroid Build Coastguard Worker     sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
90*8542734aSAndroid Build Coastguard Worker     ASSERT_EQ(0, connect(v4socket, (sockaddr *) &server4, sizeof(server4)))
91*8542734aSAndroid Build Coastguard Worker         << "IPv4 connect failed: " << strerror(errno);
92*8542734aSAndroid Build Coastguard Worker     ASSERT_EQ(0, connect(v6socket, (sockaddr *) &server6, sizeof(server6)))
93*8542734aSAndroid Build Coastguard Worker         << "IPv6 connect failed: " << strerror(errno);
94*8542734aSAndroid Build Coastguard Worker 
95*8542734aSAndroid Build Coastguard Worker     sockaddr_in6 client46, client6;
96*8542734aSAndroid Build Coastguard Worker     socklen_t clientlen = std::max(sizeof(client46), sizeof(client6));
97*8542734aSAndroid Build Coastguard Worker     int accepted4 = accept4(
98*8542734aSAndroid Build Coastguard Worker             listensocket, (sockaddr *) &client46, &clientlen, SOCK_CLOEXEC);
99*8542734aSAndroid Build Coastguard Worker     int accepted6 = accept4(
100*8542734aSAndroid Build Coastguard Worker             listensocket, (sockaddr *) &client6, &clientlen, SOCK_CLOEXEC);
101*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(-1, accepted4);
102*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(-1, accepted6);
103*8542734aSAndroid Build Coastguard Worker 
104*8542734aSAndroid Build Coastguard Worker     int v4SocketsSeen = 0;
105*8542734aSAndroid Build Coastguard Worker     bool seenclient46 = false;
106*8542734aSAndroid Build Coastguard Worker     char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
107*8542734aSAndroid Build Coastguard Worker 
108*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "Ports:\n  server=%d. client46=%d, client6=%d\n",
109*8542734aSAndroid Build Coastguard Worker             port, ntohs(client46.sin6_port), ntohs(client6.sin6_port));
110*8542734aSAndroid Build Coastguard Worker 
111*8542734aSAndroid Build Coastguard Worker     auto checkIPv4Dump = [&] (uint8_t /* proto */, const inet_diag_msg *msg) {
112*8542734aSAndroid Build Coastguard Worker         EXPECT_EQ(htonl(INADDR_LOOPBACK), msg->id.idiag_src[0]);
113*8542734aSAndroid Build Coastguard Worker         v4SocketsSeen++;
114*8542734aSAndroid Build Coastguard Worker         seenclient46 |= (msg->id.idiag_sport == client46.sin6_port);
115*8542734aSAndroid Build Coastguard Worker         inet_ntop(AF_INET, msg->id.idiag_src, src, sizeof(src));
116*8542734aSAndroid Build Coastguard Worker         inet_ntop(AF_INET, msg->id.idiag_src, dst, sizeof(dst));
117*8542734aSAndroid Build Coastguard Worker         fprintf(stderr, "  v4 %s:%d -> %s:%d %s\n",
118*8542734aSAndroid Build Coastguard Worker                 src, htons(msg->id.idiag_sport),
119*8542734aSAndroid Build Coastguard Worker                 dst, htons(msg->id.idiag_dport),
120*8542734aSAndroid Build Coastguard Worker                 tcpStateName(msg->idiag_state));
121*8542734aSAndroid Build Coastguard Worker         if (msg->idiag_state == TCP_ESTABLISHED) {
122*8542734aSAndroid Build Coastguard Worker             EXPECT_TRUE(isLoopbackSocket(msg));
123*8542734aSAndroid Build Coastguard Worker         }
124*8542734aSAndroid Build Coastguard Worker         return false;
125*8542734aSAndroid Build Coastguard Worker     };
126*8542734aSAndroid Build Coastguard Worker 
127*8542734aSAndroid Build Coastguard Worker     int v6SocketsSeen = 0;
128*8542734aSAndroid Build Coastguard Worker     bool seenClient6 = false, seenServer46 = false, seenServer6 = false;
129*8542734aSAndroid Build Coastguard Worker 
130*8542734aSAndroid Build Coastguard Worker     auto checkIPv6Dump = [&] (uint8_t /* proto */, const inet_diag_msg *msg) {
131*8542734aSAndroid Build Coastguard Worker         struct in6_addr *saddr = (struct in6_addr *) msg->id.idiag_src;
132*8542734aSAndroid Build Coastguard Worker         EXPECT_TRUE(
133*8542734aSAndroid Build Coastguard Worker             IN6_IS_ADDR_LOOPBACK(saddr) ||
134*8542734aSAndroid Build Coastguard Worker             (IN6_IS_ADDR_V4MAPPED(saddr) && saddr->s6_addr32[3] == htonl(INADDR_LOOPBACK)));
135*8542734aSAndroid Build Coastguard Worker         v6SocketsSeen++;
136*8542734aSAndroid Build Coastguard Worker         seenClient6 |= (msg->id.idiag_sport == client6.sin6_port);
137*8542734aSAndroid Build Coastguard Worker         seenServer46 |= (msg->id.idiag_sport == htons(port));
138*8542734aSAndroid Build Coastguard Worker         seenServer6 |= (msg->id.idiag_sport == htons(port));
139*8542734aSAndroid Build Coastguard Worker         inet_ntop(AF_INET6, msg->id.idiag_src, src, sizeof(src));
140*8542734aSAndroid Build Coastguard Worker         inet_ntop(AF_INET6, msg->id.idiag_src, dst, sizeof(dst));
141*8542734aSAndroid Build Coastguard Worker         fprintf(stderr, "  v6 [%s]:%d -> [%s]:%d %s\n",
142*8542734aSAndroid Build Coastguard Worker                 src, htons(msg->id.idiag_sport),
143*8542734aSAndroid Build Coastguard Worker                 dst, htons(msg->id.idiag_dport),
144*8542734aSAndroid Build Coastguard Worker                 tcpStateName(msg->idiag_state));
145*8542734aSAndroid Build Coastguard Worker         if (msg->idiag_state == TCP_ESTABLISHED) {
146*8542734aSAndroid Build Coastguard Worker             EXPECT_TRUE(isLoopbackSocket(msg));
147*8542734aSAndroid Build Coastguard Worker         }
148*8542734aSAndroid Build Coastguard Worker         return false;
149*8542734aSAndroid Build Coastguard Worker     };
150*8542734aSAndroid Build Coastguard Worker 
151*8542734aSAndroid Build Coastguard Worker     SockDiag sd;
152*8542734aSAndroid Build Coastguard Worker     ASSERT_TRUE(sd.open()) << "Failed to open SOCK_DIAG socket";
153*8542734aSAndroid Build Coastguard Worker 
154*8542734aSAndroid Build Coastguard Worker     int ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET, "127.0.0.1");
155*8542734aSAndroid Build Coastguard Worker     ASSERT_EQ(0, ret) << "Failed to send IPv4 dump request: " << strerror(-ret);
156*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "Sent IPv4 dump\n");
157*8542734aSAndroid Build Coastguard Worker     sd.readDiagMsg(IPPROTO_TCP, checkIPv4Dump);
158*8542734aSAndroid Build Coastguard Worker     EXPECT_GE(v4SocketsSeen, 1);
159*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(seenclient46);
160*8542734aSAndroid Build Coastguard Worker     EXPECT_FALSE(seenServer46);
161*8542734aSAndroid Build Coastguard Worker 
162*8542734aSAndroid Build Coastguard Worker     ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET6, "127.0.0.1");
163*8542734aSAndroid Build Coastguard Worker     ASSERT_EQ(0, ret) << "Failed to send mapped dump request: " << strerror(-ret);
164*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "Sent mapped dump\n");
165*8542734aSAndroid Build Coastguard Worker     sd.readDiagMsg(IPPROTO_TCP, checkIPv6Dump);
166*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(seenServer46);
167*8542734aSAndroid Build Coastguard Worker 
168*8542734aSAndroid Build Coastguard Worker     ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET6, "::1");
169*8542734aSAndroid Build Coastguard Worker     ASSERT_EQ(0, ret) << "Failed to send IPv6 dump request: " << strerror(-ret);
170*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "Sent IPv6 dump\n");
171*8542734aSAndroid Build Coastguard Worker 
172*8542734aSAndroid Build Coastguard Worker     sd.readDiagMsg(IPPROTO_TCP, checkIPv6Dump);
173*8542734aSAndroid Build Coastguard Worker     EXPECT_GE(v6SocketsSeen, 1);
174*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(seenClient6);
175*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(seenServer6);
176*8542734aSAndroid Build Coastguard Worker 
177*8542734aSAndroid Build Coastguard Worker     close(v4socket);
178*8542734aSAndroid Build Coastguard Worker     close(v6socket);
179*8542734aSAndroid Build Coastguard Worker     close(listensocket);
180*8542734aSAndroid Build Coastguard Worker     close(accepted4);
181*8542734aSAndroid Build Coastguard Worker     close(accepted6);
182*8542734aSAndroid Build Coastguard Worker }
183*8542734aSAndroid Build Coastguard Worker 
fillDiagAddr(__be32 addr[4],const sockaddr * sa)184*8542734aSAndroid Build Coastguard Worker bool fillDiagAddr(__be32 addr[4], const sockaddr *sa) {
185*8542734aSAndroid Build Coastguard Worker     switch (sa->sa_family) {
186*8542734aSAndroid Build Coastguard Worker         case AF_INET: {
187*8542734aSAndroid Build Coastguard Worker             sockaddr_in *sin = (sockaddr_in *) sa;
188*8542734aSAndroid Build Coastguard Worker             memcpy(addr, &sin->sin_addr, sizeof(sin->sin_addr));
189*8542734aSAndroid Build Coastguard Worker             return true;
190*8542734aSAndroid Build Coastguard Worker         }
191*8542734aSAndroid Build Coastguard Worker         case AF_INET6: {
192*8542734aSAndroid Build Coastguard Worker             sockaddr_in6 *sin6 = (sockaddr_in6 *) sa;
193*8542734aSAndroid Build Coastguard Worker             memcpy(addr, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
194*8542734aSAndroid Build Coastguard Worker             return true;
195*8542734aSAndroid Build Coastguard Worker         }
196*8542734aSAndroid Build Coastguard Worker         default:
197*8542734aSAndroid Build Coastguard Worker             return false;
198*8542734aSAndroid Build Coastguard Worker     }
199*8542734aSAndroid Build Coastguard Worker }
200*8542734aSAndroid Build Coastguard Worker 
makeDiagMessage(__u8 family,const sockaddr * src,const sockaddr * dst)201*8542734aSAndroid Build Coastguard Worker inet_diag_msg makeDiagMessage(__u8 family,  const sockaddr *src, const sockaddr *dst) {
202*8542734aSAndroid Build Coastguard Worker     inet_diag_msg msg = {
203*8542734aSAndroid Build Coastguard Worker             .idiag_family = family,
204*8542734aSAndroid Build Coastguard Worker             .idiag_state = TCP_ESTABLISHED,
205*8542734aSAndroid Build Coastguard Worker             .id =
206*8542734aSAndroid Build Coastguard Worker                     {
207*8542734aSAndroid Build Coastguard Worker                             .idiag_sport = 1234,
208*8542734aSAndroid Build Coastguard Worker                             .idiag_dport = 4321,
209*8542734aSAndroid Build Coastguard Worker                     },
210*8542734aSAndroid Build Coastguard Worker             .idiag_uid = AID_APP + 123,
211*8542734aSAndroid Build Coastguard Worker             .idiag_inode = 123456789,
212*8542734aSAndroid Build Coastguard Worker     };
213*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(fillDiagAddr(msg.id.idiag_src, src));
214*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(fillDiagAddr(msg.id.idiag_dst, dst));
215*8542734aSAndroid Build Coastguard Worker     return msg;
216*8542734aSAndroid Build Coastguard Worker }
217*8542734aSAndroid Build Coastguard Worker 
makeDiagMessage(const char * srcstr,const char * dststr)218*8542734aSAndroid Build Coastguard Worker inet_diag_msg makeDiagMessage(const char* srcstr, const char* dststr) {
219*8542734aSAndroid Build Coastguard Worker     addrinfo hints = { .ai_flags = AI_NUMERICHOST }, *src, *dst;
220*8542734aSAndroid Build Coastguard Worker     EXPECT_EQ(0, getaddrinfo(srcstr, nullptr, &hints, &src));
221*8542734aSAndroid Build Coastguard Worker     EXPECT_EQ(0, getaddrinfo(dststr, nullptr, &hints, &dst));
222*8542734aSAndroid Build Coastguard Worker     EXPECT_EQ(src->ai_addr->sa_family, dst->ai_addr->sa_family);
223*8542734aSAndroid Build Coastguard Worker     inet_diag_msg msg = makeDiagMessage(src->ai_addr->sa_family, src->ai_addr, dst->ai_addr);
224*8542734aSAndroid Build Coastguard Worker     freeaddrinfo(src);
225*8542734aSAndroid Build Coastguard Worker     freeaddrinfo(dst);
226*8542734aSAndroid Build Coastguard Worker     return msg;
227*8542734aSAndroid Build Coastguard Worker }
228*8542734aSAndroid Build Coastguard Worker 
TEST_F(SockDiagTest,TestIsLoopbackSocket)229*8542734aSAndroid Build Coastguard Worker TEST_F(SockDiagTest, TestIsLoopbackSocket) {
230*8542734aSAndroid Build Coastguard Worker     inet_diag_msg msg;
231*8542734aSAndroid Build Coastguard Worker 
232*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("127.0.0.1", "127.0.0.1");
233*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
234*8542734aSAndroid Build Coastguard Worker 
235*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("::1", "::1");
236*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
237*8542734aSAndroid Build Coastguard Worker 
238*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("::1", "::ffff:127.0.0.1");
239*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
240*8542734aSAndroid Build Coastguard Worker 
241*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("192.0.2.1", "192.0.2.1");
242*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
243*8542734aSAndroid Build Coastguard Worker 
244*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("192.0.2.1", "8.8.8.8");
245*8542734aSAndroid Build Coastguard Worker     EXPECT_FALSE(isLoopbackSocket(&msg));
246*8542734aSAndroid Build Coastguard Worker 
247*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("192.0.2.1", "127.0.0.1");
248*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
249*8542734aSAndroid Build Coastguard Worker 
250*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("2001:db8::1", "2001:db8::1");
251*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
252*8542734aSAndroid Build Coastguard Worker 
253*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("2001:db8::1", "2001:4860:4860::6464");
254*8542734aSAndroid Build Coastguard Worker     EXPECT_FALSE(isLoopbackSocket(&msg));
255*8542734aSAndroid Build Coastguard Worker 
256*8542734aSAndroid Build Coastguard Worker     // While isLoopbackSocket returns true on these sockets, we usually don't want to close them
257*8542734aSAndroid Build Coastguard Worker     // because they aren't specific to any particular network and thus don't become unusable when
258*8542734aSAndroid Build Coastguard Worker     // an app's routing changes or its network access is removed.
259*8542734aSAndroid Build Coastguard Worker     //
260*8542734aSAndroid Build Coastguard Worker     // This isn't a problem, as anything that calls destroyLiveSockets will skip them because
261*8542734aSAndroid Build Coastguard Worker     // destroyLiveSockets only enumerates ESTABLISHED, SYN_SENT, and SYN_RECV sockets.
262*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("127.0.0.1", "0.0.0.0");
263*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
264*8542734aSAndroid Build Coastguard Worker 
265*8542734aSAndroid Build Coastguard Worker     msg = makeDiagMessage("::1", "::");
266*8542734aSAndroid Build Coastguard Worker     EXPECT_TRUE(isLoopbackSocket(&msg));
267*8542734aSAndroid Build Coastguard Worker }
268*8542734aSAndroid Build Coastguard Worker 
269*8542734aSAndroid Build Coastguard Worker enum MicroBenchmarkTestType {
270*8542734aSAndroid Build Coastguard Worker     ADDRESS,
271*8542734aSAndroid Build Coastguard Worker     UID,
272*8542734aSAndroid Build Coastguard Worker     UID_EXCLUDE_LOOPBACK,
273*8542734aSAndroid Build Coastguard Worker     UIDRANGE,
274*8542734aSAndroid Build Coastguard Worker     UIDRANGE_EXCLUDE_LOOPBACK,
275*8542734aSAndroid Build Coastguard Worker     PERMISSION,
276*8542734aSAndroid Build Coastguard Worker };
277*8542734aSAndroid Build Coastguard Worker 
testTypeName(MicroBenchmarkTestType mode)278*8542734aSAndroid Build Coastguard Worker const char *testTypeName(MicroBenchmarkTestType mode) {
279*8542734aSAndroid Build Coastguard Worker #define TO_STRING_TYPE(x) case ((x)): return #x;
280*8542734aSAndroid Build Coastguard Worker     switch((mode)) {
281*8542734aSAndroid Build Coastguard Worker         TO_STRING_TYPE(ADDRESS);
282*8542734aSAndroid Build Coastguard Worker         TO_STRING_TYPE(UID);
283*8542734aSAndroid Build Coastguard Worker         TO_STRING_TYPE(UID_EXCLUDE_LOOPBACK);
284*8542734aSAndroid Build Coastguard Worker         TO_STRING_TYPE(UIDRANGE);
285*8542734aSAndroid Build Coastguard Worker         TO_STRING_TYPE(UIDRANGE_EXCLUDE_LOOPBACK);
286*8542734aSAndroid Build Coastguard Worker         TO_STRING_TYPE(PERMISSION);
287*8542734aSAndroid Build Coastguard Worker     }
288*8542734aSAndroid Build Coastguard Worker #undef TO_STRING_TYPE
289*8542734aSAndroid Build Coastguard Worker }
290*8542734aSAndroid Build Coastguard Worker 
291*8542734aSAndroid Build Coastguard Worker static struct {
292*8542734aSAndroid Build Coastguard Worker     unsigned netId;
293*8542734aSAndroid Build Coastguard Worker     bool explicitlySelected;
294*8542734aSAndroid Build Coastguard Worker     Permission permission;
295*8542734aSAndroid Build Coastguard Worker } permissionTestcases[] = {
296*8542734aSAndroid Build Coastguard Worker     { 42, false, PERMISSION_NONE,    },
297*8542734aSAndroid Build Coastguard Worker     { 42, false, PERMISSION_NETWORK, },
298*8542734aSAndroid Build Coastguard Worker     { 42, false, PERMISSION_SYSTEM,  },
299*8542734aSAndroid Build Coastguard Worker     { 42, true,  PERMISSION_NONE,    },
300*8542734aSAndroid Build Coastguard Worker     { 42, true,  PERMISSION_NETWORK, },
301*8542734aSAndroid Build Coastguard Worker     { 42, true,  PERMISSION_SYSTEM,  },
302*8542734aSAndroid Build Coastguard Worker     { 43, false, PERMISSION_NONE,    },
303*8542734aSAndroid Build Coastguard Worker     { 43, false, PERMISSION_NETWORK, },
304*8542734aSAndroid Build Coastguard Worker     { 43, false, PERMISSION_SYSTEM,  },
305*8542734aSAndroid Build Coastguard Worker     { 43, true,  PERMISSION_NONE,    },
306*8542734aSAndroid Build Coastguard Worker     { 43, true,  PERMISSION_NETWORK, },
307*8542734aSAndroid Build Coastguard Worker     { 43, true,  PERMISSION_SYSTEM,  },
308*8542734aSAndroid Build Coastguard Worker };
309*8542734aSAndroid Build Coastguard Worker 
310*8542734aSAndroid Build Coastguard Worker class SockDiagMicroBenchmarkTest : public ::testing::TestWithParam<MicroBenchmarkTestType> {
311*8542734aSAndroid Build Coastguard Worker 
312*8542734aSAndroid Build Coastguard Worker public:
SetUp()313*8542734aSAndroid Build Coastguard Worker     void SetUp() {
314*8542734aSAndroid Build Coastguard Worker         ASSERT_TRUE(mSd.open()) << "Failed to open SOCK_DIAG socket";
315*8542734aSAndroid Build Coastguard Worker     }
316*8542734aSAndroid Build Coastguard Worker 
317*8542734aSAndroid Build Coastguard Worker protected:
318*8542734aSAndroid Build Coastguard Worker     SockDiag mSd;
319*8542734aSAndroid Build Coastguard Worker 
320*8542734aSAndroid Build Coastguard Worker     constexpr static int MAX_SOCKETS = 500;
321*8542734aSAndroid Build Coastguard Worker     constexpr static int ADDRESS_SOCKETS = 500;
322*8542734aSAndroid Build Coastguard Worker     constexpr static int UID_SOCKETS = 50;
323*8542734aSAndroid Build Coastguard Worker     constexpr static int PERMISSION_SOCKETS = 16;
324*8542734aSAndroid Build Coastguard Worker 
325*8542734aSAndroid Build Coastguard Worker     constexpr static uid_t START_UID = 8000;  // START_UID + number of sockets must be <= 9999.
326*8542734aSAndroid Build Coastguard Worker     constexpr static int CLOSE_UID = START_UID + UID_SOCKETS - 42;  // Close to the end
327*8542734aSAndroid Build Coastguard Worker     static_assert(START_UID + MAX_SOCKETS < 9999, "Too many sockets");
328*8542734aSAndroid Build Coastguard Worker 
329*8542734aSAndroid Build Coastguard Worker     constexpr static int TEST_NETID = 42;  // One of the OEM netIds.
330*8542734aSAndroid Build Coastguard Worker 
331*8542734aSAndroid Build Coastguard Worker 
howManySockets()332*8542734aSAndroid Build Coastguard Worker     int howManySockets() {
333*8542734aSAndroid Build Coastguard Worker         MicroBenchmarkTestType mode = GetParam();
334*8542734aSAndroid Build Coastguard Worker         switch (mode) {
335*8542734aSAndroid Build Coastguard Worker         case ADDRESS:
336*8542734aSAndroid Build Coastguard Worker             return ADDRESS_SOCKETS;
337*8542734aSAndroid Build Coastguard Worker         case UID:
338*8542734aSAndroid Build Coastguard Worker         case UID_EXCLUDE_LOOPBACK:
339*8542734aSAndroid Build Coastguard Worker         case UIDRANGE:
340*8542734aSAndroid Build Coastguard Worker         case UIDRANGE_EXCLUDE_LOOPBACK:
341*8542734aSAndroid Build Coastguard Worker             return UID_SOCKETS;
342*8542734aSAndroid Build Coastguard Worker         case PERMISSION:
343*8542734aSAndroid Build Coastguard Worker             return ARRAY_SIZE(permissionTestcases);
344*8542734aSAndroid Build Coastguard Worker         }
345*8542734aSAndroid Build Coastguard Worker     }
346*8542734aSAndroid Build Coastguard Worker 
modifySocketForTest(int s,int i)347*8542734aSAndroid Build Coastguard Worker     int modifySocketForTest(int s, int i) {
348*8542734aSAndroid Build Coastguard Worker         MicroBenchmarkTestType mode = GetParam();
349*8542734aSAndroid Build Coastguard Worker         switch (mode) {
350*8542734aSAndroid Build Coastguard Worker         case UID:
351*8542734aSAndroid Build Coastguard Worker         case UID_EXCLUDE_LOOPBACK:
352*8542734aSAndroid Build Coastguard Worker         case UIDRANGE:
353*8542734aSAndroid Build Coastguard Worker         case UIDRANGE_EXCLUDE_LOOPBACK: {
354*8542734aSAndroid Build Coastguard Worker             uid_t uid = START_UID + i;
355*8542734aSAndroid Build Coastguard Worker             return fchown(s, uid, -1);
356*8542734aSAndroid Build Coastguard Worker         }
357*8542734aSAndroid Build Coastguard Worker         case PERMISSION: {
358*8542734aSAndroid Build Coastguard Worker             Fwmark fwmark;
359*8542734aSAndroid Build Coastguard Worker             fwmark.netId = permissionTestcases[i].netId;
360*8542734aSAndroid Build Coastguard Worker             fwmark.explicitlySelected = permissionTestcases[i].explicitlySelected;
361*8542734aSAndroid Build Coastguard Worker             fwmark.permission = permissionTestcases[i].permission;
362*8542734aSAndroid Build Coastguard Worker             return setsockopt(s, SOL_SOCKET, SO_MARK, &fwmark.intValue, sizeof(fwmark.intValue));
363*8542734aSAndroid Build Coastguard Worker         }
364*8542734aSAndroid Build Coastguard Worker         default:
365*8542734aSAndroid Build Coastguard Worker             return 0;
366*8542734aSAndroid Build Coastguard Worker         }
367*8542734aSAndroid Build Coastguard Worker     }
368*8542734aSAndroid Build Coastguard Worker 
destroySockets()369*8542734aSAndroid Build Coastguard Worker     int destroySockets() {
370*8542734aSAndroid Build Coastguard Worker         MicroBenchmarkTestType mode = GetParam();
371*8542734aSAndroid Build Coastguard Worker         int ret;
372*8542734aSAndroid Build Coastguard Worker         switch (mode) {
373*8542734aSAndroid Build Coastguard Worker             case ADDRESS:
374*8542734aSAndroid Build Coastguard Worker                 ret = mSd.destroySockets("::1", 0 /* ifindex */);
375*8542734aSAndroid Build Coastguard Worker                 EXPECT_LE(0, ret) << ": Failed to destroy sockets on ::1: " << strerror(-ret);
376*8542734aSAndroid Build Coastguard Worker                 break;
377*8542734aSAndroid Build Coastguard Worker             case UID:
378*8542734aSAndroid Build Coastguard Worker             case UID_EXCLUDE_LOOPBACK: {
379*8542734aSAndroid Build Coastguard Worker                 bool excludeLoopback = (mode == UID_EXCLUDE_LOOPBACK);
380*8542734aSAndroid Build Coastguard Worker                 ret = mSd.destroySockets(IPPROTO_TCP, CLOSE_UID, excludeLoopback);
381*8542734aSAndroid Build Coastguard Worker                 EXPECT_LE(0, ret) << ": Failed to destroy sockets for UID " << CLOSE_UID << ": " <<
382*8542734aSAndroid Build Coastguard Worker                         strerror(-ret);
383*8542734aSAndroid Build Coastguard Worker                 break;
384*8542734aSAndroid Build Coastguard Worker             }
385*8542734aSAndroid Build Coastguard Worker             case UIDRANGE:
386*8542734aSAndroid Build Coastguard Worker             case UIDRANGE_EXCLUDE_LOOPBACK: {
387*8542734aSAndroid Build Coastguard Worker                 bool excludeLoopback = (mode == UIDRANGE_EXCLUDE_LOOPBACK);
388*8542734aSAndroid Build Coastguard Worker                 const char *uidRangeStrings[] = { "8005-8012", "8042", "8043", "8090-8099" };
389*8542734aSAndroid Build Coastguard Worker                 std::set<uid_t> skipUids { 8007, 8043, 8098, 8099 };
390*8542734aSAndroid Build Coastguard Worker                 UidRanges uidRanges;
391*8542734aSAndroid Build Coastguard Worker                 uidRanges.parseFrom(ARRAY_SIZE(uidRangeStrings), (char **) uidRangeStrings);
392*8542734aSAndroid Build Coastguard Worker                 ret = mSd.destroySockets(uidRanges, skipUids, excludeLoopback);
393*8542734aSAndroid Build Coastguard Worker                 break;
394*8542734aSAndroid Build Coastguard Worker             }
395*8542734aSAndroid Build Coastguard Worker             case PERMISSION: {
396*8542734aSAndroid Build Coastguard Worker                 ret = mSd.destroySocketsLackingPermission(TEST_NETID, PERMISSION_NETWORK, false);
397*8542734aSAndroid Build Coastguard Worker                 break;
398*8542734aSAndroid Build Coastguard Worker             }
399*8542734aSAndroid Build Coastguard Worker         }
400*8542734aSAndroid Build Coastguard Worker         return ret;
401*8542734aSAndroid Build Coastguard Worker     }
402*8542734aSAndroid Build Coastguard Worker 
shouldHaveClosedSocket(int i)403*8542734aSAndroid Build Coastguard Worker     bool shouldHaveClosedSocket(int i) {
404*8542734aSAndroid Build Coastguard Worker         MicroBenchmarkTestType mode = GetParam();
405*8542734aSAndroid Build Coastguard Worker         switch (mode) {
406*8542734aSAndroid Build Coastguard Worker             case ADDRESS:
407*8542734aSAndroid Build Coastguard Worker                 return true;
408*8542734aSAndroid Build Coastguard Worker             case UID:
409*8542734aSAndroid Build Coastguard Worker                 return i == CLOSE_UID - START_UID;
410*8542734aSAndroid Build Coastguard Worker             case UIDRANGE: {
411*8542734aSAndroid Build Coastguard Worker                 uid_t uid = i + START_UID;
412*8542734aSAndroid Build Coastguard Worker                 // Skip UIDs in skipUids.
413*8542734aSAndroid Build Coastguard Worker                 if (uid == 8007 || uid == 8043 || uid == 8098 || uid == 8099) {
414*8542734aSAndroid Build Coastguard Worker                     return false;
415*8542734aSAndroid Build Coastguard Worker                 }
416*8542734aSAndroid Build Coastguard Worker                 // Include UIDs in uidRanges.
417*8542734aSAndroid Build Coastguard Worker                 if ((8005 <= uid && uid <= 8012) || uid == 8042 || (8090 <= uid && uid <= 8099)) {
418*8542734aSAndroid Build Coastguard Worker                     return true;
419*8542734aSAndroid Build Coastguard Worker                 }
420*8542734aSAndroid Build Coastguard Worker                 return false;
421*8542734aSAndroid Build Coastguard Worker             }
422*8542734aSAndroid Build Coastguard Worker             case UID_EXCLUDE_LOOPBACK:
423*8542734aSAndroid Build Coastguard Worker             case UIDRANGE_EXCLUDE_LOOPBACK:
424*8542734aSAndroid Build Coastguard Worker                 return false;
425*8542734aSAndroid Build Coastguard Worker             case PERMISSION:
426*8542734aSAndroid Build Coastguard Worker                 if (permissionTestcases[i].netId != 42) return false;
427*8542734aSAndroid Build Coastguard Worker                 if (permissionTestcases[i].explicitlySelected != 1) return true;
428*8542734aSAndroid Build Coastguard Worker                 Permission permission = permissionTestcases[i].permission;
429*8542734aSAndroid Build Coastguard Worker                 return permission != PERMISSION_NETWORK && permission != PERMISSION_SYSTEM;
430*8542734aSAndroid Build Coastguard Worker         }
431*8542734aSAndroid Build Coastguard Worker     }
432*8542734aSAndroid Build Coastguard Worker 
checkSocketState(int i,int sock,const char * msg)433*8542734aSAndroid Build Coastguard Worker     bool checkSocketState(int i, int sock, const char *msg) {
434*8542734aSAndroid Build Coastguard Worker         const char data[] = "foo";
435*8542734aSAndroid Build Coastguard Worker         const int ret = send(sock, data, sizeof(data), 0);
436*8542734aSAndroid Build Coastguard Worker         const int err = errno;
437*8542734aSAndroid Build Coastguard Worker         if (!shouldHaveClosedSocket(i)) {
438*8542734aSAndroid Build Coastguard Worker             EXPECT_EQ((ssize_t) sizeof(data), ret) <<
439*8542734aSAndroid Build Coastguard Worker                     "Write on open socket failed: " << strerror(err);
440*8542734aSAndroid Build Coastguard Worker             return false;
441*8542734aSAndroid Build Coastguard Worker         }
442*8542734aSAndroid Build Coastguard Worker 
443*8542734aSAndroid Build Coastguard Worker         EXPECT_EQ(-1, ret) << msg << " " << i << " not closed";
444*8542734aSAndroid Build Coastguard Worker         if (ret != -1) {
445*8542734aSAndroid Build Coastguard Worker             return false;
446*8542734aSAndroid Build Coastguard Worker         }
447*8542734aSAndroid Build Coastguard Worker 
448*8542734aSAndroid Build Coastguard Worker         // Since we're connected to ourselves, the error might be ECONNABORTED (if we destroyed the
449*8542734aSAndroid Build Coastguard Worker         // socket) or ECONNRESET (if the other end was destroyed and sent a RST).
450*8542734aSAndroid Build Coastguard Worker         EXPECT_TRUE(err == ECONNABORTED || err == ECONNRESET)
451*8542734aSAndroid Build Coastguard Worker             << msg << ": unexpected error: " << strerror(err);
452*8542734aSAndroid Build Coastguard Worker         return (err == ECONNABORTED);  // Return true iff. SOCK_DESTROY closed this socket.
453*8542734aSAndroid Build Coastguard Worker     }
454*8542734aSAndroid Build Coastguard Worker };
455*8542734aSAndroid Build Coastguard Worker 
TEST_P(SockDiagMicroBenchmarkTest,TestMicroBenchmark)456*8542734aSAndroid Build Coastguard Worker TEST_P(SockDiagMicroBenchmarkTest, TestMicroBenchmark) {
457*8542734aSAndroid Build Coastguard Worker     MicroBenchmarkTestType mode = GetParam();
458*8542734aSAndroid Build Coastguard Worker 
459*8542734aSAndroid Build Coastguard Worker     int numSockets = howManySockets();
460*8542734aSAndroid Build Coastguard Worker 
461*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "Benchmarking closing %d sockets based on %s\n",
462*8542734aSAndroid Build Coastguard Worker             numSockets, testTypeName(mode));
463*8542734aSAndroid Build Coastguard Worker 
464*8542734aSAndroid Build Coastguard Worker     int listensocket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
465*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(-1, listensocket) << "Failed to open listen socket";
466*8542734aSAndroid Build Coastguard Worker 
467*8542734aSAndroid Build Coastguard Worker     uint16_t port = bindAndListen(listensocket);
468*8542734aSAndroid Build Coastguard Worker     ASSERT_NE(0, port) << "Can't bind to server port";
469*8542734aSAndroid Build Coastguard Worker     sockaddr_in6 server = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
470*8542734aSAndroid Build Coastguard Worker 
471*8542734aSAndroid Build Coastguard Worker     using ms = std::chrono::duration<float, std::ratio<1, 1000>>;
472*8542734aSAndroid Build Coastguard Worker 
473*8542734aSAndroid Build Coastguard Worker     int clientsockets[MAX_SOCKETS], serversockets[MAX_SOCKETS];
474*8542734aSAndroid Build Coastguard Worker     uint16_t clientports[MAX_SOCKETS];
475*8542734aSAndroid Build Coastguard Worker     sockaddr_in6 client;
476*8542734aSAndroid Build Coastguard Worker     socklen_t clientlen;
477*8542734aSAndroid Build Coastguard Worker 
478*8542734aSAndroid Build Coastguard Worker     auto start = std::chrono::steady_clock::now();
479*8542734aSAndroid Build Coastguard Worker     for (int i = 0; i < numSockets; i++) {
480*8542734aSAndroid Build Coastguard Worker         int s = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
481*8542734aSAndroid Build Coastguard Worker         clientlen = sizeof(client);
482*8542734aSAndroid Build Coastguard Worker         ASSERT_EQ(0, connect(s, (sockaddr *) &server, sizeof(server)))
483*8542734aSAndroid Build Coastguard Worker             << "Connecting socket " << i << " failed " << strerror(errno);
484*8542734aSAndroid Build Coastguard Worker         ASSERT_EQ(0, modifySocketForTest(s, i));
485*8542734aSAndroid Build Coastguard Worker         serversockets[i] = accept4(
486*8542734aSAndroid Build Coastguard Worker                 listensocket, (sockaddr *) &client, &clientlen, SOCK_CLOEXEC);
487*8542734aSAndroid Build Coastguard Worker         ASSERT_NE(-1, serversockets[i])
488*8542734aSAndroid Build Coastguard Worker             << "Accepting socket " << i << " failed " << strerror(errno);
489*8542734aSAndroid Build Coastguard Worker         clientports[i] = client.sin6_port;
490*8542734aSAndroid Build Coastguard Worker         clientsockets[i] = s;
491*8542734aSAndroid Build Coastguard Worker     }
492*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "  Connecting: %6.1f ms\n",
493*8542734aSAndroid Build Coastguard Worker             std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());
494*8542734aSAndroid Build Coastguard Worker 
495*8542734aSAndroid Build Coastguard Worker     start = std::chrono::steady_clock::now();
496*8542734aSAndroid Build Coastguard Worker     destroySockets();
497*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "  Destroying: %6.1f ms\n",
498*8542734aSAndroid Build Coastguard Worker             std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());
499*8542734aSAndroid Build Coastguard Worker 
500*8542734aSAndroid Build Coastguard Worker     start = std::chrono::steady_clock::now();
501*8542734aSAndroid Build Coastguard Worker     int socketsClosed = 0;
502*8542734aSAndroid Build Coastguard Worker     for (int i = 0; i < numSockets; i++) {
503*8542734aSAndroid Build Coastguard Worker         socketsClosed += checkSocketState(i, clientsockets[i], "Client socket");
504*8542734aSAndroid Build Coastguard Worker         socketsClosed += checkSocketState(i, serversockets[i], "Server socket");
505*8542734aSAndroid Build Coastguard Worker     }
506*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "   Verifying: %6.1f ms (%d sockets destroyed)\n",
507*8542734aSAndroid Build Coastguard Worker             std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count(),
508*8542734aSAndroid Build Coastguard Worker             socketsClosed);
509*8542734aSAndroid Build Coastguard Worker     if (strstr(testTypeName(mode), "_EXCLUDE_LOOPBACK") == nullptr) {
510*8542734aSAndroid Build Coastguard Worker         EXPECT_GT(socketsClosed, 0);  // Just in case there's a bug in the test.
511*8542734aSAndroid Build Coastguard Worker     }
512*8542734aSAndroid Build Coastguard Worker 
513*8542734aSAndroid Build Coastguard Worker     start = std::chrono::steady_clock::now();
514*8542734aSAndroid Build Coastguard Worker     for (int i = 0; i < numSockets; i++) {
515*8542734aSAndroid Build Coastguard Worker         close(clientsockets[i]);
516*8542734aSAndroid Build Coastguard Worker         close(serversockets[i]);
517*8542734aSAndroid Build Coastguard Worker     }
518*8542734aSAndroid Build Coastguard Worker     fprintf(stderr, "     Closing: %6.1f ms\n",
519*8542734aSAndroid Build Coastguard Worker             std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());
520*8542734aSAndroid Build Coastguard Worker 
521*8542734aSAndroid Build Coastguard Worker     close(listensocket);
522*8542734aSAndroid Build Coastguard Worker }
523*8542734aSAndroid Build Coastguard Worker 
524*8542734aSAndroid Build Coastguard Worker // "SockDiagTest.cpp:232: error: undefined reference to 'SockDiagMicroBenchmarkTest::CLOSE_UID'".
525*8542734aSAndroid Build Coastguard Worker constexpr int SockDiagMicroBenchmarkTest::CLOSE_UID;
526*8542734aSAndroid Build Coastguard Worker 
527*8542734aSAndroid Build Coastguard Worker INSTANTIATE_TEST_CASE_P(Address, SockDiagMicroBenchmarkTest,
528*8542734aSAndroid Build Coastguard Worker                         testing::Values(ADDRESS, UID, UIDRANGE,
529*8542734aSAndroid Build Coastguard Worker                                         UID_EXCLUDE_LOOPBACK, UIDRANGE_EXCLUDE_LOOPBACK,
530*8542734aSAndroid Build Coastguard Worker                                         PERMISSION));
531*8542734aSAndroid Build Coastguard Worker 
532*8542734aSAndroid Build Coastguard Worker }  // namespace net
533*8542734aSAndroid Build Coastguard Worker }  // namespace android
534