summaryrefslogtreecommitdiffstats
path: root/libc/bionic
diff options
context:
space:
mode:
authorSreeram Ramachandran <sreeram@google.com>2014-05-12 11:19:16 -0700
committerSreeram Ramachandran <sreeram@google.com>2014-05-13 11:30:03 -0700
commitceb5bd787c8ce281e5f4343c5d4f77b41c3e2919 (patch)
tree4b91184c22597e1757ba036d30e09f5c5e586a74 /libc/bionic
parent0ccef7ec5294b34902e07c26db55891d3eddb2be (diff)
downloadbionic-ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919.zip
bionic-ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919.tar.gz
bionic-ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919.tar.bz2
Introduce netd_client, a dynamic library that talks to netd.
The library exists outside bionic. It is dynamically loaded, to replace selected standard socket syscalls with versions that talk to netd. Change connect() to use the library if available. (cherry picked from commit 3a6b627a14df8111b03e452f2df4b5f4938e0e49) Change-Id: Ib6198e19dbc306521a26fcecfdf6e8424d163fc9
Diffstat (limited to 'libc/bionic')
-rw-r--r--libc/bionic/NetdClient.cpp68
-rw-r--r--libc/bionic/connect.cpp22
-rw-r--r--libc/bionic/libc_init_dynamic.cpp4
3 files changed, 94 insertions, 0 deletions
diff --git a/libc/bionic/NetdClient.cpp b/libc/bionic/NetdClient.cpp
new file mode 100644
index 0000000..56d8244
--- /dev/null
+++ b/libc/bionic/NetdClient.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <private/NetdClient.h>
+#include <private/libc_logging.h>
+#include <pthread.h>
+
+#ifdef __i386__
+#define __socketcall __attribute__((__cdecl__))
+#else
+#define __socketcall
+#endif
+
+extern "C" __socketcall int __connect(int, const sockaddr*, socklen_t);
+
+NetdClientDispatch __netdClientDispatch __attribute__((aligned(32))) = {
+ __connect
+};
+
+#ifndef LIBC_STATIC
+
+#include <dlfcn.h>
+
+template <typename FunctionType>
+static void netdClientInitFunction(void* handle, const char* symbol, FunctionType* function) {
+ typedef void (*InitFunctionType)(FunctionType*);
+ InitFunctionType initFunction = reinterpret_cast<InitFunctionType>(dlsym(handle, symbol));
+ if (initFunction != NULL) {
+ initFunction(function);
+ }
+}
+
+static void netdClientInitImpl() {
+ void* netdClientHandle = dlopen("libnetd_client.so", RTLD_LAZY);
+ if (netdClientHandle == NULL) {
+ // If the library is not available, it's not an error. We'll just use
+ // default implementations of functions that it would've overridden.
+ return;
+ }
+ netdClientInitFunction(netdClientHandle, "netdClientInitConnect",
+ &__netdClientDispatch.connect);
+}
+
+static pthread_once_t netdClientInitOnce = PTHREAD_ONCE_INIT;
+
+#endif // LIBC_STATIC
+
+extern "C" __LIBC_HIDDEN__ void netdClientInit() {
+#ifndef LIBC_STATIC
+ if (pthread_once(&netdClientInitOnce, netdClientInitImpl)) {
+ __libc_format_log(ANDROID_LOG_ERROR, "netdClient",
+ "Unable to initialize netd_client component.");
+ }
+#endif // LIBC_STATIC
+}
diff --git a/libc/bionic/connect.cpp b/libc/bionic/connect.cpp
new file mode 100644
index 0000000..c5db46b
--- /dev/null
+++ b/libc/bionic/connect.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <private/NetdClient.h>
+#include <sys/socket.h>
+
+int connect(int sockfd, const sockaddr* addr, socklen_t addrlen) {
+ return __netdClientDispatch.connect(sockfd, addr, addrlen);
+}
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 61fb887..3d98861 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -58,6 +58,7 @@ extern "C" {
extern void pthread_debug_init(void);
extern void malloc_debug_init(void);
extern void malloc_debug_fini(void);
+ extern void netdClientInit(void);
};
// We flag the __libc_preinit function as a constructor to ensure
@@ -79,6 +80,9 @@ __attribute__((constructor)) static void __libc_preinit() {
// Hooks for the debug malloc and pthread libraries to let them know that we're starting up.
pthread_debug_init();
malloc_debug_init();
+
+ // Hook for the netd client library to let it know that we're starting up.
+ netdClientInit();
}
__LIBC_HIDDEN__ void __libc_postfini() {