• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
main()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 
write_pid_file()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 
remove_pid_file()174 static void remove_pid_file() {
175     unlink(PID_FILE_PATH);
176 }
177