OSDN Git Service

Move iptables test code to a new IptablesBaseTest class.
[android-x86/system-netd.git] / server / main.cpp
index 6af1e4e..4a5f315 100644 (file)
 #define LOG_TAG "Netd"
 
 #include "cutils/log.h"
+#include "utils/RWLock.h"
 
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "Controllers.h"
 #include "CommandListener.h"
+#include "NetdConstants.h"
+#include "NetdNativeService.h"
 #include "NetlinkManager.h"
 #include "DnsProxyListener.h"
 #include "MDnsSdListener.h"
 #include "FwmarkServer.h"
 
+using android::status_t;
+using android::sp;
+using android::IPCThreadState;
+using android::ProcessState;
+using android::defaultServiceManager;
+using android::net::NetdNativeService;
+
 static void blockSigpipe();
+static void remove_pid_file();
+static bool write_pid_file();
 
-int main() {
+const char* const PID_FILE_PATH = "/data/misc/net/netd_pid";
+const int PID_FILE_FLAGS = O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW | O_CLOEXEC;
+const mode_t PID_FILE_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;  // mode 0644, rw-r--r--
 
-    CommandListener *cl;
-    NetlinkManager *nm;
-    DnsProxyListener *dpl;
-    MDnsSdListener *mdnsl;
-    FwmarkServer* fwmarkServer;
+android::RWLock android::net::gBigNetdLock;
+
+int main() {
+    using android::net::gCtls;
 
     ALOGI("Netd 1.0 starting");
+    remove_pid_file();
 
     blockSigpipe();
 
-    if (!(nm = NetlinkManager::Instance())) {
+    NetlinkManager *nm = NetlinkManager::Instance();
+    if (nm == nullptr) {
         ALOGE("Unable to create NetlinkManager");
         exit(1);
     };
 
-    cl = new CommandListener();
-    nm->setBroadcaster((SocketListener *) cl);
+    gCtls = new android::net::Controllers();
+    CommandListener cl;
+    nm->setBroadcaster((SocketListener *) &cl);
 
     if (nm->start()) {
         ALOGE("Unable to start NetlinkManager (%s)", strerror(errno));
@@ -66,41 +87,82 @@ int main() {
     // Set local DNS mode, to prevent bionic from proxying
     // back to this service, recursively.
     setenv("ANDROID_DNS_MODE", "local", 1);
-    dpl = new DnsProxyListener(CommandListener::sNetCtrl);
-    if (dpl->startListener()) {
+    DnsProxyListener dpl(&gCtls->netCtrl);
+    if (dpl.startListener()) {
         ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));
         exit(1);
     }
 
-    mdnsl = new MDnsSdListener();
-    if (mdnsl->startListener()) {
+    MDnsSdListener mdnsl;
+    if (mdnsl.startListener()) {
         ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno));
         exit(1);
     }
 
-    fwmarkServer = new FwmarkServer(CommandListener::sNetCtrl);
-    if (fwmarkServer->startListener()) {
+    FwmarkServer fwmarkServer(&gCtls->netCtrl);
+    if (fwmarkServer.startListener()) {
         ALOGE("Unable to start FwmarkServer (%s)", strerror(errno));
         exit(1);
     }
 
+    status_t ret;
+    if ((ret = NetdNativeService::start()) != android::OK) {
+        ALOGE("Unable to start NetdNativeService: %d", ret);
+        exit(1);
+    }
+
     /*
-     * Now that we're up, we can respond to commands
+     * 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()) {
+    if (cl.startListener()) {
         ALOGE("Unable to start CommandListener (%s)", strerror(errno));
         exit(1);
     }
 
-    // Eventually we'll become the monitoring thread
-    while(1) {
-        sleep(1000);
-    }
+    write_pid_file();
+
+    IPCThreadState::self()->joinThreadPool();
 
     ALOGI("Netd exiting");
+
+    remove_pid_file();
+
     exit(0);
 }
 
+static bool write_pid_file() {
+    char pid_buf[INT32_STRLEN];
+    snprintf(pid_buf, sizeof(pid_buf), "%d\n", (int) getpid());
+
+    int fd = open(PID_FILE_PATH, PID_FILE_FLAGS, PID_FILE_MODE);
+    if (fd == -1) {
+        ALOGE("Unable to create pid file (%s)", strerror(errno));
+        return false;
+    }
+
+    // File creation is affected by umask, so make sure the right mode bits are set.
+    if (fchmod(fd, PID_FILE_MODE) == -1) {
+        ALOGE("failed to set mode 0%o on %s (%s)", PID_FILE_MODE, PID_FILE_PATH, strerror(errno));
+        close(fd);
+        remove_pid_file();
+        return false;
+    }
+
+    if (write(fd, pid_buf, strlen(pid_buf)) != (ssize_t)strlen(pid_buf)) {
+        ALOGE("Unable to write to pid file (%s)", strerror(errno));
+        close(fd);
+        remove_pid_file();
+        return false;
+    }
+    close(fd);
+    return true;
+}
+
+static void remove_pid_file() {
+    unlink(PID_FILE_PATH);
+}
+
 static void blockSigpipe()
 {
     sigset_t mask;