if (nm->start()) { ALOGE("Unable to start NetlinkManager (%s)", strerror(errno)); exit(1); }
std::unique_ptr<NFLogListener> logListener; { auto result = makeNFLogListener(); if (!isOk(result)) { ALOGE("Unable to create NFLogListener: %s", toString(result).c_str()); exit(1); } logListener = std::move(result.value()); auto status = gCtls->wakeupCtrl.init(logListener.get()); if (!isOk(result)) { ALOGE("Unable to init WakeupController: %s", toString(result).c_str()); // We can still continue without wakeup packet logging. } }
// Set local DNS mode, to prevent bionic from proxying // back to this service, recursively. setenv("ANDROID_DNS_MODE", "local", 1); DnsProxyListener dpl(&gCtls->netCtrl, &gCtls->eventReporter); if (dpl.startListener()) { ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno)); exit(1); }
MDnsSdListener mdnsl; if (mdnsl.startListener()) { ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno)); exit(1); }
FwmarkServer fwmarkServer(&gCtls->netCtrl, &gCtls->eventReporter); if (fwmarkServer.startListener()) { ALOGE("Unable to start FwmarkServer (%s)", strerror(errno)); exit(1); }
/* * Now that we're up, we can respond to commands. Starting the listener also tells * NetworkManagementService that we are up and that our binder interface is ready. */ if (cl.startListener()) { ALOGE("Unable to start CommandListener (%s)", strerror(errno)); exit(1); } ALOGI("Starting CommandListener: %.1fms", subTime.getTimeAndReset());
write_pid_file();
// Now that netd is ready to process commands, advertise service // availability for HAL clients. NetdHwService mHwSvc; if ((ret = mHwSvc.start()) != android::OK) { ALOGE("Unable to start NetdHwService: %d", ret); exit(1); } ALOGI("Registering NetdHwService: %.1fms", subTime.getTimeAndReset());
ALOGI("Netd started in %dms", static_cast<int>(s.timeTaken()));
while(1) { SocketClientCollection::iterator it; fd_set read_fds; int rc = 0; int max = -1;
FD_ZERO(&read_fds);
if (mListen) { max = mSock; FD_SET(mSock, &read_fds); }
FD_SET(mCtrlPipe[0], &read_fds); if (mCtrlPipe[0] > max) max = mCtrlPipe[0];
pthread_mutex_lock(&mClientsLock); for (it = mClients->begin(); it != mClients->end(); ++it) { // NB: calling out to an other object with mClientsLock held (safe) int fd = (*it)->getSocket(); FD_SET(fd, &read_fds); if (fd > max) { max = fd; } } pthread_mutex_unlock(&mClientsLock); SLOGV("mListen=%d, max=%d, mSocketName=%s", mListen, max, mSocketName); if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) { if (errno == EINTR) continue; SLOGE("select failed (%s) mListen=%d, max=%d", strerror(errno), mListen, max); sleep(1); continue; } elseif (!rc) continue;
if (FD_ISSET(mCtrlPipe[0], &read_fds)) { char c = CtrlPipe_Shutdown; TEMP_FAILURE_RETRY(read(mCtrlPipe[0], &c, 1)); if (c == CtrlPipe_Shutdown) { break; } continue; } if (mListen && FD_ISSET(mSock, &read_fds)) { int c = TEMP_FAILURE_RETRY(accept4(mSock, nullptr, nullptr, SOCK_CLOEXEC)); if (c < 0) { SLOGE("accept failed (%s)", strerror(errno)); sleep(1); continue; } pthread_mutex_lock(&mClientsLock); mClients->push_back(newSocketClient(c, true, mUseCmdNum)); pthread_mutex_unlock(&mClientsLock); }
/* Add all active clients to the pending list first */ pendingList.clear(); pthread_mutex_lock(&mClientsLock); for (it = mClients->begin(); it != mClients->end(); ++it) { SocketClient* c = *it; // NB: calling out to an other object with mClientsLock held (safe) int fd = c->getSocket(); if (FD_ISSET(fd, &read_fds)) { pendingList.push_back(c); c->incRef(); } } pthread_mutex_unlock(&mClientsLock);
/* Process the pending list, since it is owned by the thread, * there is no need to lock it */ while (!pendingList.empty()) { /* Pop the first item from the list */ it = pendingList.begin(); SocketClient* c = *it; pendingList.erase(it); /* Process it, if false is returned, remove from list */ if (!onDataAvailable(c)) { release(c, false); } c->decRef(); } } }
// make sure this is on the same looper as our NativeDaemonConnector for sync purposes mFgHandler = newHandler(FgThread.get().getLooper());
// Don't need this wake lock, since we now have a time stamp for when // the network actually went inactive. (It might be nice to still do this, // but I don't want to do it through the power manager because that pollutes the // battery stats history with pointless noise.) //PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLockwl=null; //pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NETD_TAG);
FileDescriptor[] fdList = null; byte[] buffer = new byte[BUFFER_SIZE]; int start = 0;
while (true) { int count = inputStream.read(buffer, start, BUFFER_SIZE - start); if (count < 0) { loge("got " + count + " reading with start = " + start); break; } fdList = socket.getAncillaryFileDescriptors();
// Add our starting point to the count and reset the start. count += start; start = 0;
for (int i = 0; i < count; i++) { if (buffer[i] == 0) { // Note - do not log this raw message since it may contain // sensitive data final String rawEvent = new String( buffer, start, i - start, StandardCharsets.UTF_8);
if (errorRate && (++mCommandCount % errorRate == 0)) { /* ignore this command - let the timeout handler handle it */ SLOGE("Faking a timeout"); goto out; }
for (i = mCommands->begin(); i != mCommands->end(); ++i) { FrameworkCommand *c = *i;
if (!strcmp(argv[0], c->getCommand())) { if (c->runCommand(cli, argc, argv)) { SLOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno)); } goto out; } } cli->sendMsg(500, "Command not recognized", false); out: int j; for (j = 0; j < argc; j++) free(argv[j]); return;
overflow: cli->sendMsg(500, "Command too long", false); goto out; }
if ((mQuotaHandler = setupSocket(&mQuotaSock, NETLINK_NFLOG, NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY, false)) == NULL) { ALOGW("Unable to open qlog quota socket, check if xt_quota2 can send via UeventHandler"); // TODO: return -1 once the emulator gets a new kernel. }
if ((mStrictHandler = setupSocket(&mStrictSock, NETLINK_NETFILTER, 0, NetlinkListener::NETLINK_FORMAT_BINARY_UNICAST, true)) == NULL) { ALOGE("Unable to open strict socket"); // TODO: return -1 once the emulator gets a new kernel. }