summaryrefslogtreecommitdiff
path: root/pjlib-util
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-10-08 12:39:34 +0000
committerBenny Prijono <bennylp@teluu.com>2006-10-08 12:39:34 +0000
commit36413704c1ff24a8e38e0fcf47c9a9c87621e71a (patch)
tree4393a2f84da0f02f8b1374b0e3ff29d4dce50fb1 /pjlib-util
parentb1cdeda73284f461f15c68468369baf7556cb0e3 (diff)
Major addition to support DNS SRV resolution in PJSIP:
- added DNS asynchronous/caching resolver engine in PJLIB-UTIL (resolver.[hc]) - modified SIP resolver (sip_resolve.c) to properly perform DNS SRV/A resolution when DNS resolution is enabled. - added dns_test.c in PJSIP-TEST for testing the SIP resolver. - added nameserver configuration in PJSUA-LIB - added "--nameserver" option in PJSUA. - updated project/Makefiles and doxygen documentation. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@753 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib-util')
-rw-r--r--pjlib-util/build/Makefile2
-rw-r--r--pjlib-util/build/pjlib_util.dsp35
-rw-r--r--pjlib-util/build/wince-evc4/pjlib_util_wince.vcp1826
-rw-r--r--pjlib-util/include/pjlib-util.h1
-rw-r--r--pjlib-util/include/pjlib-util/dns.h164
-rw-r--r--pjlib-util/include/pjlib-util/errno.h113
-rw-r--r--pjlib-util/include/pjlib-util/resolver.h520
-rw-r--r--pjlib-util/src/pjlib-util/dns.c257
-rw-r--r--pjlib-util/src/pjlib-util/dns_dump.c96
-rw-r--r--pjlib-util/src/pjlib-util/errno.c23
-rw-r--r--pjlib-util/src/pjlib-util/resolver.c1408
11 files changed, 4280 insertions, 165 deletions
diff --git a/pjlib-util/build/Makefile b/pjlib-util/build/Makefile
index 3c7be4f4..a5d8c925 100644
--- a/pjlib-util/build/Makefile
+++ b/pjlib-util/build/Makefile
@@ -26,7 +26,7 @@ export _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJLIB_UTIL_LIB)) \
#
export PJLIB_UTIL_SRCDIR = ../src/pjlib-util
export PJLIB_UTIL_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
- errno.o dns.o dns_dump.o getopt.o md5.o \
+ errno.o dns.o dns_dump.o getopt.o md5.o resolver.o \
scanner.o stun.o string.o stun.o stun_client.o xml.o
export PJLIB_UTIL_CFLAGS += $(_CFLAGS)
diff --git a/pjlib-util/build/pjlib_util.dsp b/pjlib-util/build/pjlib_util.dsp
index 56dac412..a8722e69 100644
--- a/pjlib-util/build/pjlib_util.dsp
+++ b/pjlib-util/build/pjlib_util.dsp
@@ -41,7 +41,8 @@ RSC=rc.exe
# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
+# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -64,7 +65,8 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -86,10 +88,24 @@ LIB32=link.exe -lib
# Begin Source File
SOURCE="..\src\pjlib-util\dns.c"
+
+!IF "$(CFG)" == "pjlib_util - Win32 Release"
+
+!ELSEIF "$(CFG)" == "pjlib_util - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
SOURCE="..\src\pjlib-util\dns_dump.c"
+
+!IF "$(CFG)" == "pjlib_util - Win32 Release"
+
+!ELSEIF "$(CFG)" == "pjlib_util - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -105,6 +121,17 @@ SOURCE="..\src\pjlib-util\md5.c"
# End Source File
# Begin Source File
+SOURCE="..\src\pjlib-util\resolver.c"
+
+!IF "$(CFG)" == "pjlib_util - Win32 Release"
+
+!ELSEIF "$(CFG)" == "pjlib_util - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjlib-util\scanner.c"
# End Source File
# Begin Source File
@@ -163,6 +190,10 @@ SOURCE="..\include\pjlib-util.h"
# End Source File
# Begin Source File
+SOURCE="..\include\pjlib-util\resolver.h"
+# End Source File
+# Begin Source File
+
SOURCE="..\include\pjlib-util\scanner.h"
# End Source File
# Begin Source File
diff --git a/pjlib-util/build/wince-evc4/pjlib_util_wince.vcp b/pjlib-util/build/wince-evc4/pjlib_util_wince.vcp
index fa7e155a..953b54b8 100644
--- a/pjlib-util/build/wince-evc4/pjlib_util_wince.vcp
+++ b/pjlib-util/build/wince-evc4/pjlib_util_wince.vcp
@@ -1659,6 +1659,8 @@ DEP_CPP_DNS_C=\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
"..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
@@ -2505,10 +2507,17 @@ DEP_CPP_DNS_D=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_DNS_D=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
"..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
@@ -2517,12 +2526,40 @@ DEP_CPP_DNS_D=\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
"..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
"..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjlib-util\dns.h"\
@@ -3316,16 +3353,17 @@ DEP_CPP_ERRNO=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_ERRNO=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_powerpc.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
- "..\..\..\pjlib\include\pj\compat\m_x86_64.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
"..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
@@ -3334,19 +3372,40 @@ DEP_CPP_ERRNO=\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
"..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
"..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjlib-util\errno.h"\
@@ -4201,15 +4260,17 @@ DEP_CPP_GETOP=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_GETOP=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_powerpc.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
- "..\..\..\pjlib\include\pj\compat\m_x86_64.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
"..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
@@ -4218,18 +4279,40 @@ DEP_CPP_GETOP=\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
"..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjlib-util\getopt.h"\
@@ -5055,36 +5138,61 @@ NODEP_CPP_MD5_C=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_MD5_C=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
"..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjlib-util\md5.h"\
-NODEP_CPP_MD5_C=\
- "..\..\..\pjlib\include\pj\compat\sprintf.h"\
- "..\..\..\pjlib\include\pj\compat\vsprintf.h"\
-
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug"
@@ -5330,6 +5438,1477 @@ DEP_CPP_MD5_C=\
# End Source File
# Begin Source File
+SOURCE="..\..\src\pjlib-util\resolver.c"
+
+!IF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSII_FP) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSII_FP) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSII) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSII) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE SH4) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE SH4) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE SH3) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE SH3) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSIV) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSIV) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE emulator) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE emulator) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4I) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4I) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSIV_FP) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSIV_FP) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPS16) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPS16) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4T) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4T) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE x86) Release"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE x86) Debug"
+
+DEP_CPP_RESOL=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\dns.h"\
+ "..\..\include\pjlib-util\errno.h"\
+ "..\..\include\pjlib-util\resolver.h"\
+
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
SOURCE="..\..\src\pjlib-util\scanner.c"
!IF "$(CFG)" == "pjlib_util_wince - Win32 (WCE MIPSII_FP) Release"
@@ -6071,19 +7650,22 @@ NODEP_CPP_SCANN=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_SCANN=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
"..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
@@ -6092,26 +7674,41 @@ DEP_CPP_SCANN=\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
"..\..\..\pjlib\include\pj\errno.h"\
"..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
"..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjlib-util\scanner.h"\
"..\..\include\pjlib-util\scanner_cis_bitwise.h"\
"..\..\include\pjlib-util\scanner_cis_uint.h"\
"..\..\src\pjlib-util\scanner_cis_bitwise.c"\
"..\..\src\pjlib-util\scanner_cis_uint.c"\
-NODEP_CPP_SCANN=\
- "..\..\..\pjlib\include\pj\compat\sprintf.h"\
- "..\..\..\pjlib\include\pj\compat\vsprintf.h"\
-
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug"
@@ -7086,41 +8683,64 @@ NODEP_CPP_STRIN=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_STRIN=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
"..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
"..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjlib-util\scanner.h"\
"..\..\include\pjlib-util\scanner_cis_bitwise.h"\
"..\..\include\pjlib-util\scanner_cis_uint.h"\
"..\..\include\pjlib-util\string.h"\
-NODEP_CPP_STRIN=\
- "..\..\..\pjlib\include\pj\compat\sprintf.h"\
- "..\..\..\pjlib\include\pj\compat\vsprintf.h"\
-
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug"
@@ -8019,39 +9639,62 @@ NODEP_CPP_STUN_=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_STUN_=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
"..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
"..\..\..\pjlib\include\pj\log.h"\
"..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
"..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\errno.h"\
"..\..\include\pjlib-util\stun.h"\
-NODEP_CPP_STUN_=\
- "..\..\..\pjlib\include\pj\compat\sprintf.h"\
- "..\..\..\pjlib\include\pj\compat\vsprintf.h"\
-
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug"
@@ -8954,40 +10597,62 @@ NODEP_CPP_STUN_C=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_STUN_C=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
"..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
"..\..\..\pjlib\include\pj\log.h"\
"..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
"..\..\..\pjlib\include\pj\sock.h"\
"..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjlib-util\errno.h"\
"..\..\include\pjlib-util\stun.h"\
-NODEP_CPP_STUN_C=\
- "..\..\..\pjlib\include\pj\compat\sprintf.h"\
- "..\..\..\pjlib\include\pj\compat\vsprintf.h"\
-
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug"
@@ -9944,16 +11609,22 @@ NODEP_CPP_XML_C=\
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release"
DEP_CPP_XML_C=\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
- "..\..\..\pjlib\include\pj\compat\m_alpha.h"\
- "..\..\..\pjlib\include\pj\compat\m_armv4.h"\
- "..\..\..\pjlib\include\pj\compat\m_i386.h"\
- "..\..\..\pjlib\include\pj\compat\m_m68k.h"\
- "..\..\..\pjlib\include\pj\compat\m_sparc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
"..\..\..\pjlib\include\pj\compat\os_linux.h"\
"..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
"..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
@@ -9962,25 +11633,40 @@ DEP_CPP_XML_C=\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
"..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
"..\..\..\pjlib\include\pj\list.h"\
"..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
"..\..\..\pjlib\include\pj\log.h"\
"..\..\..\pjlib\include\pj\os.h"\
"..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
"..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
"..\..\..\pjlib\include\pj\string.h"\
"..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
"..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjlib-util\scanner.h"\
"..\..\include\pjlib-util\scanner_cis_bitwise.h"\
"..\..\include\pjlib-util\scanner_cis_uint.h"\
"..\..\include\pjlib-util\xml.h"\
-NODEP_CPP_XML_C=\
- "..\..\..\pjlib\include\pj\compat\sprintf.h"\
- "..\..\..\pjlib\include\pj\compat\vsprintf.h"\
-
!ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug"
@@ -10299,6 +11985,10 @@ SOURCE="..\..\include\pjlib-util.h"
# End Source File
# Begin Source File
+SOURCE="..\..\include\pjlib-util\resolver.h"
+# End Source File
+# Begin Source File
+
SOURCE="..\..\include\pjlib-util\scanner.h"
# End Source File
# Begin Source File
diff --git a/pjlib-util/include/pjlib-util.h b/pjlib-util/include/pjlib-util.h
index 741578fd..3ac8c50b 100644
--- a/pjlib-util/include/pjlib-util.h
+++ b/pjlib-util/include/pjlib-util.h
@@ -23,6 +23,7 @@
#include <pjlib-util/errno.h>
#include <pjlib-util/getopt.h>
#include <pjlib-util/md5.h>
+#include <pjlib-util/resolver.h>
#include <pjlib-util/scanner.h>
#include <pjlib-util/stun.h>
#include <pjlib-util/xml.h>
diff --git a/pjlib-util/include/pjlib-util/dns.h b/pjlib-util/include/pjlib-util/dns.h
index cb6a28f2..d431b0da 100644
--- a/pjlib-util/include/pjlib-util/dns.h
+++ b/pjlib-util/include/pjlib-util/dns.h
@@ -22,7 +22,7 @@
/**
* @file dns.h
- * @brief Asynchronous DNS Name Resolution/resolver
+ * @brief Low level DNS message parsing and packetization.
*/
#include <pj/types.h>
@@ -31,16 +31,35 @@ PJ_BEGIN_DECL
/**
- * @defgroup PJ_DNS_RESOLVER Asynchronous DNS Name Resolution/resolver
+ * @defgroup PJ_DNS Low-level DNS message parsing and packetization
* @ingroup PJ
* @{
*
- * This module provides services to performing asynchronous DNS resolution.
+ * This module provides low-level services to parse and packetize DNS queries
+ * and responses. The functions support building a DNS query packet and parse
+ * the data in the DNS response.
+ *
+ * To create a DNS query packet, application should call #pj_dns_make_query()
+ * function, specifying the desired DNS query type, the name to be resolved,
+ * and the buffer where the DNS packet will be built into.
+ *
+ * When incoming DNS query or response packet arrives, application can use
+ * #pj_dns_parse_packet() to parse the TCP/UDP payload into parsed DNS packet
+ * structure.
+ *
+ * This module does not provide any networking functionalities to send or
+ * receive DNS packets. This functionality should be provided by higher layer
+ * modules such as @ref PJ_DNS_RESOLVER.
*/
+enum
+{
+ PJ_DNS_CLASS_IN = 1 /**< DNS class IN. */
+};
+
/**
* This enumeration describes standard DNS record types as described by
- * RFC 1035.
+ * RFC 1035, RFC 2782, and others.
*/
typedef enum pj_dns_type
{
@@ -158,31 +177,69 @@ typedef struct pj_dns_hdr
#define PJ_DNS_GET_QR(val) (((val) & PJ_DNS_SET_QR(1)) >> 15)
+/**
+ * These constants describe DNS RCODEs. Application can fold these constants
+ * into PJLIB pj_status_t namespace by calling #PJ_STATUS_FROM_DNS_RCODE()
+ * macro.
+ */
+typedef enum pj_dns_rcode
+{
+ PJ_DNS_RCODE_FORMERR = 1, /**< Format error. */
+ PJ_DNS_RCODE_SERVFAIL = 2, /**< Server failure. */
+ PJ_DNS_RCODE_NXDOMAIN = 3, /**< Name Error. */
+ PJ_DNS_RCODE_NOTIMPL = 4, /**< Not Implemented. */
+ PJ_DNS_RCODE_REFUSED = 5, /**< Refused. */
+ PJ_DNS_RCODE_YXDOMAIN = 6, /**< The name exists. */
+ PJ_DNS_RCODE_YXRRSET = 7, /**< The RRset (name, type) exists. */
+ PJ_DNS_RCODE_NXRRSET = 8, /**< The RRset (name, type) doesn't exist*/
+ PJ_DNS_RCODE_NOTAUTH = 9, /**< Not authorized. */
+ PJ_DNS_RCODE_NOTZONE = 10 /**< The zone specified is not a zone. */
+
+} pj_dns_rcode;
+
/**
- * This constants describes record types in the DNS packet.
+ * This constant specifies the maximum names to keep in the temporary name
+ * table when performing name compression scheme when duplicating DNS packet
+ * (the #pj_dns_packet_dup() function).
+ *
+ * Generally name compression is desired, since it saves some memory (see
+ * PJ_DNS_RESOLVER_RES_BUF_SIZE setting). However it comes at the expense of
+ * a little processing overhead to perform name scanning and also a little
+ * bit more stack usage (8 bytes per entry on 32bit platform).
+ *
+ * Default: 16
*/
-typedef enum pj_dns_rec_type
+#ifndef PJ_DNS_MAX_NAMES_IN_NAMETABLE
+# define PJ_DNS_MAX_NAMES_IN_NAMETABLE 16
+#endif
+
+
+/**
+ * This structure describes a DNS query record.
+ */
+typedef struct pj_dns_parsed_query
{
- DNS_QUERY_REC, /**< The record is a query record */
- DNS_RR_REC, /**< The record is resource record */
- DNS_NS_REC, /**< The record is name server record */
- DNS_REC_AR, /**< The record is additional RR. */
-} pj_dns_rec_type;
+ pj_str_t name; /**< The domain in the query. */
+ pj_uint16_t type; /**< Type of the query (pj_dns_type) */
+ pj_uint16_t dnsclass; /**< Network class (PJ_DNS_CLASS_IN=1) */
+} pj_dns_parsed_query;
/**
- * This structure describes a Resource Record parsed from the DNS response.
+ * This structure describes a Resource Record parsed from the DNS packet.
* All integral values are in host byte order.
*/
typedef struct pj_dns_parsed_rr
{
pj_str_t name; /**< The domain name which this rec pertains. */
pj_uint16_t type; /**< RR type code. */
- pj_uint16_t class_; /**< Class of data (normally 1, for IN). */
+ pj_uint16_t dnsclass; /**< Class of data (PJ_DNS_CLASS_IN=1). */
pj_uint32_t ttl; /**< Time to live. */
pj_uint16_t rdlength; /**< Resource data length. */
- void *data; /**< Pointer to the raw resource data. */
+ void *data; /**< Pointer to the raw resource data, only
+ when the type is not known. If it is known,
+ the data will be put in rdata below. */
/** For resource types that are recognized/supported by this library,
* the parsed resource data will be placed in this rdata union.
@@ -223,21 +280,29 @@ typedef struct pj_dns_parsed_rr
/**
- * This structure describes the response parsed from the raw DNS response.
- * Note that all integral values in the parsed response are represented in
+ * This structure describes the parsed repersentation of the raw DNS packet.
+ * Note that all integral values in the parsed packet are represented in
* host byte order.
*/
-typedef struct pj_dns_parsed_response
+typedef struct pj_dns_parsed_packet
{
- pj_dns_hdr hdr; /**< Pointer to DNS hdr, in host byte order */
- pj_dns_parsed_rr *ans; /**< Array of DNS RR answer. */
- pj_dns_parsed_rr *ns; /**< Array of NS record in the answer. */
- pj_dns_parsed_rr *arr; /**< Array of additional RR answer. */
-} pj_dns_parsed_response;
+ pj_dns_hdr hdr; /**< Pointer to DNS hdr, in host byte order */
+ pj_dns_parsed_query *q; /**< Array of DNS queries. */
+ pj_dns_parsed_rr *ans; /**< Array of DNS RR answer. */
+ pj_dns_parsed_rr *ns; /**< Array of NS record in the answer. */
+ pj_dns_parsed_rr *arr; /**< Array of additional RR answer. */
+} pj_dns_parsed_packet;
/**
- * Create DNS query packet to resolve the specified names.
+ * Create DNS query packet to resolve the specified names. This function
+ * can be used to build any types of DNS query, such as A record or DNS SRV
+ * record.
+ *
+ * Application specifies the type of record and the name to be queried,
+ * and the function will build the DNS query packet into the buffer
+ * specified. Once the packet is successfully built, application can send
+ * the packet via TCP or UDP connection.
*
* @param packet The buffer to put the DNS query packet.
* @param size On input, it specifies the size of the buffer.
@@ -245,7 +310,7 @@ typedef struct pj_dns_parsed_response
* the DNS query packet.
* @param id DNS query ID to associate DNS response with the
* query.
- * @param qtype DNS type of record to be queried.
+ * @param qtype DNS type of record to be queried (see #pj_dns_type).
* @param name Name to be queried from the DNS server.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
@@ -253,30 +318,55 @@ typedef struct pj_dns_parsed_response
PJ_DECL(pj_status_t) pj_dns_make_query(void *packet,
unsigned *size,
pj_uint16_t id,
- pj_dns_type qtype,
+ int qtype,
const pj_str_t *name);
/**
- * Parse raw DNS response packet into DNS response structure.
+ * Parse raw DNS packet into parsed DNS packet structure. This function is
+ * able to parse few DNS resource records such as A record, PTR record,
+ * CNAME record, NS record, and SRV record.
*
- * @param pool Pool to allocate memory for the parsed response.
- * @param packet
- * @param size
- * @param p_res
+ * @param pool Pool to allocate memory for the parsed packet.
+ * @param packet Pointer to the DNS packet (the TCP/UDP payload of
+ * the raw packet).
+ * @param size The size of the DNS packet.
+ * @param p_res Pointer to store the resulting parsed packet.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
-PJ_DECL(pj_status_t) pj_dns_parse_response(pj_pool_t *pool,
- const void *packet,
- unsigned size,
- pj_dns_parsed_response **p_res);
+PJ_DECL(pj_status_t) pj_dns_parse_packet(pj_pool_t *pool,
+ const void *packet,
+ unsigned size,
+ pj_dns_parsed_packet **p_res);
+
+/**
+ * Duplicate DNS packet.
+ *
+ * @param pool The pool to allocate memory for the duplicated packet.
+ * @param p The DNS packet to be cloned.
+ * @p_dst Pointer to store the cloned DNS packet.
+ */
+PJ_DECL(void) pj_dns_packet_dup(pj_pool_t *pool,
+ const pj_dns_parsed_packet*p,
+ pj_dns_parsed_packet **p_dst);
+
+
+/**
+ * Utility function to get the type name string of the specified DNS type.
+ *
+ * @param type DNS type (see #pj_dns_type).
+ *
+ * @return String name of the type (e.g. "A", "SRV", etc.).
+ */
+PJ_DECL(const char *) pj_dns_get_type_name(int type);
+
/**
- * Dump DNS response to standard log.
+ * Dump DNS packet to standard log.
*
- * @param res The DNS response.
+ * @param res The DNS packet.
*/
-PJ_DECL(void) pj_dns_dump_response(const pj_dns_parsed_response *res);
+PJ_DECL(void) pj_dns_dump_packet(const pj_dns_parsed_packet *res);
/**
diff --git a/pjlib-util/include/pjlib-util/errno.h b/pjlib-util/include/pjlib-util/errno.h
index 45e25f97..589fcb63 100644
--- a/pjlib-util/include/pjlib-util/errno.h
+++ b/pjlib-util/include/pjlib-util/errno.h
@@ -1,4 +1,4 @@
-/* $Id */
+/* $Id$ */
/*
* Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
*
@@ -107,34 +107,137 @@
***********************************************************/
/**
* @hideinitializer
- * Outgoing DNS query packet buffer is too small.
+ * DNS query packet buffer is too small.
* This error occurs when the user supplied buffer for creating DNS
* query (#pj_dns_make_query() function) is too small.
*/
#define PJLIB_UTIL_EDNSQRYTOOSMALL (PJLIB_UTIL_ERRNO_START+40) /* 320040 */
/**
* @hideinitializer
- * Invalid packet length in DNS response.
+ * Invalid DNS packet length.
* This error occurs when the received DNS response packet does not
* match all the fields length.
*/
#define PJLIB_UTIL_EDNSINSIZE (PJLIB_UTIL_ERRNO_START+41) /* 320041 */
/**
* @hideinitializer
- * Invalid class in DNS response.
+ * Invalid DNS class.
* This error occurs when the received DNS response contains network
* class other than IN (Internet).
*/
#define PJLIB_UTIL_EDNSINCLASS (PJLIB_UTIL_ERRNO_START+42) /* 320042 */
/**
* @hideinitializer
- * Invalid name pointer in DNS response.
+ * Invalid DNS name pointer.
* This error occurs when parsing the compressed names inside DNS
* response packet, when the name pointer points to an invalid address
* or the parsing has triggerred too much recursion.
*/
#define PJLIB_UTIL_EDNSINNAMEPTR (PJLIB_UTIL_ERRNO_START+43) /* 320043 */
+/**
+ * @hideinitializer
+ * Invalid DNS nameserver address. If hostname was specified for nameserver
+ * address, this error means that the function was unable to resolve
+ * the nameserver hostname.
+ */
+#define PJLIB_UTIL_EDNSINNSADDR (PJLIB_UTIL_ERRNO_START+44) /* 320044 */
+/**
+ * @hideinitializer
+ * No nameserver is in DNS resolver. No nameserver is configured in the
+ * resolver.
+ */
+#define PJLIB_UTIL_EDNSNONS (PJLIB_UTIL_ERRNO_START+45) /* 320045 */
+/**
+ * @hideinitializer
+ * No working DNS nameserver. All nameservers have been queried,
+ * but none was able to serve any DNS requests. These "bad" nameservers
+ * will be re-tested again for "goodness" after some period.
+ */
+#define PJLIB_UTIL_EDNSNOWORKINGNS (PJLIB_UTIL_ERRNO_START+46) /* 320046 */
+/**
+ * @hideinitializer
+ * No answer record in the DNS response.
+ */
+#define PJLIB_UTIL_EDNSNOANSWERREC (PJLIB_UTIL_ERRNO_START+47) /* 320047 */
+
+/* DNS ERRORS MAPPED FROM RCODE: */
+
+/**
+ * Start of error code mapped from DNS RCODE
+ */
+#define PJLIB_UTIL_DNS_RCODE_START (PJLIB_UTIL_ERRNO_START+50) /* 320050 */
+
+/**
+ * Map DNS RCODE status into pj_status_t.
+ */
+#define PJ_STATUS_FROM_DNS_RCODE(rcode) (rcode==0 ? PJ_SUCCESS : \
+ PJLIB_UTIL_DNS_RCODE_START+rcode)
+/**
+ * @hideinitializer
+ * Format error - The name server was unable to interpret the query.
+ * This corresponds to DNS RCODE 1.
+ */
+#define PJLIB_UTIL_EDNS_FORMERR PJ_STATUS_FROM_DNS_RCODE(1) /* 320051 */
+/**
+ * @hideinitializer
+ * Server failure - The name server was unable to process this query due to a
+ * problem with the name server.
+ * This corresponds to DNS RCODE 2.
+ */
+#define PJLIB_UTIL_EDNS_SERVFAIL PJ_STATUS_FROM_DNS_RCODE(2) /* 320052 */
+/**
+ * @hideinitializer
+ * Name Error - Meaningful only for responses from an authoritative name
+ * server, this code signifies that the domain name referenced in the query
+ * does not exist.
+ * This corresponds to DNS RCODE 3.
+ */
+#define PJLIB_UTIL_EDNS_NXDOMAIN PJ_STATUS_FROM_DNS_RCODE(3) /* 320053 */
+/**
+ * @hideinitializer
+ * Not Implemented - The name server does not support the requested kind of
+ * query.
+ * This corresponds to DNS RCODE 4.
+ */
+#define PJLIB_UTIL_EDNS_NOTIMPL PJ_STATUS_FROM_DNS_RCODE(4) /* 320054 */
+/**
+ * @hideinitializer
+ * Refused - The name server refuses to perform the specified operation for
+ * policy reasons.
+ * This corresponds to DNS RCODE 5.
+ */
+#define PJLIB_UTIL_EDNS_REFUSED PJ_STATUS_FROM_DNS_RCODE(5) /* 320055 */
+/**
+ * @hideinitializer
+ * The name exists.
+ * This corresponds to DNS RCODE 6.
+ */
+#define PJLIB_UTIL_EDNS_YXDOMAIN PJ_STATUS_FROM_DNS_RCODE(6) /* 320056 */
+/**
+ * @hideinitializer
+ * The RRset (name, type) exists.
+ * This corresponds to DNS RCODE 7.
+ */
+#define PJLIB_UTIL_EDNS_YXRRSET PJ_STATUS_FROM_DNS_RCODE(7) /* 320057 */
+/**
+ * @hideinitializer
+ * The RRset (name, type) does not exist.
+ * This corresponds to DNS RCODE 8.
+ */
+#define PJLIB_UTIL_EDNS_NXRRSET PJ_STATUS_FROM_DNS_RCODE(8) /* 320058 */
+/**
+ * @hideinitializer
+ * The requestor is not authorized to perform this operation.
+ * This corresponds to DNS RCODE 9.
+ */
+#define PJLIB_UTIL_EDNS_NOTAUTH PJ_STATUS_FROM_DNS_RCODE(9) /* 320059 */
+/**
+ * @hideinitializer
+ * The zone specified is not a zone.
+ * This corresponds to DNS RCODE 10.
+ */
+#define PJLIB_UTIL_EDNS_NOTZONE PJ_STATUS_FROM_DNS_RCODE(10)/* 320060 */
#endif /* __PJLIB_UTIL_ERRNO_H__ */
diff --git a/pjlib-util/include/pjlib-util/resolver.h b/pjlib-util/include/pjlib-util/resolver.h
new file mode 100644
index 00000000..471b5717
--- /dev/null
+++ b/pjlib-util/include/pjlib-util/resolver.h
@@ -0,0 +1,520 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_RESOLVER_H__
+#define __PJLIB_UTIL_RESOLVER_H__
+
+/**
+ * @file resolver.h
+ * @brief Asynchronous DNS resolver
+ */
+#include <pjlib-util/dns.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_DNS_RESOLVER Asynchronous DNS Server Resolution
+ * @ingroup PJLIB_UTIL
+ * @{
+ *
+ * This module manages the host/server resolution by performing asynchronous
+ * DNS queries and caching the results in the cache. It uses PJLIB-UTIL
+ * low-level DNS parsing functions (see @ref PJ_DNS) and currently supports
+ * several types of DNS resource records such as A record (typical query with
+ * gethostbyname()) and SRV record.
+ *
+ * \section PJ_DNS_RESOLVER_FEATURES Features
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_ASYNC Asynchronous Query and Query Aggregation
+ *
+ * The DNS queries are performed asychronously, with timeout setting
+ * configured on per resolver instance basis. Application can issue multiple
+ * asynchronous queries simultaneously. Subsequent queries to the same resource
+ * (name and DNS resource type) while existing query is still pending will be
+ * merged into one query, so that only one DNS request packet is issued.
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_RETRANSMISSION Query Retransmission
+ *
+ * Asynchronous query will be retransmitted if no response is received
+ * within the preconfigured time. Once maximum retransmission count is
+ * exceeded and no response is received, the query will time out and the
+ * callback will be called when error status.
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_CACHING Response Caching with TTL
+ *
+ * The resolver instance caches the results returned by nameservers, to
+ * enhance the performance by minimizing the message round-trip to the server.
+ * The TTL of the cached resposne is calculated from minimum TTL value found
+ * across all resource record (RR) TTL in the response and further more it can
+ * be limited to some preconfigured maximum TTL in the resolver.
+ *
+ * Response caching can be disabled by setting the maximum TTL value of the
+ * resolver to zero.
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_PARALLEL Parallel and Backup Name Servers
+ *
+ * When the resolver is configured with multiple nameservers, initially the
+ * queries will be issued to multiple name servers simultaneously to probe
+ * which servers are not active. Once the probing stage is done, subsequent
+ * queries will be directed to only one ACTIVE server which provides the best
+ * response time.
+ *
+ * Name servers are probed periodically to see which nameservers are active
+ * and which are down. This probing is done when a query is sent, thus no
+ * timer is needed to maintain this. Also probing will be done in parallel
+ * so that there would be no additional delay for the query.
+ *
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_REC Supported Resource Records
+ *
+ * The low-level DNS parsing utility (see @ref PJ_DNS) supports parsing of
+ * the following DNS resource records (RR):
+ * - DNS A record
+ * - DNS SRV record
+ * - DNS PTR record
+ * - DNS NS record
+ * - DNS CNAME record
+ *
+ * For other types of record, application can parse the raw resource
+ * record data (rdata) from the parsed DNS packet (#pj_dns_parsed_packet).
+ *
+ *
+ * \section PJ_DNS_RESOLVER_USING Using the Resolver
+ *
+ * To use the resolver, application first creates the resolver instance by
+ * calling #pj_dns_resolver_create(). If application already has its own
+ * timer and ioqueue instances, it can instruct the resolver to use these
+ * instances so that application does not need to poll the resolver
+ * periodically to process events. If application does not specify the
+ * timer and ioqueue instance for the resolver, an internal timer and
+ * ioqueue will be created by the resolver. And since the resolver does not
+ * create it's own thread, application MUST poll the resolver periodically
+ * by calling #pj_dns_resolver_handle_events() to allow events (network and
+ * timer) to be processed.
+ *
+ * Next, application MUST configure the nameservers to be used by the
+ * resolver, by calling #pj_dns_resolver_set_ns().
+ *
+ * Application performs asynchronous query by submitting the query with
+ * #pj_dns_resolver_start_query(). Once the query completes (either
+ * successfully or times out), the callback will be called.
+ *
+ * Application can cancel a pending query by calling #pj_dns_resolver_cancel_query().
+ *
+ * Resolver must be destroyed by calling #pj_dns_resolver_destroy() to
+ * release all resources back to the system.
+ *
+ *
+ * \section PJ_DNS_RESOLVER_LIMITATIONS Resolver Limitations
+ *
+ * Current implementation mainly suffers from a growing memory problem,
+ * which mainly is caused by the response caching. Although there is only
+ * one cache entry per {query, name} combination, these cache entry will
+ * never get deleted since there is no timer is created to invalidate these
+ * entries. So the more unique names being queried by application, there more
+ * enties will be created in the response cache.
+ *
+ * Note that a single response entry will occupy about 600-700 bytes of
+ * pool memory.
+ *
+ * Application can work around this problem by doing one of these:
+ * - disable caching by setting PJ_DNS_RESOLVER_MAX_TTL and
+ * PJ_DNS_RESOLVER_INVALID_TTL to zero.
+ * - periodically query #pj_dns_resolver_get_cached_count() and destroy-
+ * recreate the resolver to recycle the memory used by the resolver.
+ *
+ * Note that future improvement may solve this problem by introducing
+ * expiration timer to the cached entries.
+ *
+ *
+ * \section PJ_DNS_RESOLVER_REFERENCE Reference
+ *
+ * The PJLIB-UTIL resolver was built from the information in the following
+ * standards:
+ * - RFC 1035: "Domain names - implementation and specification"
+ * - RFC 2782: "A DNS RR for specifying the location of services (DNS SRV)"
+ */
+
+
+/*
+ * CONFIGURATIONS
+ */
+
+/**
+ * Maximum numbers of DNS nameservers that can be configured in resolver.
+ */
+#ifndef PJ_DNS_RESOLVER_MAX_NS
+# define PJ_DNS_RESOLVER_MAX_NS 16
+#endif
+
+
+/**
+ * Default retransmission delay, in miliseconds. The combination of
+ * retransmission delay and count determines the query timeout.
+ *
+ * Default: 2000 (2 seconds, according to RFC 1035)
+ */
+#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY
+# define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY 2000
+#endif
+
+
+/**
+ * Maximum number of transmissions before timeout is declared for
+ * the query.
+ *
+ * Default: 2
+ */
+#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT
+# define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT 5
+#endif
+
+
+/**
+ * Maximum life-time of DNS response in the resolver response cache,
+ * in seconds. If the value is zero, then DNS response caching will be
+ * disabled.
+ *
+ * Default is 300 seconds (5 minutes).
+ *
+ * @see PJ_DNS_RESOLVER_INVALID_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_MAX_TTL
+# define PJ_DNS_RESOLVER_MAX_TTL (5*60)
+#endif
+
+/**
+ * The life-time of invalid DNS response in the resolver response cache.
+ * An invalid DNS response is a response without an answer. These
+ * responses can be put in the cache too to minimize message round-trip.
+ *
+ * Default: 0 (which means, invalid DNS response will not be cached).
+ *
+ * @see PJ_DNS_RESOLVER_MAX_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_INVALID_TTL
+# define PJ_DNS_RESOLVER_INVALID_TTL 60
+#endif
+
+/**
+ * The interval on which nameservers which are known to be good to be
+ * probed again to determine whether they are still good. Note that
+ * this applies to both active nameserver (the one currently being used)
+ * and idle nameservers (good nameservers that are not currently selected).
+ * The probing to query the "goodness" of nameservers involves sending
+ * the same query to multiple servers, so it's probably not a good idea
+ * to send this probing too often.
+ *
+ * Default: 600 (ten minutes)
+ *
+ * @see PJ_DNS_RESOLVER_BAD_NS_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_GOOD_NS_TTL
+# define PJ_DNS_RESOLVER_GOOD_NS_TTL (10*60)
+#endif
+
+/**
+ * The interval on which nameservers which known to be bad to be probed
+ * again to determine whether it is still bad.
+ *
+ * Default: 600 (ten minutes)
+ *
+ * @see PJ_DNS_RESOLVER_GOOD_NS_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_BAD_NS_TTL
+# define PJ_DNS_RESOLVER_BAD_NS_TTL (1*60)
+#endif
+
+
+/**
+ * Maximum size of UDP packet. RFC 1035 states that maximum size of
+ * DNS packet carried over UDP is 512 bytes.
+ *
+ * Default: 512 byes
+ */
+#ifndef PJ_DNS_RESOLVER_MAX_UDP_SIZE
+# define PJ_DNS_RESOLVER_MAX_UDP_SIZE 512
+#endif
+
+
+/**
+ * Size of memory pool allocated for each individual DNS response cache.
+ * This value here should be more or less the same as maximum UDP packet
+ * size (PJ_DNS_RESOLVER_MAX_UDP_SIZE), since the DNS replicator function
+ * (#pj_dns_packet_dup()) is also capable of performing name compressions.
+ *
+ * Default: 512 (as a broad guidance, 400 is good for 4 SRV entries).
+ */
+#ifndef PJ_DNS_RESOLVER_RES_BUF_SIZE
+# define PJ_DNS_RESOLVER_RES_BUF_SIZE 512
+#endif
+
+
+
+/**
+ * Opaque data type for DNS resolver object.
+ */
+typedef struct pj_dns_resolver pj_dns_resolver;
+
+/**
+ * Opaque data type for asynchronous DNS query object.
+ */
+typedef struct pj_dns_async_query pj_dns_async_query;
+
+/**
+ * Type of asynchronous callback which will be called when the asynchronous
+ * query completes.
+ *
+ * @param user_data The user data set by application when creating the
+ * asynchronous query.
+ * @param status Status of the DNS resolution.
+ * @param response The response packet received from the server. This
+ * argument may be NULL when status is not PJ_SUCCESS.
+ */
+typedef void pj_dns_callback(void *user_data,
+ pj_status_t status,
+ pj_dns_parsed_packet *response);
+
+
+/**
+ * This structure describes resolver settings.
+ */
+typedef struct pj_dns_settings
+{
+ unsigned options; /**< Options flags. */
+ unsigned qretr_delay; /**< Query retransmit delay in msec. */
+ unsigned qretr_count; /**< Query maximum retransmission count. */
+ unsigned cache_max_ttl; /**< Maximum TTL for cached responses. If the
+ value is zero, caching is disabled. */
+} pj_dns_settings;
+
+
+/**
+ * Create DNS resolver instance. After the resolver is created, application
+ * MUST configure the nameservers with #pj_dns_resolver_set_ns().
+ *
+ * When creating the resolver, application may specify both timer heap
+ * and ioqueue instance, so that it doesn't need to poll the resolver
+ * periodically.
+ *
+ * @param pf Pool factory where the memory pool will be created from.
+ * @param name Optional resolver name to identify the instance in
+ * the log.
+ * @param options Optional options, must be zero for now.
+ * @param timer Optional timer heap instance to be used by the resolver.
+ * If timer heap is not specified, an internal timer will be
+ * created, and application would need to poll the resolver
+ * periodically.
+ * @param ioqueue Optional I/O Queue instance to be used by the resolver.
+ * If ioqueue is not specified, an internal one will be
+ * created, and application would need to poll the resolver
+ * periodically.
+ * @param p_resolver Pointer to receive the resolver instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_create(pj_pool_factory *pf,
+ const char *name,
+ unsigned options,
+ pj_timer_heap_t *timer,
+ pj_ioqueue_t *ioqueue,
+ pj_dns_resolver **p_resolver);
+
+
+/**
+ * Update the name servers for the DNS resolver. The name servers MUST be
+ * configured before any resolution can be done. The order of nameservers
+ * specifies their priority; the first name server will be tried first
+ * before the next in the list.
+ *
+ * @param resolver The resolver instance.
+ * @param count Number of name servers in the array.
+ * @param servers Array of name server IP addresses or hostnames. If
+ * hostname is specified, the hostname must be resolvable
+ * with pj_gethostbyname().
+ * @param ports Optional array of ports. If this argument is NULL,
+ * the nameserver will use default port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_set_ns(pj_dns_resolver *resolver,
+ unsigned count,
+ const pj_str_t servers[],
+ const pj_uint16_t ports[]);
+
+
+/**
+ * Get the resolver current settings.
+ *
+ * @param resolver The resolver instance.
+ * @param st Buffer to be filled up with resolver settings.
+ *
+ * @return The query timeout setting, in seconds.
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_get_settings(pj_dns_resolver *resolver,
+ pj_dns_settings *st);
+
+
+/**
+ * Modify the resolver settings. Application should initialize the settings
+ * by retrieving current settings first before applying new settings, to
+ * ensure that all fields are initialized properly.
+ *
+ * @param resolver The resolver instance.
+ * @param st The resolver settings.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_set_settings(pj_dns_resolver *resolver,
+ const pj_dns_settings *st);
+
+
+/**
+ * Poll for events from the resolver. This function MUST be called
+ * periodically when the resolver is using it's own timer or ioqueue
+ * (in other words, when NULL is specified as either \a timer or
+ * \a ioqueue argument in #pj_dns_resolver_create()).
+ *
+ * @param resolver The resolver instance.
+ * @param timeout Maximum time to wait for event occurence. If this
+ * argument is NULL, this function will wait forever
+ * until events occur.
+ */
+PJ_DECL(void) pj_dns_resolver_handle_events(pj_dns_resolver *resolver,
+ const pj_time_val *timeout);
+
+
+/**
+ * Destroy DNS resolver instance.
+ *
+ * @param resolver The resolver object to be destryed
+ * @param notify If non-zero, all pending asynchronous queries will be
+ * cancelled and its callback will be called. If FALSE,
+ * then no callback will be called.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_destroy(pj_dns_resolver *resolver,
+ pj_bool_t notify);
+
+
+/**
+ * Create and start asynchronous DNS query for a single resource. Depending
+ * on whether response cache is available, this function will either start
+ * an asynchronous DNS query or call the callback immediately.
+ *
+ * If response is not available in the cache, an asynchronous query will be
+ * started, and callback will be called at some time later when the query
+ * completes. If \a p_query argument is not NULL, it will be filled with
+ * the asynchronous query object.
+ *
+ * If response is available in the cache, the callback will be called
+ * immediately before this function returns. In this case, if \a p_query
+ * argument is not NULL, the value will be set to NULL since no new query
+ * is started.
+ *
+ * @param resolver The resolver object.
+ * @param name The name to be resolved.
+ * @param type The type of resource (see #pj_dns_type constants).
+ * @param options Optional options, must be zero for now.
+ * @param cb Callback to be called when the query completes,
+ * either successfully or with failure.
+ * @param user_data Arbitrary user data to be associated with the query,
+ * and which will be given back in the callback.
+ * @param p_query Optional pointer to receive the query object, if one
+ * was started. If this pointer is specified, a NULL may
+ * be returned if response cache is available immediately.
+ *
+ * @return PJ_SUCCESS if either an asynchronous query has been
+ * started successfully or response cache is available and
+ * the user callback has been called.
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_start_query(pj_dns_resolver *resolver,
+ const pj_str_t *name,
+ int type,
+ unsigned options,
+ pj_dns_callback *cb,
+ void *user_data,
+ pj_dns_async_query **p_query);
+
+/**
+ * Cancel a pending query.
+ *
+ * @param query The pending asynchronous query to be cancelled.
+ * @param notify If non-zero, the callback will be called with failure
+ * status to notify that the query has been cancelled.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_cancel_query(pj_dns_async_query *query,
+ pj_bool_t notify);
+
+
+/**
+ * Put the specified DNS packet into DNS cache. This function is mainly used
+ * for testing the resolver, however it can also be used to inject entries
+ * into the resolver.
+ *
+ * The packet MUST contain either answer section or query section so that
+ * it can be indexed.
+ *
+ * @param resolver The resolver instance.
+ * @param pkt DNS packet to be added to the DNS cache. If the packet
+ * matches existing entry, it will update the entry.
+ * @param set_ttl If the value is PJ_FALSE, the entry will not expire
+ * (so use with care). Otherwise cache expiration will be
+ * calculated based on the TTL of the answeres.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_add_entry(pj_dns_resolver *resolver,
+ const pj_dns_parsed_packet *pkt,
+ pj_bool_t set_ttl);
+
+/**
+ * Get the total number of response in the response cache.
+ *
+ * @param resolver The resolver instance.
+ *
+ * @return Current number of entries being stored in the response
+ * cache.
+ */
+PJ_DECL(unsigned) pj_dns_resolver_get_cached_count(pj_dns_resolver *resolver);
+
+
+/**
+ * Dump resolver state to the log.
+ *
+ * @param resolver The resolver instance.
+ * @param detail Will print detailed entries.
+ */
+PJ_DECL(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,
+ pj_bool_t detail);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_RESOLVER_H__ */
+
diff --git a/pjlib-util/src/pjlib-util/dns.c b/pjlib-util/src/pjlib-util/dns.c
index 2afd6a22..e2d3b9f4 100644
--- a/pjlib-util/src/pjlib-util/dns.c
+++ b/pjlib-util/src/pjlib-util/dns.c
@@ -25,13 +25,29 @@
#include <pj/string.h>
+PJ_DEF(const char *) pj_dns_get_type_name(int type)
+{
+ switch (type) {
+ case PJ_DNS_TYPE_A: return "A";
+ case PJ_DNS_TYPE_SRV: return "SRV";
+ case PJ_DNS_TYPE_NS: return "NS";
+ case PJ_DNS_TYPE_CNAME: return "CNAME";
+ case PJ_DNS_TYPE_PTR: return "PTR";
+ case PJ_DNS_TYPE_MX: return "MX";
+ case PJ_DNS_TYPE_TXT: return "TXT";
+ case PJ_DNS_TYPE_NAPTR: return "NAPTR";
+ }
+ return "(Unknown)";
+}
+
+
/**
* Initialize a DNS query transaction.
*/
PJ_DEF(pj_status_t) pj_dns_make_query( void *packet,
unsigned *size,
pj_uint16_t id,
- pj_dns_type qtype,
+ int qtype,
const pj_str_t *name)
{
pj_dns_hdr *hdr;
@@ -224,17 +240,42 @@ static pj_status_t get_name(int rec_counter, const char *pkt,
/* Skip query records. */
-static pj_status_t skip_query(const char *pkt, const char *start,
- const char *max, int *skip_len)
+static pj_status_t parse_query(pj_dns_parsed_query *q, pj_pool_t *pool,
+ const char *pkt, const char *start,
+ const char *max, int *parsed_len)
{
- int name_len = 0;
+ const char *p = start;
+ int name_len, name_part_len;
pj_status_t status;
- status = get_name_len(0, pkt, start, max, skip_len, &name_len);
+ /* Get the length of the name */
+ status = get_name_len(0, pkt, start, max, &name_part_len, &name_len);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Allocate memory for the name */
+ q->name.ptr = pj_pool_alloc(pool, name_len+4);
+ q->name.slen = 0;
+
+ /* Get the name */
+ status = get_name(0, pkt, start, max, &q->name);
if (status != PJ_SUCCESS)
return status;
- (*skip_len) += 4;
+ p = (start + name_part_len);
+
+ /* Get the type */
+ pj_memcpy(&q->type, p, 2);
+ q->type = pj_ntohs(q->type);
+ p += 2;
+
+ /* Get the class */
+ pj_memcpy(&q->dnsclass, p, 2);
+ q->dnsclass = pj_ntohs(q->dnsclass);
+ p += 2;
+
+ *parsed_len = (int)(p - start);
+
return PJ_SUCCESS;
}
@@ -275,12 +316,12 @@ static pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,
p += 2;
/* Get the class */
- pj_memcpy(&rr->class_, p, 2);
- rr->class_ = pj_ntohs(rr->class_);
+ pj_memcpy(&rr->dnsclass, p, 2);
+ rr->dnsclass = pj_ntohs(rr->dnsclass);
p += 2;
/* Class MUST be IN */
- if (rr->class_ != 1)
+ if (rr->dnsclass != 1)
return PJLIB_UTIL_EDNSINCLASS;
/* Get TTL */
@@ -297,10 +338,6 @@ static pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,
if (p + rr->rdlength > max)
return PJLIB_UTIL_EDNSINSIZE;
- /* Copy the raw data */
- rr->data = pj_pool_alloc(pool, rr->rdlength);
- pj_memcpy(rr->data, p, rr->rdlength);
-
/* Parse some well known records */
if (rr->type == PJ_DNS_TYPE_A) {
pj_in_addr ip_addr;
@@ -364,6 +401,10 @@ static pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,
p += name_part_len;
} else {
+ /* Copy the raw data */
+ rr->data = pj_pool_alloc(pool, rr->rdlength);
+ pj_memcpy(rr->data, p, rr->rdlength);
+
p += rr->rdlength;
}
@@ -373,14 +414,14 @@ static pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,
/*
- * Parse raw DNS response packet into DNS response structure.
+ * Parse raw DNS packet into DNS packet structure.
*/
-PJ_DEF(pj_status_t) pj_dns_parse_response( pj_pool_t *pool,
- const void *packet,
- unsigned size,
- pj_dns_parsed_response **p_res)
+PJ_DEF(pj_status_t) pj_dns_parse_packet( pj_pool_t *pool,
+ const void *packet,
+ unsigned size,
+ pj_dns_parsed_packet **p_res)
{
- pj_dns_parsed_response *res;
+ pj_dns_parsed_packet *res;
char *start, *end;
pj_status_t status;
unsigned i;
@@ -392,8 +433,8 @@ PJ_DEF(pj_status_t) pj_dns_parse_response( pj_pool_t *pool,
if (size < sizeof(pj_dns_hdr))
return PJLIB_UTIL_EDNSINSIZE;
- /* Create the response */
- res = pj_pool_zalloc(pool, sizeof(pj_dns_parsed_response));
+ /* Create the structure */
+ res = pj_pool_zalloc(pool, sizeof(pj_dns_parsed_packet));
/* Copy the DNS header, and convert endianness to host byte order */
pj_memcpy(&res->hdr, packet, sizeof(pj_dns_hdr));
@@ -408,17 +449,21 @@ PJ_DEF(pj_status_t) pj_dns_parse_response( pj_pool_t *pool,
start = ((char*)packet) + sizeof(pj_dns_hdr);
end = ((char*)packet) + size;
- /* If we have query records (some DNS servers do send them), skip
- * the records.
+ /* Parse query records (if any).
*/
- for (i=0; i<res->hdr.qdcount; ++i) {
- int skip_len;
-
- status = skip_query(packet, start, end, &skip_len);
- if (status != PJ_SUCCESS)
- return status;
+ if (res->hdr.qdcount) {
+ res->q = pj_pool_zalloc(pool, res->hdr.qdcount *
+ sizeof(pj_dns_parsed_query));
+ for (i=0; i<res->hdr.qdcount; ++i) {
+ int parsed_len;
+
+ status = parse_query(&res->q[i], pool, packet, start, end,
+ &parsed_len);
+ if (status != PJ_SUCCESS)
+ return status;
- start += skip_len;
+ start += parsed_len;
+ }
}
/* Parse answer, if any */
@@ -477,3 +522,155 @@ PJ_DEF(pj_status_t) pj_dns_parse_response( pj_pool_t *pool,
return PJ_SUCCESS;
}
+
+
+/* Perform name compression scheme.
+ * If a name is already in the nametable, when no need to duplicate
+ * the string with the pool, but rather just use the pointer there.
+ */
+static void apply_name_table( unsigned *count,
+ pj_str_t nametable[],
+ const pj_str_t *src,
+ pj_pool_t *pool,
+ pj_str_t *dst)
+{
+ unsigned i;
+
+ /* Scan strings in nametable */
+ for (i=0; i<*count; ++i) {
+ if (pj_stricmp(&nametable[i], src) == 0)
+ break;
+ }
+
+ /* If name is found in nametable, use the pointer in the nametable */
+ if (i != *count) {
+ dst->ptr = nametable[i].ptr;
+ dst->slen = nametable[i].slen;
+ return;
+ }
+
+ /* Otherwise duplicate the string, and insert new name in nametable */
+ pj_strdup(pool, dst, src);
+
+ if (*count < PJ_DNS_MAX_NAMES_IN_NAMETABLE) {
+ nametable[*count].ptr = dst->ptr;
+ nametable[*count].slen = dst->slen;
+
+ ++(*count);
+ }
+}
+
+static void copy_query(pj_pool_t *pool, pj_dns_parsed_query *dst,
+ const pj_dns_parsed_query *src,
+ unsigned *nametable_count,
+ pj_str_t nametable[])
+{
+ pj_memcpy(dst, src, sizeof(*src));
+ apply_name_table(nametable_count, nametable, &src->name, pool, &dst->name);
+}
+
+
+static void copy_rr(pj_pool_t *pool, pj_dns_parsed_rr *dst,
+ const pj_dns_parsed_rr *src,
+ unsigned *nametable_count,
+ pj_str_t nametable[])
+{
+ pj_memcpy(dst, src, sizeof(*src));
+ apply_name_table(nametable_count, nametable, &src->name, pool, &dst->name);
+
+ if (src->data) {
+ dst->data = pj_pool_alloc(pool, src->rdlength);
+ pj_memcpy(dst->data, src->data, src->rdlength);
+ }
+
+ if (src->type == PJ_DNS_TYPE_SRV) {
+ apply_name_table(nametable_count, nametable, &src->rdata.srv.target,
+ pool, &dst->rdata.srv.target);
+ } else if (src->type == PJ_DNS_TYPE_A) {
+ pj_strdup(pool, &dst->rdata.a.ip_addr, &src->rdata.a.ip_addr);
+ } else if (src->type == PJ_DNS_TYPE_CNAME) {
+ pj_strdup(pool, &dst->rdata.cname.name, &src->rdata.cname.name);
+ } else if (src->type == PJ_DNS_TYPE_NS) {
+ pj_strdup(pool, &dst->rdata.ns.name, &src->rdata.ns.name);
+ } else if (src->type == PJ_DNS_TYPE_PTR) {
+ pj_strdup(pool, &dst->rdata.ptr.name, &src->rdata.ptr.name);
+ }
+}
+
+/*
+ * Duplicate DNS packet.
+ */
+PJ_DEF(void) pj_dns_packet_dup(pj_pool_t *pool,
+ const pj_dns_parsed_packet*p,
+ pj_dns_parsed_packet **p_dst)
+{
+ pj_dns_parsed_packet *dst;
+ unsigned nametable_count = 0;
+#if PJ_DNS_MAX_NAMES_IN_NAMETABLE
+ pj_str_t nametable[PJ_DNS_MAX_NAMES_IN_NAMETABLE];
+#else
+ pj_str_t *nametable = NULL;
+#endif
+ unsigned i;
+
+ PJ_ASSERT_ON_FAIL(pool && p && p_dst, return);
+
+ /* Create packet and copy header */
+ *p_dst = dst = pj_pool_zalloc(pool, sizeof(pj_dns_parsed_packet));
+ pj_memcpy(&dst->hdr, &p->hdr, sizeof(p->hdr));
+
+ /* Initialize section counts in the target packet to zero.
+ * If memory allocation fails during copying process, the target packet
+ * should have a correct section counts.
+ */
+ dst->hdr.qdcount = 0;
+ dst->hdr.anscount = 0;
+ dst->hdr.nscount = 0;
+ dst->hdr.arcount = 0;
+
+
+ /* Copy query section */
+ if (p->hdr.qdcount) {
+ dst->q = pj_pool_alloc(pool, p->hdr.qdcount *
+ sizeof(pj_dns_parsed_query));
+ for (i=0; i<p->hdr.qdcount; ++i) {
+ copy_query(pool, &dst->q[i], &p->q[i],
+ &nametable_count, nametable);
+ ++dst->hdr.qdcount;
+ }
+ }
+
+ /* Copy answer section */
+ if (p->hdr.anscount) {
+ dst->ans = pj_pool_alloc(pool, p->hdr.anscount *
+ sizeof(pj_dns_parsed_rr));
+ for (i=0; i<p->hdr.anscount; ++i) {
+ copy_rr(pool, &dst->ans[i], &p->ans[i],
+ &nametable_count, nametable);
+ ++dst->hdr.anscount;
+ }
+ }
+
+ /* Copy NS section */
+ if (p->hdr.nscount) {
+ dst->ns = pj_pool_alloc(pool, p->hdr.nscount *
+ sizeof(pj_dns_parsed_rr));
+ for (i=0; i<p->hdr.nscount; ++i) {
+ copy_rr(pool, &dst->ns[i], &p->ns[i],
+ &nametable_count, nametable);
+ ++dst->hdr.nscount;
+ }
+ }
+
+ /* Copy additional info section */
+ if (p->hdr.arcount) {
+ dst->arr = pj_pool_alloc(pool, p->hdr.arcount *
+ sizeof(pj_dns_parsed_rr));
+ for (i=0; i<p->hdr.arcount; ++i) {
+ copy_rr(pool, &dst->arr[i], &p->arr[i],
+ &nametable_count, nametable);
+ ++dst->hdr.arcount;
+ }
+ }
+}
+
diff --git a/pjlib-util/src/pjlib-util/dns_dump.c b/pjlib-util/src/pjlib-util/dns_dump.c
index 37738c96..31602163 100644
--- a/pjlib-util/src/pjlib-util/dns_dump.c
+++ b/pjlib-util/src/pjlib-util/dns_dump.c
@@ -19,43 +19,93 @@
#include <pjlib-util/dns.h>
#include <pj/assert.h>
#include <pj/log.h>
+#include <pj/string.h>
#define THIS_FILE "dns_dump.c"
#define LEVEL 3
-static const char *get_rr_name(int type)
+static const char *spell_ttl(char *buf, int size, unsigned ttl)
{
- switch (type) {
- case PJ_DNS_TYPE_A: return "A";
- case PJ_DNS_TYPE_NS: return "NS";
- case PJ_DNS_TYPE_CNAME: return "CNAME";
- case PJ_DNS_TYPE_PTR: return "PTR";
- case PJ_DNS_TYPE_MX: return "MX";
- case PJ_DNS_TYPE_TXT: return "TXT";
- case PJ_DNS_TYPE_SRV: return "SRV";
- case PJ_DNS_TYPE_NAPTR: return "NAPTR";
+#define DAY (3600*24)
+#define HOUR (3600)
+#define MINUTE (60)
+
+ char *p = buf;
+ int len;
+
+ if (ttl > DAY) {
+ len = pj_ansi_snprintf(p, size, "%dd ", ttl/DAY);
+ if (len < 1)
+ return "-err-";
+ size -= len;
+ p += len;
+ ttl %= DAY;
}
- return "(Unknown)";
+
+ if (ttl > HOUR) {
+ len = pj_ansi_snprintf(p, size, "%dh ", ttl/HOUR);
+ if (len < 1)
+ return "-err-";
+ size -= len;
+ p += len;
+ ttl %= HOUR;
+ }
+
+ if (ttl > MINUTE) {
+ len = pj_ansi_snprintf(p, size, "%dm ", ttl/MINUTE);
+ if (len < 1)
+ return "-err-";
+ size -= len;
+ p += len;
+ ttl %= MINUTE;
+ }
+
+ if (ttl > 0) {
+ len = pj_ansi_snprintf(p, size, "%ds ", ttl);
+ if (len < 1)
+ return "-err-";
+ size -= len;
+ p += len;
+ ttl = 0;
+ }
+
+ *p = '\0';
+ return buf;
+}
+
+
+static void dump_query(unsigned index, const pj_dns_parsed_query *q)
+{
+ PJ_LOG(3,(THIS_FILE, " %d. Name: %.*s",
+ index, (int)q->name.slen, q->name.ptr));
+ PJ_LOG(3,(THIS_FILE, " Type: %s (%d)",
+ pj_dns_get_type_name(q->type), q->type));
+ PJ_LOG(3,(THIS_FILE, " Class: %s (%d)",
+ (q->dnsclass==1 ? "IN" : "<Unknown>"), q->dnsclass));
}
static void dump_answer(unsigned index, const pj_dns_parsed_rr *rr)
{
const pj_str_t root_name = { "<Root>", 6 };
const pj_str_t *name = &rr->name;
+ char ttl_words[32];
if (name->slen == 0)
name = &root_name;
- PJ_LOG(3,(THIS_FILE, " %d. %s record (type=%d)", index, get_rr_name(rr->type),
+ PJ_LOG(3,(THIS_FILE, " %d. %s record (type=%d)",
+ index, pj_dns_get_type_name(rr->type),
rr->type));
PJ_LOG(3,(THIS_FILE, " Name: %.*s", (int)name->slen, name->ptr));
- PJ_LOG(3,(THIS_FILE, " TTL: %u", rr->ttl));
+ PJ_LOG(3,(THIS_FILE, " TTL: %u (%s)", rr->ttl,
+ spell_ttl(ttl_words, sizeof(ttl_words), rr->ttl)));
PJ_LOG(3,(THIS_FILE, " Data length: %u", rr->rdlength));
if (rr->type == PJ_DNS_TYPE_SRV) {
PJ_LOG(3,(THIS_FILE, " SRV: prio=%d, weight=%d %.*s:%d",
rr->rdata.srv.prio, rr->rdata.srv.weight,
- (int)rr->rdata.srv.target.slen, rr->rdata.srv.target.ptr,
+ (int)rr->rdata.srv.target.slen,
+ rr->rdata.srv.target.ptr,
rr->rdata.srv.port));
} else if (rr->type == PJ_DNS_TYPE_CNAME ||
rr->type == PJ_DNS_TYPE_NS ||
@@ -72,7 +122,7 @@ static void dump_answer(unsigned index, const pj_dns_parsed_rr *rr)
}
-PJ_DEF(void) pj_dns_dump_response(const pj_dns_parsed_response *res)
+PJ_DEF(void) pj_dns_dump_packet(const pj_dns_parsed_packet *res)
{
unsigned i;
@@ -82,18 +132,28 @@ PJ_DEF(void) pj_dns_dump_response(const pj_dns_parsed_response *res)
PJ_LOG(3,(THIS_FILE, "Domain Name System packet (%s):",
(PJ_DNS_GET_QR(res->hdr.flags) ? "response" : "query")));
PJ_LOG(3,(THIS_FILE, " Transaction ID: %d", res->hdr.id));
- PJ_LOG(3,(THIS_FILE, " Flags: type=%s, opcode=%d, authoritative=%d, truncated=%d, rcode=%d",
- (PJ_DNS_GET_QR(res->hdr.flags) ? "response" : "query"),
+ PJ_LOG(3,(THIS_FILE,
+ " Flags: opcode=%d, authoritative=%d, truncated=%d, rcode=%d",
PJ_DNS_GET_OPCODE(res->hdr.flags),
PJ_DNS_GET_AA(res->hdr.flags),
PJ_DNS_GET_TC(res->hdr.flags),
PJ_DNS_GET_RCODE(res->hdr.flags)));
- PJ_LOG(3,(THIS_FILE, " Nb of question RR: %d", res->hdr.qdcount));
+ PJ_LOG(3,(THIS_FILE, " Nb of queries: %d", res->hdr.qdcount));
PJ_LOG(3,(THIS_FILE, " Nb of answer RR: %d", res->hdr.anscount));
PJ_LOG(3,(THIS_FILE, " Nb of authority RR: %d", res->hdr.nscount));
PJ_LOG(3,(THIS_FILE, " Nb of additional RR: %d", res->hdr.arcount));
PJ_LOG(3,(THIS_FILE, ""));
+ /* Dump queries */
+ if (res->hdr.qdcount) {
+ PJ_LOG(3,(THIS_FILE, " Queries:"));
+
+ for (i=0; i<res->hdr.qdcount; ++i) {
+ dump_query(i, &res->q[i]);
+ }
+ PJ_LOG(3,(THIS_FILE, ""));
+ }
+
/* Dump answers */
if (res->hdr.anscount) {
PJ_LOG(3,(THIS_FILE, " Answers RR:"));
diff --git a/pjlib-util/src/pjlib-util/errno.c b/pjlib-util/src/pjlib-util/errno.c
index 4bb652aa..2da114f4 100644
--- a/pjlib-util/src/pjlib-util/errno.c
+++ b/pjlib-util/src/pjlib-util/errno.c
@@ -49,10 +49,25 @@ static const struct
PJ_BUILD_ERR( PJLIB_UTIL_EINXML, "Invalid XML message" ),
/* DNS errors */
- PJ_BUILD_ERR( PJLIB_UTIL_EDNSQRYTOOSMALL, "Outgoing DNS query packet buffer is too small"),
- PJ_BUILD_ERR( PJLIB_UTIL_EDNSINSIZE, "Invalid packet length in DNS response"),
- PJ_BUILD_ERR( PJLIB_UTIL_EDNSINCLASS, "Invalid class in DNS response"),
- PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNAMEPTR, "Invalid name pointer in DNS response"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSQRYTOOSMALL, "DNS query packet buffer is too small"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSINSIZE, "Invalid DNS packet length"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSINCLASS, "Invalid DNS class"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNAMEPTR, "Invalid DNS name pointer"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNSADDR, "Invalid DNS nameserver address"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSNONS, "No nameserver is in DNS resolver"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOWORKINGNS, "No working DNS nameserver"),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOANSWERREC, "No answer record in the DNS response"),
+
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_FORMERR, "DNS \"Format error\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_SERVFAIL, "DNS \"Server failure\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXDOMAIN, "DNS \"Name Error\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTIMPL, "DNS \"Not Implemented\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_REFUSED, "DNS \"Refused\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXDOMAIN, "DNS \"The name exists\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXRRSET, "DNS \"The RRset (name, type) exists\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXRRSET, "DNS \"The RRset (name, type) does not exist\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTAUTH, "DNS \"Not authorized\""),
+ PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTZONE, "DNS \"The zone specified is not a zone\""),
};
#endif /* PJ_HAS_ERROR_STRING */
diff --git a/pjlib-util/src/pjlib-util/resolver.c b/pjlib-util/src/pjlib-util/resolver.c
new file mode 100644
index 00000000..3694c8e1
--- /dev/null
+++ b/pjlib-util/src/pjlib-util/resolver.c
@@ -0,0 +1,1408 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjlib-util/resolver.h>
+#include <pjlib-util/errno.h>
+#include <pj/assert.h>
+#include <pj/ctype.h>
+#include <pj/except.h>
+#include <pj/hash.h>
+#include <pj/ioqueue.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/pool_buf.h>
+#include <pj/string.h>
+#include <pj/sock.h>
+#include <pj/timer.h>
+
+
+#define THIS_FILE "resolver.c"
+
+
+/* Check that maximum DNS nameservers is not too large.
+ * This has got todo with the datatype to index the nameserver in the query.
+ */
+#if PJ_DNS_RESOLVER_MAX_NS > 256
+# error "PJ_DNS_RESOLVER_MAX_NS is too large (max=256)"
+#endif
+
+
+#define RES_HASH_TABLE_SIZE 127 /**< Hash table size (must be 2^n-1 */
+#define PORT 53 /**< Default NS port. */
+#define Q_HASH_TABLE_SIZE 127 /**< Query hash table size */
+#define TIMER_SIZE 127 /**< Initial number of timers. */
+#define MAX_FD 3 /**< Maximum internal sockets. */
+
+#define RES_BUF_SZ PJ_DNS_RESOLVER_RES_BUF_SIZE
+#define UDPSZ PJ_DNS_RESOLVER_MAX_UDP_SIZE
+
+
+/* Nameserver state */
+enum ns_state
+{
+ STATE_PROBING,
+ STATE_ACTIVE,
+ STATE_BAD,
+};
+
+/*
+ * Each nameserver entry.
+ * A name server is identified by its socket address (IP and port).
+ * Each NS will have a flag to indicate whether it's properly functioning.
+ */
+struct nameserver
+{
+ pj_sockaddr_in addr; /**< Server address. */
+
+ enum ns_state state; /**< Nameserver state. */
+ pj_time_val state_expiry; /**< Time set next state. */
+ pj_time_val rt_delay; /**< Response time. */
+
+
+ /* For calculating rt_delay: */
+ pj_uint16_t q_id; /**< Query ID. */
+ pj_time_val sent_time; /**< Time this query is sent. */
+};
+
+
+/* Child query list head
+ * See comments on pj_dns_async_query below.
+ */
+struct query_head
+{
+ PJ_DECL_LIST_MEMBER(pj_dns_async_query);
+};
+
+
+/* Key to look for outstanding query and/or cached response */
+struct res_key
+{
+ pj_uint16_t qtype; /**< Query type. */
+ char name[PJ_MAX_HOSTNAME]; /**< Name being queried */
+};
+
+
+/*
+ * This represents each asynchronous query entry.
+ * This entry will be put in two hash tables, the first one keyed on the DNS
+ * transaction ID to match response with the query, and the second one keyed
+ * on "res_key" structure above to match a new request against outstanding
+ * requests.
+ *
+ * An asynchronous entry may have child entries; child entries are subsequent
+ * queries to the same resource while there is pending query on the same
+ * DNS resource name and type. When a query has child entries, once the
+ * response is received (or error occurs), the response will trigger callback
+ * invocations for all childs entries.
+ *
+ * Note: when application cancels the query, the callback member will be
+ * set to NULL, but for simplicity, the query will be let running.
+ */
+struct pj_dns_async_query
+{
+ PJ_DECL_LIST_MEMBER(pj_dns_async_query); /**< List member. */
+
+ pj_dns_resolver *resolver; /**< The resolver instance. */
+ pj_uint16_t id; /**< Transaction ID. */
+
+ unsigned transmit_cnt; /**< Number of transmissions. */
+
+ struct res_key key; /**< Key to index this query. */
+ char hbufid[PJ_HASH_ENTRY_SIZE]; /**< Hash buffer 1 */
+ char hbufkey[PJ_HASH_ENTRY_SIZE]; /**< Hash buffer 2 */
+ pj_timer_entry timer_entry; /**< Timer to manage timeouts */
+ unsigned options; /**< Query options. */
+ void *user_data; /**< Application data. */
+ pj_dns_callback *cb; /**< Callback to be called. */
+ struct query_head child_head; /**< Child queries list head. */
+};
+
+
+/* This structure is used to keep cached response entry.
+ * The cache is a hash table keyed on "res_key" structure above.
+ */
+struct cached_res
+{
+ PJ_DECL_LIST_MEMBER(struct cached_res);
+
+ struct res_key key; /**< Resource key. */
+ char buf[RES_BUF_SZ];/**< Resource buffer. */
+ char hbuf[PJ_HASH_ENTRY_SIZE]; /**< Hash buffer */
+ pj_time_val expiry_time; /**< Expiration time. */
+ pj_dns_parsed_packet *pkt; /**< The response packet. */
+};
+
+
+/* Resolver entry */
+struct pj_dns_resolver
+{
+ pj_str_t name; /**< Resolver instance name for id. */
+
+ /* Internals */
+ pj_pool_t *pool; /**< Internal pool. */
+ pj_mutex_t *mutex; /**< Mutex protection. */
+ pj_bool_t own_timer; /**< Do we own timer? */
+ pj_timer_heap_t *timer; /**< Timer instance. */
+ pj_bool_t own_ioqueue; /**< Do we own ioqueue? */
+ pj_ioqueue_t *ioqueue; /**< Ioqueue instance. */
+ char tmp_pool[1500];/**< Temporary pool buffer. */
+
+ /* Socket */
+ pj_sock_t udp_sock; /**< UDP socket. */
+ pj_ioqueue_key_t *udp_key; /**< UDP socket ioqueue key. */
+ unsigned char udp_rx_pkt[UDPSZ];/**< UDP receive buffer. */
+ unsigned char udp_tx_pkt[UDPSZ];/**< UDP receive buffer. */
+ pj_ssize_t udp_len; /**< Length of received packet. */
+ pj_ioqueue_op_key_t udp_op_key; /**< UDP read operation key. */
+ pj_sockaddr_in udp_src_addr; /**< Source address of packet */
+ int udp_addr_len; /**< Source address length. */
+
+ /* Settings */
+ pj_dns_settings settings; /**< Resolver settings. */
+
+ /* Nameservers */
+ unsigned ns_count; /**< Number of name servers. */
+ struct nameserver ns[PJ_DNS_RESOLVER_MAX_NS]; /**< Array of NS. */
+
+ /* Last DNS transaction ID used. */
+ pj_uint16_t last_id;
+
+ /* Hash table for cached response */
+ pj_hash_table_t *hrescache; /**< Cached response in hash table */
+
+ /* Cached response free list */
+ struct cached_res res_free_nodes;
+
+ /* Pending asynchronous query, hashed by transaction ID. */
+ pj_hash_table_t *hquerybyid;
+
+ /* Pending asynchronous query, hashed by "res_key" */
+ pj_hash_table_t *hquerybyres;
+
+ /* Query entries free list */
+ struct query_head query_free_nodes;
+};
+
+
+/* Callback from ioqueue when packet is received */
+static void on_read_complete(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_read);
+
+/* Callback to be called when query has timed out */
+static void on_timeout( pj_timer_heap_t *timer_heap,
+ struct pj_timer_entry *entry);
+
+/* Select which nameserver to use */
+static pj_status_t select_nameservers(pj_dns_resolver *resolver,
+ unsigned *count,
+ unsigned servers[]);
+
+
+/*
+ * Create the resolver.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_create( pj_pool_factory *pf,
+ const char *name,
+ unsigned options,
+ pj_timer_heap_t *timer,
+ pj_ioqueue_t *ioqueue,
+ pj_dns_resolver **p_resolver)
+{
+ pj_pool_t *pool;
+ pj_dns_resolver *resv;
+ pj_ioqueue_callback socket_cb;
+ pj_status_t status;
+
+ /* Sanity check */
+ PJ_ASSERT_RETURN(pf && p_resolver, PJ_EINVAL);
+
+ if (name == NULL)
+ name = THIS_FILE;
+
+ /* Create and initialize resolver instance */
+ pool = pj_pool_create(pf, name, 4000, 4000, NULL);
+ if (!pool)
+ return PJ_ENOMEM;
+
+ /* Create pool and name */
+ resv = pj_pool_zalloc(pool, sizeof(struct pj_dns_resolver));
+ resv->pool = pool;
+ resv->udp_sock = PJ_INVALID_SOCKET;
+ pj_strdup2_with_null(pool, &resv->name, name);
+
+ /* Create the mutex */
+ status = pj_mutex_create_recursive(pool, name, &resv->mutex);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Timer, ioqueue, and settings */
+ resv->timer = timer;
+ resv->ioqueue = ioqueue;
+ resv->last_id = 1;
+ resv->settings.options = options;
+ resv->settings.qretr_delay = PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY;
+ resv->settings.qretr_count = PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT;
+ resv->settings.cache_max_ttl = PJ_DNS_RESOLVER_MAX_TTL;
+
+ /* Create the timer heap if one is not specified */
+ if (resv->timer == NULL) {
+ status = pj_timer_heap_create(pool, TIMER_SIZE, &resv->timer);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ /* Create the ioqueue if one is not specified */
+ if (resv->ioqueue == NULL) {
+ status = pj_ioqueue_create(pool, MAX_FD, &resv->ioqueue);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ /* Response cache hash table and item list */
+ resv->hrescache = pj_hash_create(pool, RES_HASH_TABLE_SIZE);
+ pj_list_init(&resv->res_free_nodes);
+
+ /* Query hash table and free list. */
+ resv->hquerybyid = pj_hash_create(pool, Q_HASH_TABLE_SIZE);
+ resv->hquerybyres = pj_hash_create(pool, Q_HASH_TABLE_SIZE);
+ pj_list_init(&resv->query_free_nodes);
+
+ /* Create the UDP socket */
+ status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &resv->udp_sock);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Register to ioqueue */
+ pj_bzero(&socket_cb, sizeof(socket_cb));
+ socket_cb.on_read_complete = &on_read_complete;
+ status = pj_ioqueue_register_sock(pool, resv->ioqueue, resv->udp_sock,
+ resv, &socket_cb, &resv->udp_key);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ pj_ioqueue_op_key_init(&resv->udp_op_key, sizeof(resv->udp_op_key));
+
+ /* Start asynchronous read to the UDP socket */
+ resv->udp_len = sizeof(resv->udp_rx_pkt);
+ resv->udp_addr_len = sizeof(resv->udp_src_addr);
+ status = pj_ioqueue_recvfrom(resv->udp_key, &resv->udp_op_key,
+ resv->udp_rx_pkt, &resv->udp_len,
+ PJ_IOQUEUE_ALWAYS_ASYNC,
+ &resv->udp_src_addr, &resv->udp_addr_len);
+ if (status != PJ_EPENDING)
+ goto on_error;
+
+
+ /* Looks like everything is okay */
+ *p_resolver = resv;
+ return PJ_SUCCESS;
+
+on_error:
+ pj_dns_resolver_destroy(resv, PJ_FALSE);
+ return status;
+}
+
+
+/*
+ * Destroy DNS resolver instance.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_destroy( pj_dns_resolver *resolver,
+ pj_bool_t notify)
+{
+ PJ_ASSERT_RETURN(resolver, PJ_EINVAL);
+
+ if (notify) {
+ /*
+ * Notify pending queries if requested.
+ */
+ pj_hash_iterator_t it_buf, *it;
+
+ it = pj_hash_first(resolver->hquerybyid, &it_buf);
+ while (it) {
+ pj_dns_async_query *q = pj_hash_this(resolver->hquerybyid, it);
+ pj_dns_async_query *cq;
+ if (q->cb)
+ (*q->cb)(q->user_data, PJ_ECANCELLED, NULL);
+
+ cq = q->child_head.next;
+ while (cq != (pj_dns_async_query*)&q->child_head) {
+ if (cq->cb)
+ (*cq->cb)(cq->user_data, PJ_ECANCELLED, NULL);
+ cq = cq->next;
+ }
+ it = pj_hash_next(resolver->hquerybyid, it);
+ }
+ }
+
+ if (resolver->own_timer && resolver->timer) {
+ pj_timer_heap_destroy(resolver->timer);
+ resolver->timer = NULL;
+ }
+
+ if (resolver->own_ioqueue && resolver->ioqueue) {
+ pj_ioqueue_destroy(resolver->ioqueue);
+ resolver->ioqueue = NULL;
+ }
+
+ if (resolver->udp_key != NULL) {
+ pj_ioqueue_unregister(resolver->udp_key);
+ resolver->udp_key = NULL;
+ resolver->udp_sock = PJ_INVALID_SOCKET;
+ } else if (resolver->udp_sock != PJ_INVALID_SOCKET) {
+ pj_sock_close(resolver->udp_sock);
+ resolver->udp_sock = PJ_INVALID_SOCKET;
+ }
+
+ if (resolver->mutex) {
+ pj_mutex_destroy(resolver->mutex);
+ resolver->mutex = NULL;
+ }
+
+ if (resolver->pool) {
+ pj_pool_t *pool = resolver->pool;
+ resolver->pool = NULL;
+ pj_pool_release(pool);
+ }
+ return PJ_SUCCESS;
+}
+
+
+
+/*
+ * Configure name servers for the DNS resolver.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_set_ns( pj_dns_resolver *resolver,
+ unsigned count,
+ const pj_str_t servers[],
+ const pj_uint16_t ports[])
+{
+ unsigned i;
+ pj_time_val now;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(resolver && count && servers, PJ_EINVAL);
+
+ pj_mutex_lock(resolver->mutex);
+
+ if (count > PJ_DNS_RESOLVER_MAX_NS)
+ count = PJ_DNS_RESOLVER_MAX_NS;
+
+ resolver->ns_count = 0;
+ pj_bzero(resolver->ns, sizeof(resolver->ns));
+
+ pj_gettimeofday(&now);
+
+ for (i=0; i<count; ++i) {
+ struct nameserver *ns = &resolver->ns[i];
+
+ status = pj_sockaddr_in_init(&ns->addr, &servers[i],
+ (pj_uint16_t)(ports ? ports[i] : PORT));
+ if (status != PJ_SUCCESS) {
+ pj_mutex_unlock(resolver->mutex);
+ return PJLIB_UTIL_EDNSINNSADDR;
+ }
+
+ ns->state = STATE_ACTIVE;
+ ns->state_expiry = now;
+ ns->rt_delay.sec = 10;
+ }
+
+ resolver->ns_count = count;
+
+ pj_mutex_unlock(resolver->mutex);
+ return PJ_SUCCESS;
+}
+
+
+
+/*
+ * Modify the resolver settings.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_set_settings(pj_dns_resolver *resolver,
+ const pj_dns_settings *st)
+{
+ PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL);
+
+ pj_mutex_lock(resolver->mutex);
+ pj_memcpy(&resolver->settings, st, sizeof(*st));
+ pj_mutex_unlock(resolver->mutex);
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get the resolver current settings.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_get_settings( pj_dns_resolver *resolver,
+ pj_dns_settings *st)
+{
+ PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL);
+
+ pj_mutex_lock(resolver->mutex);
+ pj_memcpy(st, &resolver->settings, sizeof(*st));
+ pj_mutex_unlock(resolver->mutex);
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Poll for events from the resolver.
+ */
+PJ_DEF(void) pj_dns_resolver_handle_events(pj_dns_resolver *resolver,
+ const pj_time_val *timeout)
+{
+ PJ_ASSERT_ON_FAIL(resolver, return);
+
+ pj_mutex_lock(resolver->mutex);
+ pj_timer_heap_poll(resolver->timer, NULL);
+ pj_mutex_unlock(resolver->mutex);
+
+ pj_ioqueue_poll(resolver->ioqueue, timeout);
+}
+
+
+/* Get one query node from the free node, if any, or allocate
+ * a new one.
+ */
+static pj_dns_async_query *alloc_qnode(pj_dns_resolver *resolver,
+ unsigned options,
+ void *user_data,
+ pj_dns_callback *cb)
+{
+ pj_dns_async_query *q;
+
+ /* Merge query options with resolver options */
+ options |= resolver->settings.options;
+
+ if (!pj_list_empty(&resolver->query_free_nodes)) {
+ q = resolver->query_free_nodes.next;
+ pj_list_erase(q);
+ pj_bzero(q, sizeof(*q));
+ } else {
+ q = pj_pool_zalloc(resolver->pool, sizeof(*q));
+ }
+
+ /* Init query */
+ q->resolver = resolver;
+ q->options = options;
+ q->user_data = user_data;
+ q->cb = cb;
+ pj_list_init(&q->child_head);
+
+ return q;
+}
+
+
+/*
+ * Transmit query.
+ */
+static pj_status_t transmit_query(pj_dns_resolver *resolver,
+ pj_dns_async_query *q)
+{
+ unsigned pkt_size;
+ unsigned i, server_cnt;
+ unsigned servers[PJ_DNS_RESOLVER_MAX_NS];
+ pj_time_val now;
+ pj_str_t name;
+ pj_time_val delay;
+ pj_status_t status;
+
+ /* Create DNS query packet */
+ pkt_size = sizeof(resolver->udp_tx_pkt);
+ name = pj_str(q->key.name);
+ status = pj_dns_make_query(resolver->udp_tx_pkt, &pkt_size,
+ q->id, q->key.qtype, &name);
+ if (status != PJ_SUCCESS) {
+ return status;
+ }
+
+ /* Select which nameserver(s) to send requests to. */
+ server_cnt = PJ_ARRAY_SIZE(servers);
+ status = select_nameservers(resolver, &server_cnt, servers);
+ if (status != PJ_SUCCESS) {
+ return status;
+ }
+
+ if (server_cnt == 0) {
+ return PJLIB_UTIL_EDNSNOWORKINGNS;
+ }
+
+ /* Start retransmit/timeout timer for the query */
+ pj_assert(q->timer_entry.id == 0);
+ q->timer_entry.id = 1;
+ q->timer_entry.user_data = q;
+ q->timer_entry.cb = &on_timeout;
+
+ delay.sec = 0;
+ delay.msec = resolver->settings.qretr_delay;
+ pj_time_val_normalize(&delay);
+ status = pj_timer_heap_schedule(resolver->timer, &q->timer_entry, &delay);
+ if (status != PJ_SUCCESS) {
+ return status;
+ }
+
+ /* Get current time. */
+ pj_gettimeofday(&now);
+
+ /* Send the packet to name servers */
+ for (i=0; i<server_cnt; ++i) {
+ pj_ssize_t sent = (pj_ssize_t) pkt_size;
+ struct nameserver *ns = &resolver->ns[servers[i]];
+
+ pj_sock_sendto(resolver->udp_sock, resolver->udp_tx_pkt, &sent, 0,
+ &resolver->ns[servers[i]].addr, sizeof(pj_sockaddr_in));
+
+ PJ_LOG(4,(resolver->name.ptr,
+ "%s %d bytes to NS %d (%s:%d): DNS %s query for %s",
+ (q->transmit_cnt==0? "Transmitting":"Re-transmitting"),
+ (int)sent, servers[i],
+ pj_inet_ntoa(ns->addr.sin_addr),
+ (int)pj_ntohs(ns->addr.sin_port),
+ pj_dns_get_type_name(q->key.qtype),
+ q->key.name));
+
+ if (ns->q_id == 0) {
+ ns->q_id = q->id;
+ ns->sent_time = now;
+ }
+ }
+
+ ++q->transmit_cnt;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Initialize resource key for hash table lookup.
+ */
+static void init_res_key(struct res_key *key, int type, const pj_str_t *name)
+{
+ unsigned i, len;
+ char *dst = key->name;
+ const char *src = name->ptr;
+
+ pj_bzero(key, sizeof(struct res_key));
+ key->qtype = (pj_uint16_t)type;
+
+ len = name->slen;
+ if (len > PJ_MAX_HOSTNAME) len = PJ_MAX_HOSTNAME;
+
+ /* Copy key, in lowercase */
+ for (i=0; i<len; ++i) {
+ *dst++ = (char)pj_tolower(*src++);
+ }
+}
+
+
+/*
+ * Create and start asynchronous DNS query for a single resource.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_start_query( pj_dns_resolver *resolver,
+ const pj_str_t *name,
+ int type,
+ unsigned options,
+ pj_dns_callback *cb,
+ void *user_data,
+ pj_dns_async_query **p_query)
+{
+ pj_time_val now;
+ struct res_key key;
+ struct cached_res *cache;
+ pj_dns_async_query *q;
+ pj_uint32_t hval;
+ pj_status_t status = PJ_SUCCESS;
+
+ /* Validate arguments */
+ PJ_ASSERT_RETURN(resolver && name && type, PJ_EINVAL);
+
+ /* Check name is not too long. */
+ PJ_ASSERT_RETURN(name->slen>0 && name->slen < PJ_MAX_HOSTNAME,
+ PJ_ENAMETOOLONG);
+
+ /* Check type */
+ PJ_ASSERT_RETURN(type > 0 && type < 0xFFFF, PJ_EINVAL);
+
+ if (p_query)
+ *p_query = NULL;
+
+ /* Build resource key for looking up hash tables */
+ init_res_key(&key, type, name);
+
+ /* Start working with the resolver */
+ pj_mutex_lock(resolver->mutex);
+
+ /* Get current time. */
+ pj_gettimeofday(&now);
+
+ /* First, check if we have cached response for the specified name/type,
+ * and the cached entry has not expired.
+ */
+ hval = 0;
+ cache = pj_hash_get(resolver->hrescache, &key, sizeof(key), &hval);
+ if (cache) {
+ /* We've found a cached entry. */
+
+ /* Check for expiration */
+ if (PJ_TIME_VAL_GT(cache->expiry_time, now)) {
+
+ /* Log */
+ PJ_LOG(5,(resolver->name.ptr,
+ "Picked up DNS %s record for %.*s in cache",
+ pj_dns_get_type_name(type),
+ (int)name->slen, name->ptr));
+
+ /* Map DNS Rcode in the response into PJLIB status name space */
+ status = PJ_DNS_GET_RCODE(cache->pkt->hdr.flags);
+ status = PJ_STATUS_FROM_DNS_RCODE(status);
+
+ /* This cached response is still valid. Just return this
+ * response to caller.
+ */
+ if (cb) {
+ (*cb)(user_data, status, cache->pkt);
+ }
+
+ /* Done. No host resolution is necessary */
+
+ /* Must return PJ_SUCCESS */
+ status = PJ_SUCCESS;
+
+ goto on_return;
+ }
+
+ /* At this point, we have a cached entry, but this entry has expired.
+ * Remove this entry from the cached list.
+ */
+ pj_hash_set(NULL, resolver->hrescache, &key, sizeof(key), 0, NULL);
+
+ /* Store the entry into free nodes */
+ pj_list_push_back(&resolver->res_free_nodes, cache);
+
+ /* Must continue with creating a query now */
+ }
+
+ /* Next, check if we have pending query on the same resource */
+ q = pj_hash_get(resolver->hquerybyres, &key, sizeof(key), NULL);
+ if (q) {
+ /* Yes, there's another pending query to the same key.
+ * Just create a new child query and add this query to
+ * pending query's child queries.
+ */
+ pj_dns_async_query *nq;
+
+ nq = alloc_qnode(resolver, options, user_data, cb);
+ pj_list_push_back(&q->child_head, nq);
+
+ /* Done. This child query will be notified once the "parent"
+ * query completes.
+ */
+ status = PJ_SUCCESS;
+ goto on_return;
+ }
+
+ /* There's no pending query to the same key, initiate a new one. */
+ q = alloc_qnode(resolver, options, user_data, cb);
+
+ /* Save the ID and key */
+ q->id = resolver->last_id++;
+ if (resolver->last_id == 0)
+ resolver->last_id = 1;
+ pj_memcpy(&q->key, &key, sizeof(struct res_key));
+
+ /* Send the query */
+ status = transmit_query(resolver, q);
+ if (status != PJ_SUCCESS) {
+ pj_list_push_back(&resolver->query_free_nodes, q);
+ goto on_return;
+ }
+
+ /* Add query entry to the hash tables */
+ pj_hash_set_np(resolver->hquerybyid, &q->id, sizeof(q->id),
+ 0, q->hbufid, q);
+ pj_hash_set_np(resolver->hquerybyres, &q->key, sizeof(q->key),
+ 0, q->hbufkey, q);
+
+ if (p_query)
+ *p_query = q;
+
+on_return:
+ pj_mutex_unlock(resolver->mutex);
+ return status;
+}
+
+
+/*
+ * Cancel a pending query.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_cancel_query(pj_dns_async_query *query,
+ pj_bool_t notify)
+{
+ pj_dns_callback *cb;
+
+ PJ_ASSERT_RETURN(query, PJ_EINVAL);
+
+ pj_mutex_lock(query->resolver->mutex);
+
+ cb = query->cb;
+ query->cb = NULL;
+
+ if (notify)
+ (*cb)(query->user_data, PJ_ECANCELLED, NULL);
+
+ pj_mutex_unlock(query->resolver->mutex);
+ return PJ_SUCCESS;
+}
+
+
+
+/* Set nameserver state */
+static void set_nameserver_state(pj_dns_resolver *resolver,
+ unsigned index,
+ enum ns_state state,
+ const pj_time_val *now)
+{
+ struct nameserver *ns = &resolver->ns[index];
+
+ ns->state = state;
+ ns->state_expiry = *now;
+
+ if (state == STATE_PROBING)
+ ns->state_expiry.sec += ((PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT + 2) *
+ PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY) / 1000;
+ else if (state == STATE_ACTIVE)
+ ns->state_expiry.sec += PJ_DNS_RESOLVER_GOOD_NS_TTL;
+ else
+ ns->state_expiry.sec += PJ_DNS_RESOLVER_BAD_NS_TTL;
+
+}
+
+
+/* Select which nameserver(s) to use. Note this may return multiple
+ * name servers. The algorithm to select which nameservers to be
+ * sent the request to is as follows:
+ * - select the first nameserver that is known to be good for the
+ * last PJ_DNS_RESOLVER_GOOD_NS_TTL interval.
+ * - for all NSes, if last_known_good >= PJ_DNS_RESOLVER_GOOD_NS_TTL,
+ * include the NS to re-check again that the server is still good,
+ * unless the NS is known to be bad in the last PJ_DNS_RESOLVER_BAD_NS_TTL
+ * interval.
+ * - for all NSes, if last_known_bad >= PJ_DNS_RESOLVER_BAD_NS_TTL,
+ * also include the NS to re-check again that the server is still bad.
+ */
+static pj_status_t select_nameservers(pj_dns_resolver *resolver,
+ unsigned *count,
+ unsigned servers[])
+{
+ unsigned i, max_count=*count;
+ int min;
+ pj_time_val now;
+
+ pj_assert(max_count > 0);
+
+ *count = 0;
+ servers[0] = 0xFFFF;
+
+ /* Check that nameservers are configured. */
+ if (resolver->ns_count == 0)
+ return PJLIB_UTIL_EDNSNONS;
+
+ pj_gettimeofday(&now);
+
+ /* Select one Active nameserver with best response time. */
+ for (min=-1, i=0; i<resolver->ns_count; ++i) {
+ struct nameserver *ns = &resolver->ns[i];
+
+ if (ns->state != STATE_ACTIVE)
+ continue;
+
+ if (min == -1)
+ min = i;
+ else if (PJ_TIME_VAL_LT(ns->rt_delay, resolver->ns[min].rt_delay))
+ min = i;
+ }
+ if (min != -1) {
+ servers[0] = min;
+ ++(*count);
+ }
+
+ /* Scan nameservers. */
+ for (i=0; i<resolver->ns_count && *count < max_count; ++i) {
+ struct nameserver *ns = &resolver->ns[i];
+
+ if (PJ_TIME_VAL_LTE(ns->state_expiry, now)) {
+ if (ns->state == STATE_PROBING) {
+ set_nameserver_state(resolver, i, STATE_BAD, &now);
+ } else {
+ set_nameserver_state(resolver, i, STATE_PROBING, &now);
+ if ((int)i != min) {
+ servers[*count] = i;
+ ++(*count);
+ }
+ }
+ } else if (ns->state == STATE_PROBING && (int)i != min) {
+ servers[*count] = i;
+ ++(*count);
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/* Update name server status */
+static void report_nameserver_status(pj_dns_resolver *resolver,
+ const pj_sockaddr_in *ns_addr,
+ const pj_dns_parsed_packet *pkt)
+{
+ unsigned i;
+ int rcode;
+ pj_uint32_t q_id;
+ pj_time_val now;
+ pj_bool_t is_good;
+
+ /* Only mark nameserver as "bad" if it returned non-parseable response or
+ * it returned the following status codes
+ */
+ if (pkt) {
+ rcode = PJ_DNS_GET_RCODE(pkt->hdr.flags);
+ q_id = pkt->hdr.id;
+ } else {
+ rcode = 0;
+ q_id = (pj_uint32_t)-1;
+ }
+
+ if (!pkt || rcode == PJ_DNS_RCODE_SERVFAIL ||
+ rcode == PJ_DNS_RCODE_REFUSED ||
+ rcode == PJ_DNS_RCODE_NOTAUTH)
+ {
+ is_good = PJ_FALSE;
+ } else {
+ is_good = PJ_TRUE;
+ }
+
+
+ /* Mark time */
+ pj_gettimeofday(&now);
+
+ /* Recheck all nameservers. */
+ for (i=0; i<resolver->ns_count; ++i) {
+ struct nameserver *ns = &resolver->ns[i];
+
+ if (ns->addr.sin_addr.s_addr == ns_addr->sin_addr.s_addr &&
+ ns->addr.sin_port == ns_addr->sin_port &&
+ ns->addr.sin_family == ns_addr->sin_family)
+ {
+ if (q_id == ns->q_id) {
+ /* Calculate response time */
+ pj_time_val rt = now;
+ PJ_TIME_VAL_SUB(rt, ns->sent_time);
+ ns->rt_delay = rt;
+ ns->q_id = 0;
+ }
+ set_nameserver_state(resolver, i,
+ (is_good ? STATE_ACTIVE : STATE_BAD), &now);
+ break;
+ }
+ }
+}
+
+
+/* Update response cache */
+static void update_res_cache(pj_dns_resolver *resolver,
+ const struct res_key *key,
+ pj_status_t status,
+ pj_bool_t set_expiry,
+ const pj_dns_parsed_packet *pkt)
+{
+ struct cached_res *cache;
+ pj_pool_t *res_pool;
+ pj_uint32_t hval=0, ttl;
+ PJ_USE_EXCEPTION;
+
+ /* If status is unsuccessful, clear the same entry from the cache */
+ if (status != PJ_SUCCESS) {
+ cache = pj_hash_get(resolver->hrescache, key, sizeof(*key), &hval);
+ if (cache)
+ pj_list_push_back(&resolver->res_free_nodes, cache);
+ pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL);
+ }
+
+
+ /* Calculate expiration time. */
+ if (set_expiry) {
+ if (pkt->hdr.anscount == 0) {
+ /* If we don't have answers for the name, then give a different
+ * ttl value (note: PJ_DNS_RESOLVER_INVALID_TTL may be zero,
+ * which means that invalid names won't be kept in the cache)
+ */
+ ttl = PJ_DNS_RESOLVER_INVALID_TTL;
+
+ } else {
+ /* Otherwise get the minimum TTL from the answers */
+ unsigned i;
+ ttl = 0xFFFFFFFF;
+ for (i=0; i<pkt->hdr.anscount; ++i) {
+ if (pkt->ans[i].ttl < ttl)
+ ttl = pkt->ans[i].ttl;
+ }
+ }
+ } else {
+ ttl = 0xFFFFFFFF;
+ }
+
+ /* Apply maximum TTL */
+ if (ttl > resolver->settings.cache_max_ttl)
+ ttl = resolver->settings.cache_max_ttl;
+
+ /* If TTL is zero, clear the same entry in the hash table */
+ if (ttl == 0) {
+ cache = pj_hash_get(resolver->hrescache, key, sizeof(*key), &hval);
+ if (cache)
+ pj_list_push_back(&resolver->res_free_nodes, cache);
+ pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL);
+ return;
+ }
+
+ /* Get a cache response entry */
+ cache = pj_hash_get(resolver->hrescache, key, sizeof(*key), &hval);
+ if (cache == NULL) {
+ if (!pj_list_empty(&resolver->res_free_nodes)) {
+ cache = resolver->res_free_nodes.next;
+ pj_list_erase(cache);
+ } else {
+ cache = pj_pool_zalloc(resolver->pool, sizeof(*cache));
+ }
+ }
+
+ /* Duplicate the packet */
+ res_pool = pj_pool_create_on_buf("respool", cache->buf, sizeof(cache->buf));
+ PJ_TRY {
+ cache->pkt = NULL;
+ pj_dns_packet_dup(res_pool, pkt, &cache->pkt);
+ }
+ PJ_CATCH_ANY {
+ PJ_LOG(1,(THIS_FILE,
+ "Not enough memory to duplicate DNS response. Response was "
+ "truncated."));
+ }
+ PJ_END;
+
+ /* Calculate expiration time */
+ if (set_expiry) {
+ pj_gettimeofday(&cache->expiry_time);
+ cache->expiry_time.sec += ttl;
+ } else {
+ cache->expiry_time.sec = 0x7FFFFFFFL;
+ cache->expiry_time.msec = 0;
+ }
+
+ /* Copy key to the cached response */
+ pj_memcpy(&cache->key, key, sizeof(*key));
+
+ /* Update the hash table */
+ pj_hash_set_np(resolver->hrescache, &cache->key, sizeof(*key), hval,
+ cache->hbuf, cache);
+}
+
+
+/* Callback to be called when query has timed out */
+static void on_timeout( pj_timer_heap_t *timer_heap,
+ struct pj_timer_entry *entry)
+{
+ pj_dns_resolver *resolver;
+ pj_dns_async_query *q, *cq;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(timer_heap);
+
+ q = entry->user_data;
+ resolver = q->resolver;
+
+ pj_mutex_lock(resolver->mutex);
+
+ /* Recheck that this query is still pending, since there is a slight
+ * possibility of race condition (timer elapsed while at the same time
+ * response arrives)
+ */
+ if (pj_hash_get(resolver->hquerybyid, &q->id, sizeof(q->id), NULL)==NULL) {
+ /* Yeah, this query is done. */
+ pj_mutex_unlock(resolver->mutex);
+ return;
+ }
+
+ /* Invalidate id. */
+ q->timer_entry.id = 0;
+
+ /* Check to see if we should retransmit instead of time out */
+ if (q->transmit_cnt < PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT) {
+ status = transmit_query(resolver, q);
+ if (status == PJ_SUCCESS) {
+ pj_mutex_unlock(resolver->mutex);
+ return;
+ } else {
+ /* Error occurs */
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(4,(resolver->name.ptr,
+ "Error transmitting request: %s", errmsg));
+
+ /* Let it fallback to timeout section below */
+ }
+ }
+
+ /* Clear hash table entries */
+ pj_hash_set(NULL, resolver->hquerybyid, &q->id, sizeof(q->id), 0, NULL);
+ pj_hash_set(NULL, resolver->hquerybyres, &q->key, sizeof(q->key), 0, NULL);
+
+ /* Call application callback, if any. */
+ if (q->cb)
+ (*q->cb)(q->user_data, PJ_ETIMEDOUT, NULL);
+
+ /* Call application callback for child queries. */
+ cq = q->child_head.next;
+ while (cq != (void*)&q->child_head) {
+ if (cq->cb)
+ (*cq->cb)(cq->user_data, PJ_ETIMEDOUT, NULL);
+ cq = cq->next;
+ }
+
+ /* Clear data */
+ q->timer_entry.id = 0;
+ q->user_data = NULL;
+
+ /* Put child entries into recycle list */
+ cq = q->child_head.next;
+ while (cq != (void*)&q->child_head) {
+ pj_dns_async_query *next = cq->next;
+ pj_list_push_back(&resolver->query_free_nodes, cq);
+ cq = next;
+ }
+
+ /* Put query entry into recycle list */
+ pj_list_push_back(&resolver->query_free_nodes, q);
+
+ pj_mutex_unlock(resolver->mutex);
+}
+
+
+/* Callback from ioqueue when packet is received */
+static void on_read_complete(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_read)
+{
+ pj_dns_resolver *resolver;
+ pj_pool_t *pool;
+ pj_dns_parsed_packet *dns_pkt;
+ pj_dns_async_query *q;
+ pj_status_t status;
+ PJ_USE_EXCEPTION;
+
+
+ resolver = pj_ioqueue_get_user_data(key);
+ pj_mutex_lock(resolver->mutex);
+
+
+ /* Check for errors */
+ if (bytes_read < 0) {
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ status = -bytes_read;
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(4,(resolver->name.ptr,
+ "DNS resolver read error from %s:%d: %s",
+ pj_inet_ntoa(resolver->udp_src_addr.sin_addr),
+ pj_ntohs(resolver->udp_src_addr.sin_port),
+ errmsg));
+
+ goto read_next_packet;
+ }
+
+ PJ_LOG(5,(resolver->name.ptr,
+ "Received %d bytes DNS response from %s:%d",
+ (int)bytes_read,
+ pj_inet_ntoa(resolver->udp_src_addr.sin_addr),
+ pj_ntohs(resolver->udp_src_addr.sin_port)));
+
+
+ /* Check for zero packet */
+ if (bytes_read == 0)
+ goto read_next_packet;
+
+ /* Create temporary pool from a fixed buffer */
+ pool = pj_pool_create_on_buf("restmp", resolver->tmp_pool,
+ sizeof(resolver->tmp_pool));
+
+ /* Parse DNS response */
+ status = -1;
+ dns_pkt = NULL;
+ PJ_TRY {
+ status = pj_dns_parse_packet(pool, resolver->udp_rx_pkt,
+ (unsigned)bytes_read, &dns_pkt);
+ }
+ PJ_CATCH_ANY {
+ status = PJ_ENOMEM;
+ }
+ PJ_END;
+
+ /* Update nameserver status */
+ report_nameserver_status(resolver, &resolver->udp_src_addr, dns_pkt);
+
+ /* Handle parse error */
+ if (status != PJ_SUCCESS) {
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(3,(resolver->name.ptr,
+ "Error parsing DNS response from %s:%d: %s",
+ pj_inet_ntoa(resolver->udp_src_addr.sin_addr),
+ pj_ntohs(resolver->udp_src_addr.sin_port),
+ errmsg));
+ goto read_next_packet;
+ }
+
+ /* Find the query based on the transaction ID */
+ q = pj_hash_get(resolver->hquerybyid, &dns_pkt->hdr.id,
+ sizeof(dns_pkt->hdr.id), NULL);
+ if (!q) {
+ PJ_LOG(5,(resolver->name.ptr,
+ "Unable to find query for DNS response id=%d from %s:%d "
+ "(the query may had been answered by other name servers)",
+ (unsigned)dns_pkt->hdr.id,
+ pj_inet_ntoa(resolver->udp_src_addr.sin_addr),
+ pj_ntohs(resolver->udp_src_addr.sin_port)));
+ goto read_next_packet;
+ }
+
+ /* Map DNS Rcode in the response into PJLIB status name space */
+ status = PJ_STATUS_FROM_DNS_RCODE(PJ_DNS_GET_RCODE(dns_pkt->hdr.flags));
+
+ /* Cancel query timeout timer. */
+ pj_assert(q->timer_entry.id != 0);
+ pj_timer_heap_cancel(resolver->timer, &q->timer_entry);
+ q->timer_entry.id = 0;
+
+ /* Clear hash table entries */
+ pj_hash_set(NULL, resolver->hquerybyid, &q->id, sizeof(q->id), 0, NULL);
+ pj_hash_set(NULL, resolver->hquerybyres, &q->key, sizeof(q->key), 0, NULL);
+
+ /* Notify applications first, to allow application to modify the
+ * record before it is saved to the hash table.
+ */
+ if (q->cb)
+ (*q->cb)(q->user_data, status, dns_pkt);
+
+ /* If query has subqueries, notify subqueries's application callback */
+ if (!pj_list_empty(&q->child_head)) {
+ pj_dns_async_query *child_q;
+
+ child_q = q->child_head.next;
+ while (child_q != (pj_dns_async_query*)&q->child_head) {
+ if (child_q->cb)
+ (*child_q->cb)(child_q->user_data, status, dns_pkt);
+ child_q = child_q->next;
+ }
+ }
+
+ /* We don't need NS and query section in the packet, so trim them. */
+ dns_pkt->hdr.qdcount = 0;
+ dns_pkt->hdr.nscount = 0;
+
+ /* Save/update response cache. */
+ update_res_cache(resolver, &q->key, status, PJ_TRUE, dns_pkt);
+
+ /* Recycle query objects, starting with the child queries */
+ if (!pj_list_empty(&q->child_head)) {
+ pj_dns_async_query *child_q;
+
+ child_q = q->child_head.next;
+ while (child_q != (pj_dns_async_query*)&q->child_head) {
+ pj_dns_async_query *next = child_q->next;
+ pj_list_erase(child_q);
+ pj_list_push_back(&resolver->query_free_nodes, child_q);
+ child_q = next;
+ }
+ }
+ pj_list_push_back(&resolver->query_free_nodes, q);
+
+read_next_packet:
+ bytes_read = sizeof(resolver->udp_rx_pkt);
+ resolver->udp_addr_len = sizeof(resolver->udp_src_addr);
+ status = pj_ioqueue_recvfrom(resolver->udp_key, op_key,
+ resolver->udp_rx_pkt,
+ &bytes_read, PJ_IOQUEUE_ALWAYS_ASYNC,
+ &resolver->udp_src_addr,
+ &resolver->udp_addr_len);
+ if (status != PJ_EPENDING) {
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(4,(resolver->name.ptr, "DNS resolver ioqueue read error: %s",
+ errmsg));
+
+ pj_assert(!"Unhandled error");
+ }
+
+ pj_mutex_unlock(resolver->mutex);
+}
+
+
+/*
+ * Put the specified DNS packet into DNS cache. This function is mainly used
+ * for testing the resolver, however it can also be used to inject entries
+ * into the resolver.
+ */
+PJ_DEF(pj_status_t) pj_dns_resolver_add_entry( pj_dns_resolver *resolver,
+ const pj_dns_parsed_packet *pkt,
+ pj_bool_t set_ttl)
+{
+ struct res_key key;
+
+ /* Sanity check */
+ PJ_ASSERT_RETURN(resolver && pkt, PJ_EINVAL);
+
+ /* Packet must be a DNS response */
+ PJ_ASSERT_RETURN(PJ_DNS_GET_QR(pkt->hdr.flags) & 1, PJ_EINVAL);
+
+ /* Make sure there are answers in the packet */
+ PJ_ASSERT_RETURN(pkt->hdr.anscount && pkt->ans ||
+ pkt->hdr.qdcount && pkt->q,
+ PJLIB_UTIL_EDNSNOANSWERREC);
+
+ pj_mutex_lock(resolver->mutex);
+
+ /* Build resource key for looking up hash tables */
+ pj_bzero(&key, sizeof(struct res_key));
+ if (pkt->hdr.anscount) {
+ /* Make sure name is not too long. */
+ PJ_ASSERT_RETURN(pkt->ans[0].name.slen < PJ_MAX_HOSTNAME,
+ PJ_ENAMETOOLONG);
+
+ init_res_key(&key, pkt->ans[0].type, &pkt->ans[0].name);
+
+ } else {
+ /* Make sure name is not too long. */
+ PJ_ASSERT_RETURN(pkt->q[0].name.slen < PJ_MAX_HOSTNAME,
+ PJ_ENAMETOOLONG);
+
+ init_res_key(&key, pkt->q[0].type, &pkt->q[0].name);
+ }
+
+ /* Insert entry. */
+ update_res_cache(resolver, &key, PJ_SUCCESS, set_ttl, pkt);
+
+ pj_mutex_unlock(resolver->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get the total number of response in the response cache.
+ */
+PJ_DEF(unsigned) pj_dns_resolver_get_cached_count(pj_dns_resolver *resolver)
+{
+ unsigned count;
+
+ PJ_ASSERT_RETURN(resolver, 0);
+
+ pj_mutex_lock(resolver->mutex);
+ count = pj_hash_count(resolver->hrescache);
+ pj_mutex_unlock(resolver->mutex);
+
+ return count;
+}
+
+
+/*
+ * Dump resolver state to the log.
+ */
+PJ_DEF(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,
+ pj_bool_t detail)
+{
+#if PJ_LOG_MAX_LEVEL >= 3
+ unsigned i;
+ pj_time_val now;
+
+ pj_mutex_lock(resolver->mutex);
+
+ pj_gettimeofday(&now);
+
+ PJ_LOG(3,(resolver->name.ptr, " Dumping resolver state:"));
+
+ PJ_LOG(3,(resolver->name.ptr, " Name servers:"));
+ for (i=0; i<resolver->ns_count; ++i) {
+ const char *state_names[] = { "probing", "active", "bad"};
+ struct nameserver *ns = &resolver->ns[i];
+
+ PJ_LOG(3,(resolver->name.ptr,
+ " NS %d: %s:%d (state=%s until %ds, rtt=%d ms)",
+ i, pj_inet_ntoa(ns->addr.sin_addr),
+ pj_ntohs(ns->addr.sin_port),
+ state_names[ns->state],
+ ns->state_expiry.sec - now.sec,
+ PJ_TIME_VAL_MSEC(ns->rt_delay)));
+ }
+
+ PJ_LOG(3,(resolver->name.ptr, " Nb. of cached responses: %u",
+ pj_hash_count(resolver->hrescache)));
+ if (detail) {
+ pj_hash_iterator_t itbuf, *it;
+ it = pj_hash_first(resolver->hrescache, &itbuf);
+ while (it) {
+ struct cached_res *cache = pj_hash_this(resolver->hrescache, it);
+ PJ_LOG(3,(resolver->name.ptr,
+ " Type %s: %s",
+ pj_dns_get_type_name(cache->key.qtype),
+ cache->key.name));
+ it = pj_hash_next(resolver->hrescache, it);
+ }
+ }
+ PJ_LOG(3,(resolver->name.ptr, " Nb. of cached response free nodes: %u",
+ pj_list_size(&resolver->res_free_nodes)));
+ PJ_LOG(3,(resolver->name.ptr, " Nb. of pending queries: %u (%u)",
+ pj_hash_count(resolver->hquerybyid),
+ pj_hash_count(resolver->hquerybyres)));
+ if (detail) {
+ pj_hash_iterator_t itbuf, *it;
+ it = pj_hash_first(resolver->hquerybyid, &itbuf);
+ while (it) {
+ struct pj_dns_async_query *q;
+ q = pj_hash_this(resolver->hquerybyid, it);
+ PJ_LOG(3,(resolver->name.ptr,
+ " Type %s: %s",
+ pj_dns_get_type_name(q->key.qtype),
+ q->key.name));
+ it = pj_hash_next(resolver->hquerybyid, it);
+ }
+ }
+ PJ_LOG(3,(resolver->name.ptr, " Nb. of pending query free nodes: %u",
+ pj_list_size(&resolver->query_free_nodes)));
+ PJ_LOG(3,(resolver->name.ptr, " Nb. of timer entries: %u",
+ pj_timer_heap_count(resolver->timer)));
+ PJ_LOG(3,(resolver->name.ptr, " Pool capacity: %d, used size: %d",
+ pj_pool_get_capacity(resolver->pool),
+ pj_pool_get_used_size(resolver->pool)));
+
+ pj_mutex_unlock(resolver->mutex);
+#endif
+}
+