ClatdController.cpp revision 45d3dd0ad99d566ea589d9d5d37102ef35ca8fb2
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#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" 25#include "Fwmark.h" 26#include "NetdConstants.h" 27#include "NetworkController.h" 28 29ClatdController::ClatdController(NetworkController* controller) 30 : mNetCtrl(controller), mClatdPid(0) { 31} 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) { 53 // 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 62 char *args[] = { 63 (char *) "/system/bin/clatd", 64 (char *) "-i", 65 interface, 66 (char *) "-n", 67 netIdString, 68 (char *) "-m", 69 fwmarkString, 70 NULL 71 }; 72 73 if (execv(args[0], args)) { 74 ALOGE("execv failed (%s)", strerror(errno)); 75 } 76 ALOGE("Should never get here!"); 77 _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} 114