blob: b91b69aab2de28102147ee294a6c19c76ae3c37b [file] [log] [blame]
Daniel Drown0da73fc2012-06-20 16:51:39 -05001/*
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#include <unistd.h>
17#include <errno.h>
18#include <sys/types.h>
19#include <sys/wait.h>
20
21#define LOG_TAG "ClatdController"
22#include <cutils/log.h>
23
24#include "ClatdController.h"
Lorenzo Colitti45d3dd02014-06-09 14:09:20 +090025#include "Fwmark.h"
Paul Jensen84c1d032014-05-30 13:29:41 -040026#include "NetdConstants.h"
27#include "NetworkController.h"
Daniel Drown0da73fc2012-06-20 16:51:39 -050028
Paul Jensen84c1d032014-05-30 13:29:41 -040029ClatdController::ClatdController(NetworkController* controller)
30 : mNetCtrl(controller), mClatdPid(0) {
Daniel Drown0da73fc2012-06-20 16:51:39 -050031}
32
33ClatdController::~ClatdController() {
34}
35
36int ClatdController::startClatd(char *interface) {
37 pid_t pid;
38
39 if(mClatdPid != 0) {
40 ALOGE("clatd already running");
41 errno = EBUSY;
42 return -1;
43 }
44
45 ALOGD("starting clatd");
46
47 if ((pid = fork()) < 0) {
48 ALOGE("fork failed (%s)", strerror(errno));
49 return -1;
50 }
51
52 if (!pid) {
Lorenzo Colitti45d3dd02014-06-09 14:09:20 +090053 // Pass in the interface, a netid to use for DNS lookups, and a fwmark for outgoing packets.
54 unsigned netId = mNetCtrl->getNetworkId(interface);
55 char netIdString[UINT32_STRLEN];
56 snprintf(netIdString, sizeof(netIdString), "%u", netId);
57
58 Fwmark fwmark = { netId, true, true, PERMISSION_CONNECTIVITY_INTERNAL };
59 char fwmarkString[UINT32_HEX_STRLEN];
60 snprintf(fwmarkString, sizeof(fwmarkString), "0x%x", fwmark.intValue);
61
Paul Jensen84c1d032014-05-30 13:29:41 -040062 char *args[] = {
Lorenzo Colitti45d3dd02014-06-09 14:09:20 +090063 (char *) "/system/bin/clatd",
64 (char *) "-i",
Paul Jensen84c1d032014-05-30 13:29:41 -040065 interface,
Lorenzo Colitti45d3dd02014-06-09 14:09:20 +090066 (char *) "-n",
67 netIdString,
68 (char *) "-m",
69 fwmarkString,
Paul Jensen84c1d032014-05-30 13:29:41 -040070 NULL
71 };
Daniel Drown0da73fc2012-06-20 16:51:39 -050072
73 if (execv(args[0], args)) {
74 ALOGE("execv failed (%s)", strerror(errno));
75 }
76 ALOGE("Should never get here!");
Daniel Drown0da73fc2012-06-20 16:51:39 -050077 _exit(0);
78 } else {
79 mClatdPid = pid;
80 ALOGD("clatd started");
81 }
82
83 return 0;
84}
85
86int ClatdController::stopClatd() {
87 if (mClatdPid == 0) {
88 ALOGE("clatd already stopped");
89 return -1;
90 }
91
92 ALOGD("Stopping clatd");
93
94 kill(mClatdPid, SIGTERM);
95 waitpid(mClatdPid, NULL, 0);
96 mClatdPid = 0;
97
98 ALOGD("clatd stopped");
99
100 return 0;
101}
102
103bool ClatdController::isClatdStarted() {
104 pid_t waitpid_status;
105 if(mClatdPid == 0) {
106 return false;
107 }
108 waitpid_status = waitpid(mClatdPid, NULL, WNOHANG);
109 if(waitpid_status != 0) {
110 mClatdPid = 0; // child exited, don't call waitpid on it again
111 }
112 return waitpid_status == 0; // 0 while child is running
113}