I want to use an existing C/C++ library in an Android project. The library contains calls to res_query
in the resolv.h
header (libresolv on Linux), which exists in the NDK and, according to Wikipedia, is part of Android's Bionic libc.
The program builds and links fine after removing the explicit link instruction -lresolv
from the build file, but DNS resolution with res_query
always fails (returns -1
).
To further inspect this issue, I built an example program using only a single call to res_query
using the example C++ project of Android Studio:
#include <jni.h>
#include <android/log.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_cpptest_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
unsigned char buf[128];
const int result = res_query("example.com", C_IN, T_A, buf, 128);
if (result < 0) {
herror(NULL);
__android_log_print(ANDROID_LOG_DEBUG, "CppTest", "DNS Error %d", h_errno);
return env->NewStringUTF("DNS: Query failed.");
}
else
return env->NewStringUTF("DNS: Query successful.");
}
This program, too, always fails with result == -1
and h_errno == 2
.
I have tried giving the app both android.permission.INTERNET
and android.permission.ACCESS_NETWORK_STATE
without success.
Building this as a simple C command line application with the Android NDK CMake toolchain and pushing it onto the Android device with adb
, it also exhibits the same behavior. Building the exact same code with a default Linux toolchain and executing it there works and returns a valid DNS response.
I cannot find any documentation or discussion online about the state of resolv.h
on Android, except this AOSP documentation page about DNS Resolvers, which names resolv
and states:
The code in Bionic continues to exist for app compatibility reasons
suggesting that it should work in native app code.
I am aware that most Android systems do not ship with a resolv.conf
file and this may very well be the issue. But bulletproof documentation stating this simply does not exist.
Does anyone know more specifically whether or not resolv.h
can work in Android NDK apps to make DNS queries using the system-supplied DNS nameserver settings or not?