summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorSreeram Ramachandran <sreeram@google.com>2014-05-21 11:41:39 -0700
committerSreeram Ramachandran <sreeram@google.com>2014-05-21 11:42:08 -0700
commitefbe05d203f2f1cc3c24ddc111be159a1ff1f292 (patch)
treeecc6cfe21ac58d7a9aa2fbbb4b5a4f241e11d8c8 /client
parentf4cfad361175a7f9ccf4d41e76a9b289c3c3da22 (diff)
downloadandroid_system_netd-efbe05d203f2f1cc3c24ddc111be159a1ff1f292.tar.gz
android_system_netd-efbe05d203f2f1cc3c24ddc111be159a1ff1f292.tar.bz2
android_system_netd-efbe05d203f2f1cc3c24ddc111be159a1ff1f292.zip
New network selection APIs.
Continued from: https://android-review.git.corp.google.com/#/c/94977/ Change-Id: Ie0576888f50a8ce91bbb0a4794708b406eb0aa35
Diffstat (limited to 'client')
-rw-r--r--client/Android.mk2
-rw-r--r--client/NetdClient.cpp76
2 files changed, 73 insertions, 5 deletions
diff --git a/client/Android.mk b/client/Android.mk
index 2a4878c4..0332deaf 100644
--- a/client/Android.mk
+++ b/client/Android.mk
@@ -16,7 +16,7 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := system/netd/include
+LOCAL_C_INCLUDES := bionic/libc/dns/include system/netd/include
LOCAL_MODULE := libnetd_client
LOCAL_SRC_FILES := FwmarkClient.cpp NetdClient.cpp
diff --git a/client/NetdClient.cpp b/client/NetdClient.cpp
index 2e8390c8..31c2e4d2 100644
--- a/client/NetdClient.cpp
+++ b/client/NetdClient.cpp
@@ -14,8 +14,11 @@
* limitations under the License.
*/
+#include "NetdClient.h"
+
#include "FwmarkClient.h"
#include "FwmarkCommand.h"
+#include "resolv_netid.h"
#include <sys/socket.h>
#include <unistd.h>
@@ -31,14 +34,17 @@ int closeFdAndRestoreErrno(int fd) {
typedef int (*ConnectFunctionType)(int, const sockaddr*, socklen_t);
typedef int (*AcceptFunctionType)(int, sockaddr*, socklen_t*);
+typedef unsigned (*NetIdForResolvFunctionType)(unsigned);
+// These variables are only modified at startup (when libc.so is loaded) and never afterwards, so
+// it's okay that they are read later at runtime without a lock.
ConnectFunctionType libcConnect = 0;
AcceptFunctionType libcAccept = 0;
int netdClientConnect(int sockfd, const sockaddr* addr, socklen_t addrlen) {
if (FwmarkClient::shouldSetFwmark(sockfd, addr)) {
- char data[] = {FWMARK_COMMAND_ON_CONNECT};
- if (!FwmarkClient().send(data, sizeof(data), sockfd)) {
+ FwmarkCommand command = {FwmarkCommand::ON_CONNECT, 0};
+ if (!FwmarkClient().send(&command, sizeof(command), sockfd)) {
return -1;
}
}
@@ -59,14 +65,49 @@ int netdClientAccept(int sockfd, sockaddr* addr, socklen_t* addrlen) {
addr = &socketAddress;
}
if (FwmarkClient::shouldSetFwmark(acceptedSocket, addr)) {
- char data[] = {FWMARK_COMMAND_ON_ACCEPT};
- if (!FwmarkClient().send(data, sizeof(data), acceptedSocket)) {
+ FwmarkCommand command = {FwmarkCommand::ON_ACCEPT, 0};
+ if (!FwmarkClient().send(&command, sizeof(command), acceptedSocket)) {
return closeFdAndRestoreErrno(acceptedSocket);
}
}
return acceptedSocket;
}
+// TODO: Convert to C++11 std::atomic<unsigned>.
+volatile sig_atomic_t netIdForProcess = NETID_UNSET;
+volatile sig_atomic_t netIdForResolv = NETID_UNSET;
+
+unsigned getNetworkForResolv(unsigned netId) {
+ if (netId != NETID_UNSET) {
+ return netId;
+ }
+ netId = netIdForProcess;
+ if (netId != NETID_UNSET) {
+ return netId;
+ }
+ return netIdForResolv;
+}
+
+bool setNetworkForTarget(unsigned netId, volatile sig_atomic_t* target) {
+ if (netId == NETID_UNSET) {
+ *target = netId;
+ return true;
+ }
+ // Verify that we are allowed to use |netId|, by creating a socket and trying to have it marked
+ // with the netId. Don't create an AF_INET socket, because then the creation itself might cause
+ // another check with the fwmark server (see netdClientSocket()), which would be wasteful.
+ int socketFd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (socketFd < 0) {
+ return false;
+ }
+ bool status = setNetworkForSocket(netId, socketFd);
+ closeFdAndRestoreErrno(socketFd);
+ if (status) {
+ *target = netId;
+ }
+ return status;
+}
+
} // namespace
extern "C" void netdClientInitConnect(ConnectFunctionType* function) {
@@ -82,3 +123,30 @@ extern "C" void netdClientInitAccept(AcceptFunctionType* function) {
*function = netdClientAccept;
}
}
+
+extern "C" void netdClientInitNetIdForResolv(NetIdForResolvFunctionType* function) {
+ if (function) {
+ *function = getNetworkForResolv;
+ }
+}
+
+extern "C" unsigned getNetworkForProcess() {
+ return netIdForProcess;
+}
+
+extern "C" bool setNetworkForSocket(unsigned netId, int socketFd) {
+ if (socketFd < 0) {
+ errno = EBADF;
+ return false;
+ }
+ FwmarkCommand command = {FwmarkCommand::SELECT_NETWORK, netId};
+ return FwmarkClient().send(&command, sizeof(command), socketFd);
+}
+
+extern "C" bool setNetworkForProcess(unsigned netId) {
+ return setNetworkForTarget(netId, &netIdForProcess);
+}
+
+extern "C" bool setNetworkForResolv(unsigned netId) {
+ return setNetworkForTarget(netId, &netIdForResolv);
+}