1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <signal.h> 20 #include <errno.h> 21 #include <string.h> 22 #include <sys/stat.h> 23 #include <sys/types.h> 24 #include <sys/wait.h> 25 26 #include <fcntl.h> 27 #include <dirent.h> 28 29 #define LOG_TAG "Netd" 30 31 #include "cutils/log.h" 32 #include "utils/RWLock.h" 33 34 #include <binder/IPCThreadState.h> 35 #include <binder/IServiceManager.h> 36 #include <binder/ProcessState.h> 37 38 #include "Controllers.h" 39 #include "CommandListener.h" 40 #include "NetdConstants.h" 41 #include "NetdNativeService.h" 42 #include "NetlinkManager.h" 43 #include "Stopwatch.h" 44 #include "DnsProxyListener.h" 45 #include "MDnsSdListener.h" 46 #include "FwmarkServer.h" 47 48 using android::status_t; 49 using android::sp; 50 using android::IPCThreadState; 51 using android::ProcessState; 52 using android::defaultServiceManager; 53 using android::net::CommandListener; 54 using android::net::DnsProxyListener; 55 using android::net::FwmarkServer; 56 using android::net::NetdNativeService; 57 using android::net::NetlinkManager; 58 59 static void remove_pid_file(); 60 static bool write_pid_file(); 61 62 const char* const PID_FILE_PATH = "/data/misc/net/netd_pid"; 63 const int PID_FILE_FLAGS = O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW | O_CLOEXEC; 64 const mode_t PID_FILE_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // mode 0644, rw-r--r-- 65 66 android::RWLock android::net::gBigNetdLock; 67 68 int main() { 69 using android::net::gCtls; 70 Stopwatch s; 71 72 ALOGI("Netd 1.0 starting"); 73 remove_pid_file(); 74 75 blockSigpipe(); 76 77 NetlinkManager *nm = NetlinkManager::Instance(); 78 if (nm == nullptr) { 79 ALOGE("Unable to create NetlinkManager"); 80 exit(1); 81 }; 82 83 gCtls = new android::net::Controllers(); 84 gCtls->init(); 85 86 CommandListener cl; 87 nm->setBroadcaster((SocketListener *) &cl); 88 89 if (nm->start()) { 90 ALOGE("Unable to start NetlinkManager (%s)", strerror(errno)); 91 exit(1); 92 } 93 94 // Set local DNS mode, to prevent bionic from proxying 95 // back to this service, recursively. 96 setenv("ANDROID_DNS_MODE", "local", 1); 97 DnsProxyListener dpl(&gCtls->netCtrl, &gCtls->eventReporter); 98 if (dpl.startListener()) { 99 ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno)); 100 exit(1); 101 } 102 103 MDnsSdListener mdnsl; 104 if (mdnsl.startListener()) { 105 ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno)); 106 exit(1); 107 } 108 109 FwmarkServer fwmarkServer(&gCtls->netCtrl, &gCtls->eventReporter); 110 if (fwmarkServer.startListener()) { 111 ALOGE("Unable to start FwmarkServer (%s)", strerror(errno)); 112 exit(1); 113 } 114 115 Stopwatch subTime; 116 status_t ret; 117 if ((ret = NetdNativeService::start()) != android::OK) { 118 ALOGE("Unable to start NetdNativeService: %d", ret); 119 exit(1); 120 } 121 ALOGI("Registering NetdNativeService: %.1fms", subTime.getTimeAndReset()); 122 123 /* 124 * Now that we're up, we can respond to commands. Starting the listener also tells 125 * NetworkManagementService that we are up and that our binder interface is ready. 126 */ 127 if (cl.startListener()) { 128 ALOGE("Unable to start CommandListener (%s)", strerror(errno)); 129 exit(1); 130 } 131 ALOGI("Starting CommandListener: %.1fms", subTime.getTimeAndReset()); 132 133 write_pid_file(); 134 135 ALOGI("Netd started in %dms", static_cast<int>(s.timeTaken())); 136 137 IPCThreadState::self()->joinThreadPool(); 138 139 ALOGI("Netd exiting"); 140 141 remove_pid_file(); 142 143 exit(0); 144 } 145 146 static bool write_pid_file() { 147 char pid_buf[INT32_STRLEN]; 148 snprintf(pid_buf, sizeof(pid_buf), "%d\n", (int) getpid()); 149 150 int fd = open(PID_FILE_PATH, PID_FILE_FLAGS, PID_FILE_MODE); 151 if (fd == -1) { 152 ALOGE("Unable to create pid file (%s)", strerror(errno)); 153 return false; 154 } 155 156 // File creation is affected by umask, so make sure the right mode bits are set. 157 if (fchmod(fd, PID_FILE_MODE) == -1) { 158 ALOGE("failed to set mode 0%o on %s (%s)", PID_FILE_MODE, PID_FILE_PATH, strerror(errno)); 159 close(fd); 160 remove_pid_file(); 161 return false; 162 } 163 164 if (write(fd, pid_buf, strlen(pid_buf)) != (ssize_t)strlen(pid_buf)) { 165 ALOGE("Unable to write to pid file (%s)", strerror(errno)); 166 close(fd); 167 remove_pid_file(); 168 return false; 169 } 170 close(fd); 171 return true; 172 } 173 174 static void remove_pid_file() { 175 unlink(PID_FILE_PATH); 176 } 177