1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker * Copyright (C) 2012-2013 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker *
4*598139dcSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker *
8*598139dcSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker *
10*598139dcSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker */
16*598139dcSAndroid Build Coastguard Worker
17*598139dcSAndroid Build Coastguard Worker #include <ctype.h>
18*598139dcSAndroid Build Coastguard Worker #include <inttypes.h>
19*598139dcSAndroid Build Coastguard Worker #include <poll.h>
20*598139dcSAndroid Build Coastguard Worker #include <sched.h>
21*598139dcSAndroid Build Coastguard Worker #include <sys/prctl.h>
22*598139dcSAndroid Build Coastguard Worker #include <sys/socket.h>
23*598139dcSAndroid Build Coastguard Worker #include <sys/types.h>
24*598139dcSAndroid Build Coastguard Worker
25*598139dcSAndroid Build Coastguard Worker #include <chrono>
26*598139dcSAndroid Build Coastguard Worker
27*598139dcSAndroid Build Coastguard Worker #include <android-base/logging.h>
28*598139dcSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
29*598139dcSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
30*598139dcSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
31*598139dcSAndroid Build Coastguard Worker #include <cutils/sockets.h>
32*598139dcSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
33*598139dcSAndroid Build Coastguard Worker #include <private/android_logger.h>
34*598139dcSAndroid Build Coastguard Worker
35*598139dcSAndroid Build Coastguard Worker #include "LogdNativeService.h"
36*598139dcSAndroid Build Coastguard Worker #include "LogBuffer.h"
37*598139dcSAndroid Build Coastguard Worker #include "LogBufferElement.h"
38*598139dcSAndroid Build Coastguard Worker #include "LogPermissions.h"
39*598139dcSAndroid Build Coastguard Worker #include "LogReader.h"
40*598139dcSAndroid Build Coastguard Worker #include "LogUtils.h"
41*598139dcSAndroid Build Coastguard Worker #include "LogWriter.h"
42*598139dcSAndroid Build Coastguard Worker
43*598139dcSAndroid Build Coastguard Worker using android::defaultServiceManager;
44*598139dcSAndroid Build Coastguard Worker using android::ProcessState;
45*598139dcSAndroid Build Coastguard Worker using android::sp;
46*598139dcSAndroid Build Coastguard Worker using android::String16;
47*598139dcSAndroid Build Coastguard Worker
CanReadSecurityLogs(SocketClient * client)48*598139dcSAndroid Build Coastguard Worker static bool CanReadSecurityLogs(SocketClient* client) {
49*598139dcSAndroid Build Coastguard Worker return client->getUid() == AID_SYSTEM || client->getGid() == AID_SYSTEM;
50*598139dcSAndroid Build Coastguard Worker }
51*598139dcSAndroid Build Coastguard Worker
SocketClientToName(SocketClient * client)52*598139dcSAndroid Build Coastguard Worker static std::string SocketClientToName(SocketClient* client) {
53*598139dcSAndroid Build Coastguard Worker return android::base::StringPrintf("pid %d, fd %d", client->getPid(), client->getSocket());
54*598139dcSAndroid Build Coastguard Worker }
55*598139dcSAndroid Build Coastguard Worker
InitLogdBinderServiceStatus(LogReaderList * reader_list)56*598139dcSAndroid Build Coastguard Worker static bool InitLogdBinderServiceStatus(LogReaderList* reader_list) {
57*598139dcSAndroid Build Coastguard Worker sp<LogdNativeService> service = new LogdNativeService(reader_list);
58*598139dcSAndroid Build Coastguard Worker auto service_status = defaultServiceManager()->addService(String16("logd"), service);
59*598139dcSAndroid Build Coastguard Worker if (service_status != android::OK) {
60*598139dcSAndroid Build Coastguard Worker LOG(ERROR) << "Failed to add logd binder service.";
61*598139dcSAndroid Build Coastguard Worker return false;
62*598139dcSAndroid Build Coastguard Worker }
63*598139dcSAndroid Build Coastguard Worker
64*598139dcSAndroid Build Coastguard Worker sp<ProcessState> proc(ProcessState::self());
65*598139dcSAndroid Build Coastguard Worker proc->startThreadPool();
66*598139dcSAndroid Build Coastguard Worker return true;
67*598139dcSAndroid Build Coastguard Worker }
68*598139dcSAndroid Build Coastguard Worker
GetLogdBinderServiceStatus(LogReaderList * reader_list)69*598139dcSAndroid Build Coastguard Worker static bool GetLogdBinderServiceStatus(LogReaderList* reader_list) {
70*598139dcSAndroid Build Coastguard Worker static bool service_status = InitLogdBinderServiceStatus(reader_list);
71*598139dcSAndroid Build Coastguard Worker return service_status;
72*598139dcSAndroid Build Coastguard Worker }
73*598139dcSAndroid Build Coastguard Worker
74*598139dcSAndroid Build Coastguard Worker class SocketLogWriter : public LogWriter {
75*598139dcSAndroid Build Coastguard Worker public:
SocketLogWriter(LogReader * reader,SocketClient * client,bool privileged)76*598139dcSAndroid Build Coastguard Worker SocketLogWriter(LogReader* reader, SocketClient* client, bool privileged)
77*598139dcSAndroid Build Coastguard Worker : LogWriter(client->getUid(), privileged), reader_(reader), client_(client) {}
78*598139dcSAndroid Build Coastguard Worker
Write(const logger_entry & entry,const char * msg)79*598139dcSAndroid Build Coastguard Worker bool Write(const logger_entry& entry, const char* msg) override {
80*598139dcSAndroid Build Coastguard Worker struct iovec iovec[2];
81*598139dcSAndroid Build Coastguard Worker iovec[0].iov_base = const_cast<logger_entry*>(&entry);
82*598139dcSAndroid Build Coastguard Worker iovec[0].iov_len = entry.hdr_size;
83*598139dcSAndroid Build Coastguard Worker iovec[1].iov_base = const_cast<char*>(msg);
84*598139dcSAndroid Build Coastguard Worker iovec[1].iov_len = entry.len;
85*598139dcSAndroid Build Coastguard Worker
86*598139dcSAndroid Build Coastguard Worker return client_->sendDatav(iovec, 1 + (entry.len != 0)) == 0;
87*598139dcSAndroid Build Coastguard Worker }
88*598139dcSAndroid Build Coastguard Worker
Release()89*598139dcSAndroid Build Coastguard Worker void Release() override {
90*598139dcSAndroid Build Coastguard Worker reader_->release(client_);
91*598139dcSAndroid Build Coastguard Worker client_->decRef();
92*598139dcSAndroid Build Coastguard Worker }
93*598139dcSAndroid Build Coastguard Worker
Shutdown()94*598139dcSAndroid Build Coastguard Worker void Shutdown() override { shutdown(client_->getSocket(), SHUT_RDWR); }
95*598139dcSAndroid Build Coastguard Worker
name() const96*598139dcSAndroid Build Coastguard Worker std::string name() const override { return SocketClientToName(client_); }
97*598139dcSAndroid Build Coastguard Worker
98*598139dcSAndroid Build Coastguard Worker private:
99*598139dcSAndroid Build Coastguard Worker LogReader* reader_;
100*598139dcSAndroid Build Coastguard Worker SocketClient* client_;
101*598139dcSAndroid Build Coastguard Worker };
102*598139dcSAndroid Build Coastguard Worker
LogReader(LogBuffer * logbuf,LogReaderList * reader_list)103*598139dcSAndroid Build Coastguard Worker LogReader::LogReader(LogBuffer* logbuf, LogReaderList* reader_list)
104*598139dcSAndroid Build Coastguard Worker : SocketListener(getLogSocket(), true), log_buffer_(logbuf), reader_list_(reader_list) {}
105*598139dcSAndroid Build Coastguard Worker
106*598139dcSAndroid Build Coastguard Worker // Note returning false will release the SocketClient instance.
onDataAvailable(SocketClient * cli)107*598139dcSAndroid Build Coastguard Worker bool LogReader::onDataAvailable(SocketClient* cli) {
108*598139dcSAndroid Build Coastguard Worker static bool name_set;
109*598139dcSAndroid Build Coastguard Worker if (!name_set) {
110*598139dcSAndroid Build Coastguard Worker prctl(PR_SET_NAME, "logd.reader");
111*598139dcSAndroid Build Coastguard Worker name_set = true;
112*598139dcSAndroid Build Coastguard Worker }
113*598139dcSAndroid Build Coastguard Worker
114*598139dcSAndroid Build Coastguard Worker char buffer[255];
115*598139dcSAndroid Build Coastguard Worker
116*598139dcSAndroid Build Coastguard Worker int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1);
117*598139dcSAndroid Build Coastguard Worker if (len <= 0) {
118*598139dcSAndroid Build Coastguard Worker DoSocketDelete(cli);
119*598139dcSAndroid Build Coastguard Worker return false;
120*598139dcSAndroid Build Coastguard Worker }
121*598139dcSAndroid Build Coastguard Worker buffer[len] = '\0';
122*598139dcSAndroid Build Coastguard Worker
123*598139dcSAndroid Build Coastguard Worker // Clients are only allowed to send one command, disconnect them if they send another.
124*598139dcSAndroid Build Coastguard Worker if (DoSocketDelete(cli)) {
125*598139dcSAndroid Build Coastguard Worker return false;
126*598139dcSAndroid Build Coastguard Worker }
127*598139dcSAndroid Build Coastguard Worker
128*598139dcSAndroid Build Coastguard Worker unsigned long tail = 0;
129*598139dcSAndroid Build Coastguard Worker static const char _tail[] = " tail=";
130*598139dcSAndroid Build Coastguard Worker char* cp = strstr(buffer, _tail);
131*598139dcSAndroid Build Coastguard Worker if (cp) {
132*598139dcSAndroid Build Coastguard Worker tail = atol(cp + sizeof(_tail) - 1);
133*598139dcSAndroid Build Coastguard Worker }
134*598139dcSAndroid Build Coastguard Worker
135*598139dcSAndroid Build Coastguard Worker log_time start(log_time::EPOCH);
136*598139dcSAndroid Build Coastguard Worker static const char _start[] = " start=";
137*598139dcSAndroid Build Coastguard Worker cp = strstr(buffer, _start);
138*598139dcSAndroid Build Coastguard Worker if (cp) {
139*598139dcSAndroid Build Coastguard Worker // Parse errors will result in current time
140*598139dcSAndroid Build Coastguard Worker start.strptime(cp + sizeof(_start) - 1, "%s.%q");
141*598139dcSAndroid Build Coastguard Worker }
142*598139dcSAndroid Build Coastguard Worker
143*598139dcSAndroid Build Coastguard Worker std::chrono::steady_clock::time_point deadline = {};
144*598139dcSAndroid Build Coastguard Worker static const char _timeout[] = " timeout=";
145*598139dcSAndroid Build Coastguard Worker cp = strstr(buffer, _timeout);
146*598139dcSAndroid Build Coastguard Worker if (cp) {
147*598139dcSAndroid Build Coastguard Worker long timeout_seconds = atol(cp + sizeof(_timeout) - 1);
148*598139dcSAndroid Build Coastguard Worker deadline = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_seconds);
149*598139dcSAndroid Build Coastguard Worker }
150*598139dcSAndroid Build Coastguard Worker
151*598139dcSAndroid Build Coastguard Worker unsigned int logMask = -1;
152*598139dcSAndroid Build Coastguard Worker static const char _logIds[] = " lids=";
153*598139dcSAndroid Build Coastguard Worker cp = strstr(buffer, _logIds);
154*598139dcSAndroid Build Coastguard Worker if (cp) {
155*598139dcSAndroid Build Coastguard Worker logMask = 0;
156*598139dcSAndroid Build Coastguard Worker cp += sizeof(_logIds) - 1;
157*598139dcSAndroid Build Coastguard Worker while (*cp != '\0') {
158*598139dcSAndroid Build Coastguard Worker int val = 0;
159*598139dcSAndroid Build Coastguard Worker while (isdigit(*cp)) {
160*598139dcSAndroid Build Coastguard Worker val = val * 10 + *cp - '0';
161*598139dcSAndroid Build Coastguard Worker ++cp;
162*598139dcSAndroid Build Coastguard Worker }
163*598139dcSAndroid Build Coastguard Worker logMask |= 1 << val;
164*598139dcSAndroid Build Coastguard Worker if (*cp != ',') {
165*598139dcSAndroid Build Coastguard Worker break;
166*598139dcSAndroid Build Coastguard Worker }
167*598139dcSAndroid Build Coastguard Worker ++cp;
168*598139dcSAndroid Build Coastguard Worker }
169*598139dcSAndroid Build Coastguard Worker }
170*598139dcSAndroid Build Coastguard Worker
171*598139dcSAndroid Build Coastguard Worker pid_t pid = 0;
172*598139dcSAndroid Build Coastguard Worker static const char _pid[] = " pid=";
173*598139dcSAndroid Build Coastguard Worker cp = strstr(buffer, _pid);
174*598139dcSAndroid Build Coastguard Worker if (cp) {
175*598139dcSAndroid Build Coastguard Worker pid = atol(cp + sizeof(_pid) - 1);
176*598139dcSAndroid Build Coastguard Worker }
177*598139dcSAndroid Build Coastguard Worker
178*598139dcSAndroid Build Coastguard Worker bool nonBlock = false;
179*598139dcSAndroid Build Coastguard Worker if (!fastcmp<strncmp>(buffer, "dumpAndClose", 12)) {
180*598139dcSAndroid Build Coastguard Worker // Allow writer to get some cycles, and wait for pending notifications
181*598139dcSAndroid Build Coastguard Worker sched_yield();
182*598139dcSAndroid Build Coastguard Worker logd_lock.lock();
183*598139dcSAndroid Build Coastguard Worker logd_lock.unlock();
184*598139dcSAndroid Build Coastguard Worker sched_yield();
185*598139dcSAndroid Build Coastguard Worker nonBlock = true;
186*598139dcSAndroid Build Coastguard Worker }
187*598139dcSAndroid Build Coastguard Worker
188*598139dcSAndroid Build Coastguard Worker bool privileged = clientHasLogCredentials(cli);
189*598139dcSAndroid Build Coastguard Worker bool can_read_security = CanReadSecurityLogs(cli);
190*598139dcSAndroid Build Coastguard Worker if (!can_read_security) {
191*598139dcSAndroid Build Coastguard Worker logMask &= ~(1 << LOG_ID_SECURITY);
192*598139dcSAndroid Build Coastguard Worker }
193*598139dcSAndroid Build Coastguard Worker
194*598139dcSAndroid Build Coastguard Worker std::unique_ptr<LogWriter> socket_log_writer(new SocketLogWriter(this, cli, privileged));
195*598139dcSAndroid Build Coastguard Worker
196*598139dcSAndroid Build Coastguard Worker uint64_t sequence = 1;
197*598139dcSAndroid Build Coastguard Worker // Convert realtime to sequence number
198*598139dcSAndroid Build Coastguard Worker if (start != log_time::EPOCH) {
199*598139dcSAndroid Build Coastguard Worker bool start_time_set = false;
200*598139dcSAndroid Build Coastguard Worker uint64_t last = sequence;
201*598139dcSAndroid Build Coastguard Worker auto log_find_start = [pid, start, &sequence, &start_time_set, &last](
202*598139dcSAndroid Build Coastguard Worker log_id_t, pid_t element_pid, uint64_t element_sequence,
203*598139dcSAndroid Build Coastguard Worker log_time element_realtime) -> FilterResult {
204*598139dcSAndroid Build Coastguard Worker if (pid && pid != element_pid) {
205*598139dcSAndroid Build Coastguard Worker return FilterResult::kSkip;
206*598139dcSAndroid Build Coastguard Worker }
207*598139dcSAndroid Build Coastguard Worker if (start == element_realtime) {
208*598139dcSAndroid Build Coastguard Worker sequence = element_sequence;
209*598139dcSAndroid Build Coastguard Worker start_time_set = true;
210*598139dcSAndroid Build Coastguard Worker return FilterResult::kStop;
211*598139dcSAndroid Build Coastguard Worker } else {
212*598139dcSAndroid Build Coastguard Worker if (start < element_realtime) {
213*598139dcSAndroid Build Coastguard Worker sequence = last;
214*598139dcSAndroid Build Coastguard Worker start_time_set = true;
215*598139dcSAndroid Build Coastguard Worker return FilterResult::kStop;
216*598139dcSAndroid Build Coastguard Worker }
217*598139dcSAndroid Build Coastguard Worker last = element_sequence;
218*598139dcSAndroid Build Coastguard Worker }
219*598139dcSAndroid Build Coastguard Worker return FilterResult::kSkip;
220*598139dcSAndroid Build Coastguard Worker };
221*598139dcSAndroid Build Coastguard Worker auto lock = std::lock_guard{logd_lock};
222*598139dcSAndroid Build Coastguard Worker auto flush_to_state = log_buffer_->CreateFlushToState(sequence, logMask);
223*598139dcSAndroid Build Coastguard Worker log_buffer_->FlushTo(socket_log_writer.get(), *flush_to_state, log_find_start);
224*598139dcSAndroid Build Coastguard Worker
225*598139dcSAndroid Build Coastguard Worker if (!start_time_set) {
226*598139dcSAndroid Build Coastguard Worker if (nonBlock) {
227*598139dcSAndroid Build Coastguard Worker return false;
228*598139dcSAndroid Build Coastguard Worker }
229*598139dcSAndroid Build Coastguard Worker sequence = log_buffer_->sequence();
230*598139dcSAndroid Build Coastguard Worker }
231*598139dcSAndroid Build Coastguard Worker }
232*598139dcSAndroid Build Coastguard Worker
233*598139dcSAndroid Build Coastguard Worker LOG(INFO) << android::base::StringPrintf(
234*598139dcSAndroid Build Coastguard Worker "logdr: UID=%d GID=%d PID=%d %c tail=%lu logMask=%x pid=%d "
235*598139dcSAndroid Build Coastguard Worker "start=%" PRIu64 "ns deadline=%" PRIi64 "ns",
236*598139dcSAndroid Build Coastguard Worker cli->getUid(), cli->getGid(), cli->getPid(), nonBlock ? 'n' : 'b', tail, logMask,
237*598139dcSAndroid Build Coastguard Worker (int)pid, start.nsec(), static_cast<int64_t>(deadline.time_since_epoch().count()));
238*598139dcSAndroid Build Coastguard Worker
239*598139dcSAndroid Build Coastguard Worker if (start == log_time::EPOCH) {
240*598139dcSAndroid Build Coastguard Worker deadline = {};
241*598139dcSAndroid Build Coastguard Worker }
242*598139dcSAndroid Build Coastguard Worker
243*598139dcSAndroid Build Coastguard Worker auto lock = std::lock_guard{logd_lock};
244*598139dcSAndroid Build Coastguard Worker auto entry = std::make_unique<LogReaderThread>(log_buffer_, reader_list_,
245*598139dcSAndroid Build Coastguard Worker std::move(socket_log_writer), nonBlock, tail,
246*598139dcSAndroid Build Coastguard Worker logMask, pid, start, sequence, deadline);
247*598139dcSAndroid Build Coastguard Worker // release client and entry reference counts once done
248*598139dcSAndroid Build Coastguard Worker cli->incRef();
249*598139dcSAndroid Build Coastguard Worker
250*598139dcSAndroid Build Coastguard Worker entry->set_pending_reader_thread_key(cli->getUid(), cli->getGid(), cli->getPid(),
251*598139dcSAndroid Build Coastguard Worker cli->getSocket());
252*598139dcSAndroid Build Coastguard Worker
253*598139dcSAndroid Build Coastguard Worker bool only_read_event_logs = (logMask ^ (1 << LOG_ID_EVENTS)) == 0;
254*598139dcSAndroid Build Coastguard Worker
255*598139dcSAndroid Build Coastguard Worker // The logd access will be granted when any of the following three
256*598139dcSAndroid Build Coastguard Worker // conditions is satisfied:
257*598139dcSAndroid Build Coastguard Worker // 1. the client (native processes) is exempted from user consent check.
258*598139dcSAndroid Build Coastguard Worker // 2. the client doesn't have log credentials and so can only access its own log data anyway
259*598139dcSAndroid Build Coastguard Worker // 3. the client (for EventLog API) only wants to access the event log.
260*598139dcSAndroid Build Coastguard Worker if (clientIsExemptedFromUserConsent(cli) || !clientHasLogCredentials(cli) ||
261*598139dcSAndroid Build Coastguard Worker only_read_event_logs) {
262*598139dcSAndroid Build Coastguard Worker reader_list_->AddAndRunThread(std::move(entry));
263*598139dcSAndroid Build Coastguard Worker } else {
264*598139dcSAndroid Build Coastguard Worker if (GetLogdBinderServiceStatus(reader_list_)) {
265*598139dcSAndroid Build Coastguard Worker reader_list_->AddPendingThread(std::move(entry));
266*598139dcSAndroid Build Coastguard Worker } else {
267*598139dcSAndroid Build Coastguard Worker // The logd binder service is not available, we are not able to
268*598139dcSAndroid Build Coastguard Worker // check user consent. So we revoke the privileges.
269*598139dcSAndroid Build Coastguard Worker entry->Revoke();
270*598139dcSAndroid Build Coastguard Worker reader_list_->AddAndRunThread(std::move(entry));
271*598139dcSAndroid Build Coastguard Worker }
272*598139dcSAndroid Build Coastguard Worker }
273*598139dcSAndroid Build Coastguard Worker
274*598139dcSAndroid Build Coastguard Worker // Set acceptable upper limit to wait for slow reader processing b/27242723
275*598139dcSAndroid Build Coastguard Worker struct timeval t = { LOGD_SNDTIMEO, 0 };
276*598139dcSAndroid Build Coastguard Worker setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&t,
277*598139dcSAndroid Build Coastguard Worker sizeof(t));
278*598139dcSAndroid Build Coastguard Worker
279*598139dcSAndroid Build Coastguard Worker return true;
280*598139dcSAndroid Build Coastguard Worker }
281*598139dcSAndroid Build Coastguard Worker
DoSocketDelete(SocketClient * cli)282*598139dcSAndroid Build Coastguard Worker bool LogReader::DoSocketDelete(SocketClient* cli) {
283*598139dcSAndroid Build Coastguard Worker auto cli_name = SocketClientToName(cli);
284*598139dcSAndroid Build Coastguard Worker auto lock = std::lock_guard{logd_lock};
285*598139dcSAndroid Build Coastguard Worker return reader_list_->ReleaseThreadByName(cli_name);
286*598139dcSAndroid Build Coastguard Worker }
287*598139dcSAndroid Build Coastguard Worker
getLogSocket()288*598139dcSAndroid Build Coastguard Worker int LogReader::getLogSocket() {
289*598139dcSAndroid Build Coastguard Worker static const char socketName[] = "logdr";
290*598139dcSAndroid Build Coastguard Worker int sock = android_get_control_socket(socketName);
291*598139dcSAndroid Build Coastguard Worker
292*598139dcSAndroid Build Coastguard Worker if (sock < 0) {
293*598139dcSAndroid Build Coastguard Worker sock = socket_local_server(
294*598139dcSAndroid Build Coastguard Worker socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET);
295*598139dcSAndroid Build Coastguard Worker }
296*598139dcSAndroid Build Coastguard Worker
297*598139dcSAndroid Build Coastguard Worker return sock;
298*598139dcSAndroid Build Coastguard Worker }
299