1ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran/*
2ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * Copyright (C) 2014 The Android Open Source Project
3ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran *
4ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * Licensed under the Apache License, Version 2.0 (the "License");
5ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * you may not use this file except in compliance with the License.
6ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * You may obtain a copy of the License at
7ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran *
8ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran *      http://www.apache.org/licenses/LICENSE-2.0
9ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran *
10ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * Unless required by applicable law or agreed to in writing, software
11ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * distributed under the License is distributed on an "AS IS" BASIS,
12ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * See the License for the specific language governing permissions and
14ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * limitations under the License.
15ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran */
16ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran
178205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran#ifdef LIBC_STATIC
188205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran#error NetdClient.cpp should NOT be included in static libc builds.
198205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran#endif
208205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran
217a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris#include <async_safe/log.h>
227a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris
2372c53933f852be6d1cd6c09c86176fbc6d609dacSreeram Ramachandran#include "private/NetdClientDispatch.h"
24ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran
25ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran#include <dlfcn.h>
2672c53933f852be6d1cd6c09c86176fbc6d609dacSreeram Ramachandran#include <pthread.h>
27ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran
28ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandrantemplate <typename FunctionType>
29ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranstatic void netdClientInitFunction(void* handle, const char* symbol, FunctionType* function) {
30ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    typedef void (*InitFunctionType)(FunctionType*);
31ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    InitFunctionType initFunction = reinterpret_cast<InitFunctionType>(dlsym(handle, symbol));
32ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    if (initFunction != NULL) {
33ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran        initFunction(function);
34ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    }
35ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran}
36ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran
37ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranstatic void netdClientInitImpl() {
3884c10c2e7928cf2128f2495b9d5ed916088b2f2bDmitriy Ivanov    void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
39ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    if (netdClientHandle == NULL) {
40ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran        // If the library is not available, it's not an error. We'll just use
41ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran        // default implementations of functions that it would've overridden.
42ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran        return;
43ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    }
44903b78873a744d3fba187e4bd22008ba21162e51Sreeram Ramachandran    netdClientInitFunction(netdClientHandle, "netdClientInitAccept4",
45903b78873a744d3fba187e4bd22008ba21162e51Sreeram Ramachandran                           &__netdClientDispatch.accept4);
46ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    netdClientInitFunction(netdClientHandle, "netdClientInitConnect",
47ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran                           &__netdClientDispatch.connect);
485240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen    netdClientInitFunction(netdClientHandle, "netdClientInitNetIdForResolv",
495240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen                           &__netdClientDispatch.netIdForResolv);
50903b78873a744d3fba187e4bd22008ba21162e51Sreeram Ramachandran    netdClientInitFunction(netdClientHandle, "netdClientInitSocket", &__netdClientDispatch.socket);
51ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran}
52ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran
53ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranstatic pthread_once_t netdClientInitOnce = PTHREAD_ONCE_INIT;
54ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran
55ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranextern "C" __LIBC_HIDDEN__ void netdClientInit() {
56ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    if (pthread_once(&netdClientInitOnce, netdClientInitImpl)) {
577a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris        async_safe_format_log(ANDROID_LOG_ERROR, "netdClient", "Failed to initialize netd_client");
58ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran    }
59ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran}
60