summaryrefslogtreecommitdiff
path: root/src/lib/ares_android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ares_android.c')
-rw-r--r--src/lib/ares_android.c360
1 files changed, 199 insertions, 161 deletions
diff --git a/src/lib/ares_android.c b/src/lib/ares_android.c
index 5b00b80..778d4d1 100644
--- a/src/lib/ares_android.c
+++ b/src/lib/ares_android.c
@@ -1,28 +1,39 @@
-/* Copyright (C) 2017 by John Schember <john@nachtimwald.com>
+/* MIT License
*
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
+ * Copyright (c) John Schember
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * SPDX-License-Identifier: MIT
*/
#if defined(ANDROID) || defined(__ANDROID__)
-#include <jni.h>
+# include <jni.h>
-#include "ares_setup.h"
-#include "ares.h"
-#include "ares_android.h"
-#include "ares_private.h"
+# include "ares_setup.h"
+# include "ares.h"
+# include "ares_android.h"
+# include "ares_private.h"
-static JavaVM *android_jvm = NULL;
-static jobject android_connectivity_manager = NULL;
+static JavaVM *android_jvm = NULL;
+static jobject android_connectivity_manager = NULL;
/* ConnectivityManager.getActiveNetwork */
static jmethodID android_cm_active_net_mid = NULL;
@@ -39,12 +50,13 @@ static jmethodID android_list_get_mid = NULL;
/* InetAddress.getHostAddress */
static jmethodID android_ia_host_addr_mid = NULL;
-static jclass jni_get_class(JNIEnv *env, const char *path)
+static jclass jni_get_class(JNIEnv *env, const char *path)
{
jclass cls = NULL;
- if (env == NULL || path == NULL || *path == '\0')
+ if (env == NULL || path == NULL || *path == '\0') {
return NULL;
+ }
cls = (*env)->FindClass(env, path);
if ((*env)->ExceptionOccurred(env)) {
@@ -60,14 +72,12 @@ static jmethodID jni_get_method_id(JNIEnv *env, jclass cls,
jmethodID mid = NULL;
if (env == NULL || cls == NULL || func_name == NULL || *func_name == '\0' ||
- signature == NULL || *signature == '\0')
- {
+ signature == NULL || *signature == '\0') {
return NULL;
}
mid = (*env)->GetMethodID(env, cls, func_name, signature);
- if ((*env)->ExceptionOccurred(env))
- {
+ if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionClear(env);
return NULL;
}
@@ -82,29 +92,31 @@ void ares_library_init_jvm(JavaVM *jvm)
int ares_library_init_android(jobject connectivity_manager)
{
- JNIEnv *env = NULL;
- int need_detatch = 0;
- int res;
- int ret = ARES_ENOTINITIALIZED;
- jclass obj_cls = NULL;
+ JNIEnv *env = NULL;
+ int need_detatch = 0;
+ int res;
+ ares_status_t ret = ARES_ENOTINITIALIZED;
+ jclass obj_cls = NULL;
- if (android_jvm == NULL)
+ if (android_jvm == NULL) {
goto cleanup;
+ }
res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6);
- if (res == JNI_EDETACHED)
- {
- env = NULL;
- res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
+ if (res == JNI_EDETACHED) {
+ env = NULL;
+ res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
need_detatch = 1;
}
- if (res != JNI_OK || env == NULL)
+ if (res != JNI_OK || env == NULL) {
goto cleanup;
+ }
android_connectivity_manager =
- (*env)->NewGlobalRef(env, connectivity_manager);
- if (android_connectivity_manager == NULL)
+ (*env)->NewGlobalRef(env, connectivity_manager);
+ if (android_connectivity_manager == NULL) {
goto cleanup;
+ }
/* Initialization has succeeded. Now attempt to cache the methods that will be
* called by ares_get_android_server_list. */
@@ -112,166 +124,178 @@ int ares_library_init_android(jobject connectivity_manager)
/* ConnectivityManager in API 1. */
obj_cls = jni_get_class(env, "android/net/ConnectivityManager");
- if (obj_cls == NULL)
+ if (obj_cls == NULL) {
goto cleanup;
+ }
/* ConnectivityManager.getActiveNetwork in API 23. */
- android_cm_active_net_mid =
- jni_get_method_id(env, obj_cls, "getActiveNetwork",
- "()Landroid/net/Network;");
- if (android_cm_active_net_mid == NULL)
+ android_cm_active_net_mid = jni_get_method_id(
+ env, obj_cls, "getActiveNetwork", "()Landroid/net/Network;");
+ if (android_cm_active_net_mid == NULL) {
goto cleanup;
+ }
/* ConnectivityManager.getLinkProperties in API 21. */
android_cm_link_props_mid =
- jni_get_method_id(env, obj_cls, "getLinkProperties",
- "(Landroid/net/Network;)Landroid/net/LinkProperties;");
- if (android_cm_link_props_mid == NULL)
+ jni_get_method_id(env, obj_cls, "getLinkProperties",
+ "(Landroid/net/Network;)Landroid/net/LinkProperties;");
+ if (android_cm_link_props_mid == NULL) {
goto cleanup;
+ }
/* LinkProperties in API 21. */
(*env)->DeleteLocalRef(env, obj_cls);
obj_cls = jni_get_class(env, "android/net/LinkProperties");
- if (obj_cls == NULL)
+ if (obj_cls == NULL) {
goto cleanup;
+ }
/* getDnsServers in API 21. */
- android_lp_dns_servers_mid = jni_get_method_id(env, obj_cls, "getDnsServers",
- "()Ljava/util/List;");
- if (android_lp_dns_servers_mid == NULL)
+ android_lp_dns_servers_mid =
+ jni_get_method_id(env, obj_cls, "getDnsServers", "()Ljava/util/List;");
+ if (android_lp_dns_servers_mid == NULL) {
goto cleanup;
+ }
/* getDomains in API 21. */
- android_lp_domains_mid = jni_get_method_id(env, obj_cls, "getDomains",
- "()Ljava/lang/String;");
- if (android_lp_domains_mid == NULL)
+ android_lp_domains_mid =
+ jni_get_method_id(env, obj_cls, "getDomains", "()Ljava/lang/String;");
+ if (android_lp_domains_mid == NULL) {
goto cleanup;
+ }
(*env)->DeleteLocalRef(env, obj_cls);
obj_cls = jni_get_class(env, "java/util/List");
- if (obj_cls == NULL)
+ if (obj_cls == NULL) {
goto cleanup;
+ }
android_list_size_mid = jni_get_method_id(env, obj_cls, "size", "()I");
- if (android_list_size_mid == NULL)
+ if (android_list_size_mid == NULL) {
goto cleanup;
+ }
- android_list_get_mid = jni_get_method_id(env, obj_cls, "get",
- "(I)Ljava/lang/Object;");
- if (android_list_get_mid == NULL)
+ android_list_get_mid =
+ jni_get_method_id(env, obj_cls, "get", "(I)Ljava/lang/Object;");
+ if (android_list_get_mid == NULL) {
goto cleanup;
+ }
(*env)->DeleteLocalRef(env, obj_cls);
obj_cls = jni_get_class(env, "java/net/InetAddress");
- if (obj_cls == NULL)
+ if (obj_cls == NULL) {
goto cleanup;
+ }
- android_ia_host_addr_mid = jni_get_method_id(env, obj_cls, "getHostAddress",
- "()Ljava/lang/String;");
- if (android_ia_host_addr_mid == NULL)
+ android_ia_host_addr_mid =
+ jni_get_method_id(env, obj_cls, "getHostAddress", "()Ljava/lang/String;");
+ if (android_ia_host_addr_mid == NULL) {
goto cleanup;
+ }
(*env)->DeleteLocalRef(env, obj_cls);
goto done;
cleanup:
- if (obj_cls != NULL)
+ if (obj_cls != NULL) {
(*env)->DeleteLocalRef(env, obj_cls);
+ }
- android_cm_active_net_mid = NULL;
- android_cm_link_props_mid = NULL;
+ android_cm_active_net_mid = NULL;
+ android_cm_link_props_mid = NULL;
android_lp_dns_servers_mid = NULL;
- android_lp_domains_mid = NULL;
- android_list_size_mid = NULL;
- android_list_get_mid = NULL;
- android_ia_host_addr_mid = NULL;
+ android_lp_domains_mid = NULL;
+ android_list_size_mid = NULL;
+ android_list_get_mid = NULL;
+ android_ia_host_addr_mid = NULL;
done:
- if (need_detatch)
+ if (need_detatch) {
(*android_jvm)->DetachCurrentThread(android_jvm);
+ }
return ret;
}
int ares_library_android_initialized(void)
{
- if (android_jvm == NULL || android_connectivity_manager == NULL)
+ if (android_jvm == NULL || android_connectivity_manager == NULL) {
return ARES_ENOTINITIALIZED;
+ }
return ARES_SUCCESS;
}
void ares_library_cleanup_android(void)
{
- JNIEnv *env = NULL;
- int need_detatch = 0;
- int res;
+ JNIEnv *env = NULL;
+ int need_detatch = 0;
+ int res;
- if (android_jvm == NULL || android_connectivity_manager == NULL)
+ if (android_jvm == NULL || android_connectivity_manager == NULL) {
return;
+ }
res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6);
- if (res == JNI_EDETACHED)
- {
- env = NULL;
- res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
+ if (res == JNI_EDETACHED) {
+ env = NULL;
+ res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
need_detatch = 1;
}
- if (res != JNI_OK || env == NULL)
+ if (res != JNI_OK || env == NULL) {
return;
+ }
- android_cm_active_net_mid = NULL;
- android_cm_link_props_mid = NULL;
+ android_cm_active_net_mid = NULL;
+ android_cm_link_props_mid = NULL;
android_lp_dns_servers_mid = NULL;
- android_lp_domains_mid = NULL;
- android_list_size_mid = NULL;
- android_list_get_mid = NULL;
- android_ia_host_addr_mid = NULL;
+ android_lp_domains_mid = NULL;
+ android_list_size_mid = NULL;
+ android_list_get_mid = NULL;
+ android_ia_host_addr_mid = NULL;
(*env)->DeleteGlobalRef(env, android_connectivity_manager);
android_connectivity_manager = NULL;
- if (need_detatch)
+ if (need_detatch) {
(*android_jvm)->DetachCurrentThread(android_jvm);
+ }
}
-char **ares_get_android_server_list(size_t max_servers,
- size_t *num_servers)
+char **ares_get_android_server_list(size_t max_servers, size_t *num_servers)
{
- JNIEnv *env = NULL;
- jobject active_network = NULL;
- jobject link_properties = NULL;
- jobject server_list = NULL;
- jobject server = NULL;
- jstring str = NULL;
- jint nserv;
+ JNIEnv *env = NULL;
+ jobject active_network = NULL;
+ jobject link_properties = NULL;
+ jobject server_list = NULL;
+ jobject server = NULL;
+ jstring str = NULL;
+ jint nserv;
const char *ch_server_address;
- int res;
- size_t i;
- char **dns_list = NULL;
- int need_detatch = 0;
+ int res;
+ size_t i;
+ char **dns_list = NULL;
+ int need_detatch = 0;
if (android_jvm == NULL || android_connectivity_manager == NULL ||
- max_servers == 0 || num_servers == NULL)
- {
+ max_servers == 0 || num_servers == NULL) {
return NULL;
}
if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL ||
android_lp_dns_servers_mid == NULL || android_list_size_mid == NULL ||
- android_list_get_mid == NULL || android_ia_host_addr_mid == NULL)
- {
+ android_list_get_mid == NULL || android_ia_host_addr_mid == NULL) {
return NULL;
}
res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6);
- if (res == JNI_EDETACHED)
- {
- env = NULL;
- res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
+ if (res == JNI_EDETACHED) {
+ env = NULL;
+ res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
need_detatch = 1;
}
- if (res != JNI_OK || env == NULL)
+ if (res != JNI_OK || env == NULL) {
goto done;
+ }
/* JNI below is equivalent to this Java code.
import android.content.Context;
@@ -296,93 +320,100 @@ char **ares_get_android_server_list(size_t max_servers,
active_network = (*env)->CallObjectMethod(env, android_connectivity_manager,
android_cm_active_net_mid);
- if (active_network == NULL)
+ if (active_network == NULL) {
goto done;
+ }
link_properties =
- (*env)->CallObjectMethod(env, android_connectivity_manager,
- android_cm_link_props_mid, active_network);
- if (link_properties == NULL)
+ (*env)->CallObjectMethod(env, android_connectivity_manager,
+ android_cm_link_props_mid, active_network);
+ if (link_properties == NULL) {
goto done;
+ }
- server_list = (*env)->CallObjectMethod(env, link_properties,
- android_lp_dns_servers_mid);
- if (server_list == NULL)
+ server_list =
+ (*env)->CallObjectMethod(env, link_properties, android_lp_dns_servers_mid);
+ if (server_list == NULL) {
goto done;
+ }
nserv = (*env)->CallIntMethod(env, server_list, android_list_size_mid);
- if (nserv > (jint)max_servers)
+ if (nserv > (jint)max_servers) {
nserv = (jint)max_servers;
- if (nserv <= 0)
+ }
+ if (nserv <= 0) {
goto done;
+ }
*num_servers = (size_t)nserv;
- dns_list = ares_malloc(sizeof(*dns_list)*(*num_servers));
- for (i=0; i<*num_servers; i++)
- {
- server = (*env)->CallObjectMethod(env, server_list, android_list_get_mid,
- (jint)i);
- dns_list[i] = ares_malloc(64);
+ dns_list = ares_malloc(sizeof(*dns_list) * (*num_servers));
+ for (i = 0; i < *num_servers; i++) {
+ size_t len = 64;
+ server =
+ (*env)->CallObjectMethod(env, server_list, android_list_get_mid, (jint)i);
+ dns_list[i] = ares_malloc(len);
dns_list[i][0] = 0;
- if (server == NULL)
- {
+ if (server == NULL) {
continue;
}
str = (*env)->CallObjectMethod(env, server, android_ia_host_addr_mid);
ch_server_address = (*env)->GetStringUTFChars(env, str, 0);
- strncpy(dns_list[i], ch_server_address, 64);
+ ares_strcpy(dns_list[i], ch_server_address, len);
(*env)->ReleaseStringUTFChars(env, str, ch_server_address);
(*env)->DeleteLocalRef(env, str);
(*env)->DeleteLocalRef(env, server);
}
done:
- if ((*env)->ExceptionOccurred(env))
+ if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionClear(env);
+ }
- if (server_list != NULL)
+ if (server_list != NULL) {
(*env)->DeleteLocalRef(env, server_list);
- if (link_properties != NULL)
+ }
+ if (link_properties != NULL) {
(*env)->DeleteLocalRef(env, link_properties);
- if (active_network != NULL)
+ }
+ if (active_network != NULL) {
(*env)->DeleteLocalRef(env, active_network);
+ }
- if (need_detatch)
+ if (need_detatch) {
(*android_jvm)->DetachCurrentThread(android_jvm);
+ }
return dns_list;
}
char *ares_get_android_search_domains_list(void)
{
- JNIEnv *env = NULL;
- jobject active_network = NULL;
- jobject link_properties = NULL;
- jstring domains = NULL;
+ JNIEnv *env = NULL;
+ jobject active_network = NULL;
+ jobject link_properties = NULL;
+ jstring domains = NULL;
const char *domain;
- int res;
- char *domain_list = NULL;
- int need_detatch = 0;
+ int res;
+ char *domain_list = NULL;
+ int need_detatch = 0;
- if (android_jvm == NULL || android_connectivity_manager == NULL)
- {
+ if (android_jvm == NULL || android_connectivity_manager == NULL) {
return NULL;
}
if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL ||
- android_lp_domains_mid == NULL)
- {
+ android_lp_domains_mid == NULL) {
return NULL;
}
res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6);
- if (res == JNI_EDETACHED)
- {
- env = NULL;
- res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
+ if (res == JNI_EDETACHED) {
+ env = NULL;
+ res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
need_detatch = 1;
}
- if (res != JNI_OK || env == NULL)
+ if (res != JNI_OK || env == NULL) {
goto done;
+ }
/* JNI below is equivalent to this Java code.
import android.content.Context;
@@ -393,7 +424,7 @@ char *ares_get_android_search_domains_list(void)
.getSystemService(Context.CONNECTIVITY_SERVICE);
Network an = cm.getActiveNetwork();
LinkProperties lp = cm.getLinkProperties(an);
- String domains = lp.getDomains();
+ String domains = lp.getDomains();
for (String domain: domains.split(",")) {
String d = domain;
}
@@ -404,38 +435,45 @@ char *ares_get_android_search_domains_list(void)
active_network = (*env)->CallObjectMethod(env, android_connectivity_manager,
android_cm_active_net_mid);
- if (active_network == NULL)
+ if (active_network == NULL) {
goto done;
+ }
link_properties =
- (*env)->CallObjectMethod(env, android_connectivity_manager,
- android_cm_link_props_mid, active_network);
- if (link_properties == NULL)
+ (*env)->CallObjectMethod(env, android_connectivity_manager,
+ android_cm_link_props_mid, active_network);
+ if (link_properties == NULL) {
goto done;
+ }
/* Get the domains. It is a common separated list of domains to search. */
- domains = (*env)->CallObjectMethod(env, link_properties,
- android_lp_domains_mid);
- if (domains == NULL)
+ domains =
+ (*env)->CallObjectMethod(env, link_properties, android_lp_domains_mid);
+ if (domains == NULL) {
goto done;
+ }
/* Split on , */
- domain = (*env)->GetStringUTFChars(env, domains, 0);
+ domain = (*env)->GetStringUTFChars(env, domains, 0);
domain_list = ares_strdup(domain);
(*env)->ReleaseStringUTFChars(env, domains, domain);
(*env)->DeleteLocalRef(env, domains);
done:
- if ((*env)->ExceptionOccurred(env))
+ if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionClear(env);
+ }
- if (link_properties != NULL)
+ if (link_properties != NULL) {
(*env)->DeleteLocalRef(env, link_properties);
- if (active_network != NULL)
+ }
+ if (active_network != NULL) {
(*env)->DeleteLocalRef(env, active_network);
+ }
- if (need_detatch)
+ if (need_detatch) {
(*android_jvm)->DetachCurrentThread(android_jvm);
+ }
return domain_list;
}
#else