1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/socket/udp_client_socket.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
8*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
9*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
10*6777b538SAndroid Build Coastguard Worker #include "net/base/network_change_notifier.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation.h"
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker namespace net {
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker
CreateNetLogUDPConnectParams(const IPEndPoint & address,int net_error)17*6777b538SAndroid Build Coastguard Worker base::Value::Dict CreateNetLogUDPConnectParams(const IPEndPoint& address,
18*6777b538SAndroid Build Coastguard Worker int net_error) {
19*6777b538SAndroid Build Coastguard Worker DCHECK_NE(ERR_IO_PENDING, net_error);
20*6777b538SAndroid Build Coastguard Worker auto params = base::Value::Dict().Set("address", address.ToString());
21*6777b538SAndroid Build Coastguard Worker if (net_error < 0) {
22*6777b538SAndroid Build Coastguard Worker params.Set("net_error", net_error);
23*6777b538SAndroid Build Coastguard Worker }
24*6777b538SAndroid Build Coastguard Worker return params;
25*6777b538SAndroid Build Coastguard Worker }
26*6777b538SAndroid Build Coastguard Worker
CreateNetLogUDPBindToNetworkParams(handles::NetworkHandle network,int net_error)27*6777b538SAndroid Build Coastguard Worker base::Value::Dict CreateNetLogUDPBindToNetworkParams(
28*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle network,
29*6777b538SAndroid Build Coastguard Worker int net_error) {
30*6777b538SAndroid Build Coastguard Worker DCHECK_NE(ERR_IO_PENDING, net_error);
31*6777b538SAndroid Build Coastguard Worker auto params = base::Value::Dict().Set("network", static_cast<int>(network));
32*6777b538SAndroid Build Coastguard Worker if (net_error < 0) {
33*6777b538SAndroid Build Coastguard Worker params.Set("net_error", net_error);
34*6777b538SAndroid Build Coastguard Worker }
35*6777b538SAndroid Build Coastguard Worker return params;
36*6777b538SAndroid Build Coastguard Worker }
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker } // namespace
39*6777b538SAndroid Build Coastguard Worker
UDPClientSocket(DatagramSocket::BindType bind_type,net::NetLog * net_log,const net::NetLogSource & source,handles::NetworkHandle network)40*6777b538SAndroid Build Coastguard Worker UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type,
41*6777b538SAndroid Build Coastguard Worker net::NetLog* net_log,
42*6777b538SAndroid Build Coastguard Worker const net::NetLogSource& source,
43*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle network)
44*6777b538SAndroid Build Coastguard Worker : net_log_(
45*6777b538SAndroid Build Coastguard Worker NetLogWithSource::Make(net_log, NetLogSourceType::UDP_CLIENT_SOCKET)),
46*6777b538SAndroid Build Coastguard Worker socket_(bind_type, net_log, net_log_.source()),
47*6777b538SAndroid Build Coastguard Worker connect_using_network_(network) {
48*6777b538SAndroid Build Coastguard Worker net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE, source);
49*6777b538SAndroid Build Coastguard Worker }
50*6777b538SAndroid Build Coastguard Worker
UDPClientSocket(DatagramSocket::BindType bind_type,NetLogWithSource source_net_log,handles::NetworkHandle network)51*6777b538SAndroid Build Coastguard Worker UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type,
52*6777b538SAndroid Build Coastguard Worker NetLogWithSource source_net_log,
53*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle network)
54*6777b538SAndroid Build Coastguard Worker : net_log_(NetLogWithSource::Make(source_net_log.net_log(),
55*6777b538SAndroid Build Coastguard Worker NetLogSourceType::UDP_CLIENT_SOCKET)),
56*6777b538SAndroid Build Coastguard Worker socket_(bind_type, net_log_),
57*6777b538SAndroid Build Coastguard Worker connect_using_network_(network) {
58*6777b538SAndroid Build Coastguard Worker net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE,
59*6777b538SAndroid Build Coastguard Worker source_net_log.source());
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker
~UDPClientSocket()62*6777b538SAndroid Build Coastguard Worker UDPClientSocket::~UDPClientSocket() {
63*6777b538SAndroid Build Coastguard Worker net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE);
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker
Connect(const IPEndPoint & address)66*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::Connect(const IPEndPoint& address) {
67*6777b538SAndroid Build Coastguard Worker CHECK(!connect_called_);
68*6777b538SAndroid Build Coastguard Worker if (connect_using_network_ != handles::kInvalidNetworkHandle)
69*6777b538SAndroid Build Coastguard Worker return ConnectUsingNetwork(connect_using_network_, address);
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker connect_called_ = true;
72*6777b538SAndroid Build Coastguard Worker int rv = OK;
73*6777b538SAndroid Build Coastguard Worker if (!adopted_opened_socket_) {
74*6777b538SAndroid Build Coastguard Worker rv = socket_.Open(address.GetFamily());
75*6777b538SAndroid Build Coastguard Worker net_log_.AddEventWithNetErrorCode(NetLogEventType::SOCKET_OPEN, rv);
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker if (rv != OK)
78*6777b538SAndroid Build Coastguard Worker return rv;
79*6777b538SAndroid Build Coastguard Worker rv = socket_.Connect(address);
80*6777b538SAndroid Build Coastguard Worker net_log_.AddEvent(NetLogEventType::SOCKET_CONNECT,
81*6777b538SAndroid Build Coastguard Worker [&] { return CreateNetLogUDPConnectParams(address, rv); });
82*6777b538SAndroid Build Coastguard Worker return rv;
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker
ConnectUsingNetwork(handles::NetworkHandle network,const IPEndPoint & address)85*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::ConnectUsingNetwork(handles::NetworkHandle network,
86*6777b538SAndroid Build Coastguard Worker const IPEndPoint& address) {
87*6777b538SAndroid Build Coastguard Worker CHECK(!connect_called_);
88*6777b538SAndroid Build Coastguard Worker connect_called_ = true;
89*6777b538SAndroid Build Coastguard Worker if (!NetworkChangeNotifier::AreNetworkHandlesSupported())
90*6777b538SAndroid Build Coastguard Worker return ERR_NOT_IMPLEMENTED;
91*6777b538SAndroid Build Coastguard Worker int rv = OK;
92*6777b538SAndroid Build Coastguard Worker if (!adopted_opened_socket_) {
93*6777b538SAndroid Build Coastguard Worker rv = socket_.Open(address.GetFamily());
94*6777b538SAndroid Build Coastguard Worker net_log_.AddEventWithNetErrorCode(NetLogEventType::SOCKET_OPEN, rv);
95*6777b538SAndroid Build Coastguard Worker }
96*6777b538SAndroid Build Coastguard Worker if (rv != OK) {
97*6777b538SAndroid Build Coastguard Worker return rv;
98*6777b538SAndroid Build Coastguard Worker }
99*6777b538SAndroid Build Coastguard Worker rv = socket_.BindToNetwork(network);
100*6777b538SAndroid Build Coastguard Worker net_log_.AddEvent(NetLogEventType::SOCKET_BIND_TO_NETWORK, [&] {
101*6777b538SAndroid Build Coastguard Worker return CreateNetLogUDPBindToNetworkParams(network, rv);
102*6777b538SAndroid Build Coastguard Worker });
103*6777b538SAndroid Build Coastguard Worker if (rv != OK)
104*6777b538SAndroid Build Coastguard Worker return rv;
105*6777b538SAndroid Build Coastguard Worker network_ = network;
106*6777b538SAndroid Build Coastguard Worker rv = socket_.Connect(address);
107*6777b538SAndroid Build Coastguard Worker net_log_.AddEvent(NetLogEventType::SOCKET_CONNECT,
108*6777b538SAndroid Build Coastguard Worker [&] { return CreateNetLogUDPConnectParams(address, rv); });
109*6777b538SAndroid Build Coastguard Worker return rv;
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker
ConnectUsingDefaultNetwork(const IPEndPoint & address)112*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::ConnectUsingDefaultNetwork(const IPEndPoint& address) {
113*6777b538SAndroid Build Coastguard Worker CHECK(!connect_called_);
114*6777b538SAndroid Build Coastguard Worker connect_called_ = true;
115*6777b538SAndroid Build Coastguard Worker if (!NetworkChangeNotifier::AreNetworkHandlesSupported())
116*6777b538SAndroid Build Coastguard Worker return ERR_NOT_IMPLEMENTED;
117*6777b538SAndroid Build Coastguard Worker int rv = OK;
118*6777b538SAndroid Build Coastguard Worker if (!adopted_opened_socket_) {
119*6777b538SAndroid Build Coastguard Worker rv = socket_.Open(address.GetFamily());
120*6777b538SAndroid Build Coastguard Worker net_log_.AddEventWithNetErrorCode(NetLogEventType::SOCKET_OPEN, rv);
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker if (rv != OK)
123*6777b538SAndroid Build Coastguard Worker return rv;
124*6777b538SAndroid Build Coastguard Worker // Calling connect() will bind a socket to the default network, however there
125*6777b538SAndroid Build Coastguard Worker // is no way to determine what network the socket got bound to. The
126*6777b538SAndroid Build Coastguard Worker // alternative is to query what the default network is and bind the socket to
127*6777b538SAndroid Build Coastguard Worker // that network explicitly, however this is racy because the default network
128*6777b538SAndroid Build Coastguard Worker // can change in between when we query it and when we bind to it. This is
129*6777b538SAndroid Build Coastguard Worker // rare but should be accounted for. Since changes of the default network
130*6777b538SAndroid Build Coastguard Worker // should not come in quick succession, we can simply try again.
131*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle network;
132*6777b538SAndroid Build Coastguard Worker for (int attempt = 0; attempt < 2; attempt++) {
133*6777b538SAndroid Build Coastguard Worker network = NetworkChangeNotifier::GetDefaultNetwork();
134*6777b538SAndroid Build Coastguard Worker if (network == handles::kInvalidNetworkHandle)
135*6777b538SAndroid Build Coastguard Worker return ERR_INTERNET_DISCONNECTED;
136*6777b538SAndroid Build Coastguard Worker rv = socket_.BindToNetwork(network);
137*6777b538SAndroid Build Coastguard Worker net_log_.AddEvent(NetLogEventType::SOCKET_BIND_TO_NETWORK, [&] {
138*6777b538SAndroid Build Coastguard Worker return CreateNetLogUDPBindToNetworkParams(network, rv);
139*6777b538SAndroid Build Coastguard Worker });
140*6777b538SAndroid Build Coastguard Worker // |network| may have disconnected between the call to GetDefaultNetwork()
141*6777b538SAndroid Build Coastguard Worker // and the call to BindToNetwork(). Loop only if this is the case (|rv| will
142*6777b538SAndroid Build Coastguard Worker // be ERR_NETWORK_CHANGED).
143*6777b538SAndroid Build Coastguard Worker if (rv != ERR_NETWORK_CHANGED)
144*6777b538SAndroid Build Coastguard Worker break;
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker if (rv != OK)
147*6777b538SAndroid Build Coastguard Worker return rv;
148*6777b538SAndroid Build Coastguard Worker network_ = network;
149*6777b538SAndroid Build Coastguard Worker rv = socket_.Connect(address);
150*6777b538SAndroid Build Coastguard Worker net_log_.AddEvent(NetLogEventType::SOCKET_CONNECT,
151*6777b538SAndroid Build Coastguard Worker [&] { return CreateNetLogUDPConnectParams(address, rv); });
152*6777b538SAndroid Build Coastguard Worker return rv;
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker
ConnectAsync(const IPEndPoint & address,CompletionOnceCallback callback)155*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::ConnectAsync(const IPEndPoint& address,
156*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) {
157*6777b538SAndroid Build Coastguard Worker DCHECK(callback);
158*6777b538SAndroid Build Coastguard Worker return Connect(address);
159*6777b538SAndroid Build Coastguard Worker }
160*6777b538SAndroid Build Coastguard Worker
ConnectUsingNetworkAsync(handles::NetworkHandle network,const IPEndPoint & address,CompletionOnceCallback callback)161*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::ConnectUsingNetworkAsync(handles::NetworkHandle network,
162*6777b538SAndroid Build Coastguard Worker const IPEndPoint& address,
163*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) {
164*6777b538SAndroid Build Coastguard Worker DCHECK(callback);
165*6777b538SAndroid Build Coastguard Worker return ConnectUsingNetwork(network, address);
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker
ConnectUsingDefaultNetworkAsync(const IPEndPoint & address,CompletionOnceCallback callback)168*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::ConnectUsingDefaultNetworkAsync(
169*6777b538SAndroid Build Coastguard Worker const IPEndPoint& address,
170*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) {
171*6777b538SAndroid Build Coastguard Worker DCHECK(callback);
172*6777b538SAndroid Build Coastguard Worker return ConnectUsingDefaultNetwork(address);
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker
GetBoundNetwork() const175*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle UDPClientSocket::GetBoundNetwork() const {
176*6777b538SAndroid Build Coastguard Worker return network_;
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker
ApplySocketTag(const SocketTag & tag)179*6777b538SAndroid Build Coastguard Worker void UDPClientSocket::ApplySocketTag(const SocketTag& tag) {
180*6777b538SAndroid Build Coastguard Worker socket_.ApplySocketTag(tag);
181*6777b538SAndroid Build Coastguard Worker }
182*6777b538SAndroid Build Coastguard Worker
Read(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)183*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::Read(IOBuffer* buf,
184*6777b538SAndroid Build Coastguard Worker int buf_len,
185*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) {
186*6777b538SAndroid Build Coastguard Worker return socket_.Read(buf, buf_len, std::move(callback));
187*6777b538SAndroid Build Coastguard Worker }
188*6777b538SAndroid Build Coastguard Worker
Write(IOBuffer * buf,int buf_len,CompletionOnceCallback callback,const NetworkTrafficAnnotationTag & traffic_annotation)189*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::Write(
190*6777b538SAndroid Build Coastguard Worker IOBuffer* buf,
191*6777b538SAndroid Build Coastguard Worker int buf_len,
192*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback,
193*6777b538SAndroid Build Coastguard Worker const NetworkTrafficAnnotationTag& traffic_annotation) {
194*6777b538SAndroid Build Coastguard Worker return socket_.Write(buf, buf_len, std::move(callback), traffic_annotation);
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker
Close()197*6777b538SAndroid Build Coastguard Worker void UDPClientSocket::Close() {
198*6777b538SAndroid Build Coastguard Worker socket_.Close();
199*6777b538SAndroid Build Coastguard Worker adopted_opened_socket_ = false;
200*6777b538SAndroid Build Coastguard Worker }
201*6777b538SAndroid Build Coastguard Worker
GetPeerAddress(IPEndPoint * address) const202*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::GetPeerAddress(IPEndPoint* address) const {
203*6777b538SAndroid Build Coastguard Worker return socket_.GetPeerAddress(address);
204*6777b538SAndroid Build Coastguard Worker }
205*6777b538SAndroid Build Coastguard Worker
GetLocalAddress(IPEndPoint * address) const206*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::GetLocalAddress(IPEndPoint* address) const {
207*6777b538SAndroid Build Coastguard Worker return socket_.GetLocalAddress(address);
208*6777b538SAndroid Build Coastguard Worker }
209*6777b538SAndroid Build Coastguard Worker
SetReceiveBufferSize(int32_t size)210*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::SetReceiveBufferSize(int32_t size) {
211*6777b538SAndroid Build Coastguard Worker return socket_.SetReceiveBufferSize(size);
212*6777b538SAndroid Build Coastguard Worker }
213*6777b538SAndroid Build Coastguard Worker
SetSendBufferSize(int32_t size)214*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::SetSendBufferSize(int32_t size) {
215*6777b538SAndroid Build Coastguard Worker return socket_.SetSendBufferSize(size);
216*6777b538SAndroid Build Coastguard Worker }
217*6777b538SAndroid Build Coastguard Worker
SetDoNotFragment()218*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::SetDoNotFragment() {
219*6777b538SAndroid Build Coastguard Worker return socket_.SetDoNotFragment();
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker
SetRecvTos()222*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::SetRecvTos() {
223*6777b538SAndroid Build Coastguard Worker return socket_.SetRecvTos();
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker
SetTos(DiffServCodePoint dscp,EcnCodePoint ecn)226*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::SetTos(DiffServCodePoint dscp, EcnCodePoint ecn) {
227*6777b538SAndroid Build Coastguard Worker return socket_.SetTos(dscp, ecn);
228*6777b538SAndroid Build Coastguard Worker }
229*6777b538SAndroid Build Coastguard Worker
SetMsgConfirm(bool confirm)230*6777b538SAndroid Build Coastguard Worker void UDPClientSocket::SetMsgConfirm(bool confirm) {
231*6777b538SAndroid Build Coastguard Worker socket_.SetMsgConfirm(confirm);
232*6777b538SAndroid Build Coastguard Worker }
233*6777b538SAndroid Build Coastguard Worker
NetLog() const234*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& UDPClientSocket::NetLog() const {
235*6777b538SAndroid Build Coastguard Worker return socket_.NetLog();
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker
UseNonBlockingIO()238*6777b538SAndroid Build Coastguard Worker void UDPClientSocket::UseNonBlockingIO() {
239*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
240*6777b538SAndroid Build Coastguard Worker socket_.UseNonBlockingIO();
241*6777b538SAndroid Build Coastguard Worker #endif
242*6777b538SAndroid Build Coastguard Worker }
243*6777b538SAndroid Build Coastguard Worker
SetMulticastInterface(uint32_t interface_index)244*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::SetMulticastInterface(uint32_t interface_index) {
245*6777b538SAndroid Build Coastguard Worker return socket_.SetMulticastInterface(interface_index);
246*6777b538SAndroid Build Coastguard Worker }
247*6777b538SAndroid Build Coastguard Worker
EnableRecvOptimization()248*6777b538SAndroid Build Coastguard Worker void UDPClientSocket::EnableRecvOptimization() {
249*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX)
250*6777b538SAndroid Build Coastguard Worker socket_.enable_experimental_recv_optimization();
251*6777b538SAndroid Build Coastguard Worker #endif
252*6777b538SAndroid Build Coastguard Worker }
253*6777b538SAndroid Build Coastguard Worker
SetIOSNetworkServiceType(int ios_network_service_type)254*6777b538SAndroid Build Coastguard Worker void UDPClientSocket::SetIOSNetworkServiceType(int ios_network_service_type) {
255*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX)
256*6777b538SAndroid Build Coastguard Worker socket_.SetIOSNetworkServiceType(ios_network_service_type);
257*6777b538SAndroid Build Coastguard Worker #endif
258*6777b538SAndroid Build Coastguard Worker }
259*6777b538SAndroid Build Coastguard Worker
AdoptOpenedSocket(AddressFamily address_family,SocketDescriptor socket)260*6777b538SAndroid Build Coastguard Worker int UDPClientSocket::AdoptOpenedSocket(AddressFamily address_family,
261*6777b538SAndroid Build Coastguard Worker SocketDescriptor socket) {
262*6777b538SAndroid Build Coastguard Worker int rv = socket_.AdoptOpenedSocket(address_family, socket);
263*6777b538SAndroid Build Coastguard Worker if (rv == OK) {
264*6777b538SAndroid Build Coastguard Worker adopted_opened_socket_ = true;
265*6777b538SAndroid Build Coastguard Worker }
266*6777b538SAndroid Build Coastguard Worker return rv;
267*6777b538SAndroid Build Coastguard Worker }
268*6777b538SAndroid Build Coastguard Worker
GetLastTos() const269*6777b538SAndroid Build Coastguard Worker DscpAndEcn UDPClientSocket::GetLastTos() const {
270*6777b538SAndroid Build Coastguard Worker return socket_.GetLastTos();
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker
273*6777b538SAndroid Build Coastguard Worker } // namespace net
274