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