mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- separate ldns into core ldns inside ldns/ subdirectory. No more
--with-ldns is needed and unbound does not rely on libldns. git-svn-id: file:///svn/unbound/trunk@2998 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
1a9e620f8c
commit
29e96e86c9
982
Makefile.in
982
Makefile.in
File diff suppressed because it is too large
Load Diff
73
compat/strlcat.c
Normal file
73
compat/strlcat.c
Normal file
@ -0,0 +1,73 @@
|
||||
/* compat/strlcat.c */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_STRLCAT
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif /* !HAVE_STRLCAT */
|
33
config.h.in
33
config.h.in
@ -70,6 +70,12 @@
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `endprotoent' function. */
|
||||
#undef HAVE_ENDPROTOENT
|
||||
|
||||
/* Define to 1 if you have the `endservent' function. */
|
||||
#undef HAVE_ENDSERVENT
|
||||
|
||||
/* Define to 1 if you have the `event_base_free' function. */
|
||||
#undef HAVE_EVENT_BASE_FREE
|
||||
|
||||
@ -166,15 +172,6 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define to 1 if you have the `ldns_key_EVP_unload_gost' function. */
|
||||
#undef HAVE_LDNS_KEY_EVP_UNLOAD_GOST
|
||||
|
||||
/* Define to 1 if you have the <ldns/ldns.h> header file. */
|
||||
#undef HAVE_LDNS_LDNS_H
|
||||
|
||||
/* Define to 1 if you have the `ldns' library (-lldns). */
|
||||
#undef HAVE_LIBLDNS
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
@ -310,6 +307,9 @@
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
#undef HAVE_STRLCAT
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
@ -475,6 +475,9 @@
|
||||
/* Shared data */
|
||||
#undef SHARE_DIR
|
||||
|
||||
/* The size of `time_t', as computed by sizeof. */
|
||||
#undef SIZEOF_TIME_T
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
@ -687,6 +690,12 @@
|
||||
# define NDEBUG
|
||||
#endif
|
||||
|
||||
/** Use small-ldns codebase */
|
||||
#define USE_SLDNS 1
|
||||
#ifdef HAVE_SSL
|
||||
# define LDNS_BUILD_CONFIG_HAVE_SSL 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -796,6 +805,12 @@ void *memmove(void *dest, const void *src, size_t n);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
#define strlcat strlcat_unbound
|
||||
size_t strlcat(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy strlcpy_unbound
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
|
436
configure
vendored
436
configure
vendored
@ -632,7 +632,6 @@ ac_includes_default="\
|
||||
#endif"
|
||||
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
ldnsdir
|
||||
ALLTARGET
|
||||
SOURCEFILE
|
||||
SOURCEDETERMINE
|
||||
@ -827,7 +826,6 @@ enable_static_exe
|
||||
enable_lock_checks
|
||||
enable_allsymbols
|
||||
with_libunbound_only
|
||||
with_ldns
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
host_alias
|
||||
@ -1528,7 +1526,6 @@ Optional Packages:
|
||||
outgoing port ranges.
|
||||
--with-libexpat=path specify explicit path for libexpat.
|
||||
--with-libunbound-only do not build daemon and tool programs
|
||||
--with-ldns=PATH specify prefix of path of ldns library to use
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
@ -2036,6 +2033,189 @@ $as_echo "$ac_res" >&6; }
|
||||
|
||||
} # ac_fn_c_check_type
|
||||
|
||||
# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
|
||||
# --------------------------------------------
|
||||
# Tries to find the compile-time value of EXPR in a program that includes
|
||||
# INCLUDES, setting VAR accordingly. Returns whether the value could be
|
||||
# computed
|
||||
ac_fn_c_compute_int ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
if test "$cross_compiling" = yes; then
|
||||
# Depending upon the size, compute the lo and hi bounds.
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int test_array [1 - 2 * !(($2) >= 0)];
|
||||
test_array [0] = 0;
|
||||
return test_array [0];
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_lo=0 ac_mid=0
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
|
||||
test_array [0] = 0;
|
||||
return test_array [0];
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_hi=$ac_mid; break
|
||||
else
|
||||
as_fn_arith $ac_mid + 1 && ac_lo=$as_val
|
||||
if test $ac_lo -le $ac_mid; then
|
||||
ac_lo= ac_hi=
|
||||
break
|
||||
fi
|
||||
as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
done
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int test_array [1 - 2 * !(($2) < 0)];
|
||||
test_array [0] = 0;
|
||||
return test_array [0];
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_hi=-1 ac_mid=-1
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
|
||||
test_array [0] = 0;
|
||||
return test_array [0];
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_lo=$ac_mid; break
|
||||
else
|
||||
as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
|
||||
if test $ac_mid -le $ac_hi; then
|
||||
ac_lo= ac_hi=
|
||||
break
|
||||
fi
|
||||
as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
done
|
||||
else
|
||||
ac_lo= ac_hi=
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
# Binary search between lo and hi bounds.
|
||||
while test "x$ac_lo" != "x$ac_hi"; do
|
||||
as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
|
||||
test_array [0] = 0;
|
||||
return test_array [0];
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_hi=$ac_mid
|
||||
else
|
||||
as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
done
|
||||
case $ac_lo in #((
|
||||
?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
|
||||
'') ac_retval=1 ;;
|
||||
esac
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
static long int longval () { return $2; }
|
||||
static unsigned long int ulongval () { return $2; }
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
FILE *f = fopen ("conftest.val", "w");
|
||||
if (! f)
|
||||
return 1;
|
||||
if (($2) < 0)
|
||||
{
|
||||
long int i = longval ();
|
||||
if (i != ($2))
|
||||
return 1;
|
||||
fprintf (f, "%ld", i);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long int i = ulongval ();
|
||||
if (i != ($2))
|
||||
return 1;
|
||||
fprintf (f, "%lu", i);
|
||||
}
|
||||
/* Do not output a trailing newline, as this causes \r\n confusion
|
||||
on some platforms. */
|
||||
return ferror (f) || fclose (f) != 0;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_run "$LINENO"; then :
|
||||
echo >>conftest.val; read $3 <conftest.val; ac_retval=0
|
||||
else
|
||||
ac_retval=1
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
rm -f conftest.val
|
||||
|
||||
fi
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
as_fn_set_status $ac_retval
|
||||
|
||||
} # ac_fn_c_compute_int
|
||||
|
||||
# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
|
||||
# ---------------------------------------------
|
||||
# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
|
||||
@ -13885,6 +14065,53 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||
fi
|
||||
|
||||
|
||||
# The cast to long int works around a bug in the HP C Compiler
|
||||
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||
# This bug is HP SR number 8606223364.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
|
||||
$as_echo_n "checking size of time_t... " >&6; }
|
||||
if ${ac_cv_sizeof_time_t+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" "
|
||||
$ac_includes_default
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
"; then :
|
||||
|
||||
else
|
||||
if test "$ac_cv_type_time_t" = yes; then
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error 77 "cannot compute sizeof (time_t)
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
ac_cv_sizeof_time_t=0
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
|
||||
$as_echo "$ac_cv_sizeof_time_t" >&6; }
|
||||
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
|
||||
_ACEOF
|
||||
|
||||
|
||||
|
||||
# add option to disable the evil rpath
|
||||
|
||||
# Check whether --enable-rpath was given.
|
||||
@ -17738,7 +17965,7 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@ -17859,6 +18086,20 @@ esac
|
||||
fi
|
||||
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
|
||||
if test "x$ac_cv_func_strlcat" = xyes; then :
|
||||
$as_echo "#define HAVE_STRLCAT 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" strlcat.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS strlcat.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
|
||||
if test "x$ac_cv_func_strlcpy" = xyes; then :
|
||||
$as_echo "#define HAVE_STRLCPY 1" >>confdefs.h
|
||||
@ -18008,193 +18249,6 @@ fi
|
||||
|
||||
|
||||
|
||||
# check this after all other compilation checks, since the linking of the lib
|
||||
# may break checks after this.
|
||||
|
||||
# Check whether --with-ldns was given.
|
||||
if test "${with_ldns+set}" = set; then :
|
||||
withval=$with_ldns;
|
||||
if test "$withval" != "yes"; then
|
||||
if test "$withval" != "/usr" -a "$withval" != ""; then
|
||||
CPPFLAGS="-I$withval/include $CPPFLAGS"
|
||||
LDFLAGS="-L$withval/lib $LDFLAGS"
|
||||
|
||||
if test "x$enable_rpath" = xyes; then
|
||||
if echo "$withval/lib" | grep "^/" >/dev/null; then
|
||||
RUNTIME_PATH="$RUNTIME_PATH -R$withval/lib"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
ldnsdir="$withval"
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# check if ldns is good enough
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldns_rr_new in -lldns" >&5
|
||||
$as_echo_n "checking for ldns_rr_new in -lldns... " >&6; }
|
||||
if ${ac_cv_lib_ldns_ldns_rr_new+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lldns $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char ldns_rr_new ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return ldns_rr_new ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_ldns_ldns_rr_new=yes
|
||||
else
|
||||
ac_cv_lib_ldns_ldns_rr_new=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldns_ldns_rr_new" >&5
|
||||
$as_echo "$ac_cv_lib_ldns_ldns_rr_new" >&6; }
|
||||
if test "x$ac_cv_lib_ldns_ldns_rr_new" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBLDNS 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lldns $LIBS"
|
||||
|
||||
else
|
||||
|
||||
as_fn_error $? "No ldns library found, install the ldns library into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Install the package ldns or download source http://www.nlnetlabs.nl/projects/ldns" "$LINENO" 5
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "ldns_buffer_copy" "ac_cv_func_ldns_buffer_copy"
|
||||
if test "x$ac_cv_func_ldns_buffer_copy" = xyes; then :
|
||||
|
||||
fi
|
||||
|
||||
if test $USE_NSS = "no"; then
|
||||
ac_fn_c_check_func "$LINENO" "ldns_key_buf2rsa_raw" "ac_cv_func_ldns_key_buf2rsa_raw"
|
||||
if test "x$ac_cv_func_ldns_key_buf2rsa_raw" = xyes; then :
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
ac_cv_func_ldns_key_buf2rsa_raw="yes"
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "ldns_get_random" "ac_cv_func_ldns_get_random"
|
||||
if test "x$ac_cv_func_ldns_get_random" = xyes; then :
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "ldns_b32_ntop_extended_hex" "ac_cv_func_ldns_b32_ntop_extended_hex"
|
||||
if test "x$ac_cv_func_ldns_b32_ntop_extended_hex" = xyes; then :
|
||||
|
||||
fi
|
||||
|
||||
if test x$use_gost = xyes -a x$USE_NSS = xno; then
|
||||
ac_fn_c_check_func "$LINENO" "ldns_key_EVP_load_gost_id" "ac_cv_func_ldns_key_EVP_load_gost_id"
|
||||
if test "x$ac_cv_func_ldns_key_EVP_load_gost_id" = xyes; then :
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in ldns_key_EVP_unload_gost
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "ldns_key_EVP_unload_gost" "ac_cv_func_ldns_key_EVP_unload_gost"
|
||||
if test "x$ac_cv_func_ldns_key_EVP_unload_gost" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LDNS_KEY_EVP_UNLOAD_GOST 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
else
|
||||
ac_cv_func_ldns_key_EVP_load_gost_id="yes"
|
||||
fi
|
||||
if test x$use_ecdsa = xyes; then
|
||||
ac_fn_c_check_decl "$LINENO" "LDNS_ECDSAP384SHA384" "ac_cv_have_decl_LDNS_ECDSAP384SHA384" "
|
||||
$ac_includes_default
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_LDNS_ECDSAP384SHA384" = xyes; then :
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
ac_cv_have_decl_LDNS_ECDSAP384SHA384="yes"
|
||||
fi
|
||||
for ac_header in ldns/ldns.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "ldns/ldns.h" "ac_cv_header_ldns_ldns_h" "$ac_includes_default
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
"
|
||||
if test "x$ac_cv_header_ldns_ldns_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LDNS_LDNS_H 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
|
||||
as_fn_error $? "No ldns include file found, install the ldns library development files. Install package ldns-dev or ldns-devel or download source http://www.nlnetlabs.nl/projects/ldns" "$LINENO" 5
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if test $ac_cv_func_ldns_buffer_copy = yes \
|
||||
-a $ac_cv_func_ldns_key_buf2rsa_raw = yes \
|
||||
-a $ac_cv_func_ldns_get_random = yes \
|
||||
-a $ac_cv_header_ldns_ldns_h = yes \
|
||||
-a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
|
||||
-a $ac_cv_func_ldns_key_EVP_load_gost_id = yes \
|
||||
-a $ac_cv_have_decl_LDNS_ECDSAP384SHA384 = yes; then
|
||||
:
|
||||
else
|
||||
as_fn_error $? "ldns library is not recent, update the ldns library, install it into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Package libldns or download source http://www.nlnetlabs.nl/projects/ldns" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Stripping extension flags..." >&5
|
||||
$as_echo "$as_me: Stripping extension flags..." >&6;}
|
||||
|
110
configure.ac
110
configure.ac
@ -296,6 +296,20 @@ ACX_TYPE_IN_ADDR_T
|
||||
ACX_TYPE_IN_PORT_T
|
||||
ACX_CHECK_MEMCMP_SIGNED
|
||||
|
||||
AC_CHECK_SIZEOF(time_t,,[
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
])
|
||||
|
||||
# add option to disable the evil rpath
|
||||
ACX_ARG_RPATH
|
||||
AC_SUBST(RUNTIME_PATH)
|
||||
@ -928,7 +942,7 @@ AC_INCLUDES_DEFAULT
|
||||
#endif
|
||||
])
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
@ -940,6 +954,7 @@ AC_REPLACE_FUNCS(inet_aton)
|
||||
AC_REPLACE_FUNCS(inet_pton)
|
||||
AC_REPLACE_FUNCS(inet_ntop)
|
||||
AC_REPLACE_FUNCS(snprintf)
|
||||
AC_REPLACE_FUNCS(strlcat)
|
||||
AC_REPLACE_FUNCS(strlcpy)
|
||||
AC_REPLACE_FUNCS(memmove)
|
||||
AC_REPLACE_FUNCS(gmtime_r)
|
||||
@ -1025,92 +1040,6 @@ AC_ARG_WITH(libunbound-only, AC_HELP_STRING([--with-libunbound-only],
|
||||
])
|
||||
AC_SUBST(ALLTARGET)
|
||||
|
||||
# check this after all other compilation checks, since the linking of the lib
|
||||
# may break checks after this.
|
||||
AC_ARG_WITH(ldns, AC_HELP_STRING([--with-ldns=PATH],
|
||||
[specify prefix of path of ldns library to use]),
|
||||
[
|
||||
if test "$withval" != "yes"; then
|
||||
if test "$withval" != "/usr" -a "$withval" != ""; then
|
||||
CPPFLAGS="-I$withval/include $CPPFLAGS"
|
||||
LDFLAGS="-L$withval/lib $LDFLAGS"
|
||||
ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
fi
|
||||
ldnsdir="$withval"
|
||||
AC_SUBST(ldnsdir)
|
||||
fi
|
||||
])
|
||||
|
||||
# check if ldns is good enough
|
||||
AC_CHECK_LIB(ldns, ldns_rr_new,,[
|
||||
AC_MSG_ERROR([No ldns library found, install the ldns library into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Install the package ldns or download source http://www.nlnetlabs.nl/projects/ldns])
|
||||
])
|
||||
AC_CHECK_FUNC(ldns_buffer_copy)
|
||||
if test $USE_NSS = "no"; then
|
||||
AC_CHECK_FUNC(ldns_key_buf2rsa_raw)
|
||||
else
|
||||
dnl ignore test
|
||||
ac_cv_func_ldns_key_buf2rsa_raw="yes"
|
||||
fi
|
||||
AC_CHECK_FUNC(ldns_get_random)
|
||||
AC_CHECK_FUNC(ldns_b32_ntop_extended_hex)
|
||||
if test x$use_gost = xyes -a x$USE_NSS = xno; then
|
||||
AC_CHECK_FUNC(ldns_key_EVP_load_gost_id)
|
||||
AC_CHECK_FUNCS([ldns_key_EVP_unload_gost])
|
||||
else
|
||||
dnl ignore test
|
||||
ac_cv_func_ldns_key_EVP_load_gost_id="yes"
|
||||
fi
|
||||
if test x$use_ecdsa = xyes; then
|
||||
AC_CHECK_DECL([LDNS_ECDSAP384SHA384], [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
#include <ldns/ldns.h>
|
||||
])
|
||||
else
|
||||
ac_cv_have_decl_LDNS_ECDSAP384SHA384="yes"
|
||||
fi
|
||||
AC_CHECK_HEADERS([ldns/ldns.h],,[
|
||||
AC_MSG_ERROR([No ldns include file found, install the ldns library development files. Install package ldns-dev or ldns-devel or download source http://www.nlnetlabs.nl/projects/ldns])
|
||||
], [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
])
|
||||
if test $ac_cv_func_ldns_buffer_copy = yes \
|
||||
-a $ac_cv_func_ldns_key_buf2rsa_raw = yes \
|
||||
-a $ac_cv_func_ldns_get_random = yes \
|
||||
-a $ac_cv_header_ldns_ldns_h = yes \
|
||||
-a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
|
||||
-a $ac_cv_func_ldns_key_EVP_load_gost_id = yes \
|
||||
-a $ac_cv_have_decl_LDNS_ECDSAP384SHA384 = yes; then
|
||||
dnl ldns was found
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([ldns library is not recent, update the ldns library, install it into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Package libldns or download source http://www.nlnetlabs.nl/projects/ldns])
|
||||
fi
|
||||
|
||||
ACX_STRIP_EXT_FLAGS
|
||||
LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
|
||||
|
||||
@ -1126,6 +1055,12 @@ dnl includes
|
||||
# define NDEBUG
|
||||
#endif
|
||||
|
||||
/** Use small-ldns codebase */
|
||||
#define USE_SLDNS 1
|
||||
#ifdef HAVE_SSL
|
||||
# define LDNS_BUILD_CONFIG_HAVE_SSL 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -1180,6 +1115,7 @@ AHX_CONFIG_INET_PTON(unbound)
|
||||
AHX_CONFIG_INET_NTOP(unbound)
|
||||
AHX_CONFIG_INET_ATON(unbound)
|
||||
AHX_CONFIG_MEMMOVE(unbound)
|
||||
AHX_CONFIG_STRLCAT(unbound)
|
||||
AHX_CONFIG_STRLCPY(unbound)
|
||||
AHX_CONFIG_GMTIME_R(unbound)
|
||||
AHX_CONFIG_W32_SLEEP
|
||||
|
@ -40,7 +40,7 @@
|
||||
* to text format.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include "daemon/cachedump.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/worker.h"
|
||||
@ -56,64 +56,19 @@
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
|
||||
/** convert to ldns rr */
|
||||
static ldns_rr*
|
||||
to_rr(struct ub_packed_rrset_key* k, struct packed_rrset_data* d,
|
||||
time_t now, size_t i, uint16_t type)
|
||||
{
|
||||
ldns_rr* rr = ldns_rr_new();
|
||||
ldns_rdf* rdf;
|
||||
ldns_status status;
|
||||
size_t pos;
|
||||
log_assert(i < d->count + d->rrsig_count);
|
||||
if(!rr) {
|
||||
return NULL;
|
||||
}
|
||||
ldns_rr_set_type(rr, type);
|
||||
ldns_rr_set_class(rr, ntohs(k->rk.rrset_class));
|
||||
if(d->rr_ttl[i] < now)
|
||||
ldns_rr_set_ttl(rr, 0);
|
||||
else ldns_rr_set_ttl(rr, d->rr_ttl[i] - now);
|
||||
pos = 0;
|
||||
status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
/* we drop detailed error in status */
|
||||
ldns_rr_free(rr);
|
||||
return NULL;
|
||||
}
|
||||
ldns_rr_set_owner(rr, rdf);
|
||||
pos = 0;
|
||||
status = ldns_wire2rdf(rr, d->rr_data[i], d->rr_len[i], &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
/* we drop detailed error in status */
|
||||
ldns_rr_free(rr);
|
||||
return NULL;
|
||||
}
|
||||
return rr;
|
||||
}
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/wire2str.h"
|
||||
#include "ldns/str2wire.h"
|
||||
|
||||
/** dump one rrset zonefile line */
|
||||
static int
|
||||
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, time_t now, size_t i, uint16_t type)
|
||||
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
{
|
||||
char* s;
|
||||
ldns_rr* rr = to_rr(k, d, now, i, type);
|
||||
if(!rr) {
|
||||
char s[65535];
|
||||
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
|
||||
return ssl_printf(ssl, "BADRR\n");
|
||||
}
|
||||
s = ldns_rr2str(rr);
|
||||
ldns_rr_free(rr);
|
||||
if(!s) {
|
||||
return ssl_printf(ssl, "BADRR\n");
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s", s)) {
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
free(s);
|
||||
return 1;
|
||||
return ssl_printf(ssl, "%s\n", s);
|
||||
}
|
||||
|
||||
/** dump rrset key and data info */
|
||||
@ -134,16 +89,10 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
(int)d->trust, (int)d->security
|
||||
))
|
||||
return 0;
|
||||
for(i=0; i<d->count; i++) {
|
||||
if(!dump_rrset_line(ssl, k, d, now, i, ntohs(k->rk.type)))
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(!dump_rrset_line(ssl, k, now, i))
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<d->rrsig_count; i++) {
|
||||
if(!dump_rrset_line(ssl, k, d, now, i+d->count,
|
||||
LDNS_RR_TYPE_RRSIG))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -189,20 +138,10 @@ dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
static int
|
||||
dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
ldns_status status;
|
||||
size_t pos;
|
||||
char* nm, *tp, *cl;
|
||||
|
||||
pos = 0;
|
||||
status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
return ssl_printf(ssl, "BADREF\n");
|
||||
}
|
||||
nm = ldns_rdf2str(rdf);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
tp = ldns_rr_type2str(ntohs(k->rk.type));
|
||||
cl = ldns_rr_class2str(ntohs(k->rk.rrset_class));
|
||||
nm = ldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
|
||||
tp = ldns_wire2str_type(ntohs(k->rk.type));
|
||||
cl = ldns_wire2str_class(ntohs(k->rk.rrset_class));
|
||||
if(!nm || !cl || !tp) {
|
||||
free(nm);
|
||||
free(tp);
|
||||
@ -229,21 +168,12 @@ dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
|
||||
{
|
||||
size_t i;
|
||||
char* nm, *tp, *cl;
|
||||
ldns_rdf* rdf;
|
||||
ldns_status status;
|
||||
size_t pos;
|
||||
if(!k || !d) return 1;
|
||||
if(d->ttl < now) return 1; /* expired */
|
||||
|
||||
pos = 0;
|
||||
status = ldns_wire2dname(&rdf, k->qname, k->qname_len, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
return 1; /* skip this entry */
|
||||
}
|
||||
nm = ldns_rdf2str(rdf);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
tp = ldns_rr_type2str(k->qtype);
|
||||
cl = ldns_rr_class2str(k->qclass);
|
||||
nm = ldns_wire2str_dname(k->qname, k->qname_len);
|
||||
tp = ldns_wire2str_type(k->qtype);
|
||||
cl = ldns_wire2str_class(k->qclass);
|
||||
if(!nm || !tp || !cl) {
|
||||
free(nm);
|
||||
free(tp);
|
||||
@ -389,8 +319,9 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
|
||||
unsigned int i, int is_rrsig, int* go_on, time_t now)
|
||||
{
|
||||
ldns_rr* rr;
|
||||
ldns_status status;
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t rr_len = sizeof(rr), dname_len = 0;
|
||||
int status;
|
||||
|
||||
/* read the line */
|
||||
if(!ssl_read_buf(ssl, buf))
|
||||
@ -399,66 +330,43 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
*go_on = 0;
|
||||
return 1;
|
||||
}
|
||||
status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf),
|
||||
LDNS_DEFAULT_TTL, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
status = ldns_str2wire_rr_buf((char*)ldns_buffer_begin(buf), rr,
|
||||
&rr_len, &dname_len, 3600, NULL, 0, NULL, 0);
|
||||
if(status != 0) {
|
||||
log_warn("error cannot parse rr: %s: %s",
|
||||
ldns_get_errorstr_by_id(status),
|
||||
ldns_get_errorstr_parse(status),
|
||||
(char*)ldns_buffer_begin(buf));
|
||||
return 0;
|
||||
}
|
||||
if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
|
||||
if(is_rrsig && ldns_wirerr_get_type(rr, rr_len, dname_len)
|
||||
!= LDNS_RR_TYPE_RRSIG) {
|
||||
log_warn("error expected rrsig but got %s",
|
||||
(char*)ldns_buffer_begin(buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* convert ldns rr into packed_rr */
|
||||
d->rr_ttl[i] = ldns_rr_ttl(rr) + now;
|
||||
d->rr_ttl[i] = (time_t)ldns_wirerr_get_ttl(rr, rr_len, dname_len) + now;
|
||||
ldns_buffer_clear(buf);
|
||||
ldns_buffer_skip(buf, 2);
|
||||
status = ldns_rr_rdata2buffer_wire(buf, rr);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot rr2wire: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
ldns_buffer_flip(buf);
|
||||
ldns_buffer_write_u16_at(buf, 0, ldns_buffer_limit(buf) - 2);
|
||||
|
||||
d->rr_len[i] = ldns_buffer_limit(buf);
|
||||
d->rr_len[i] = ldns_wirerr_get_rdatalen(rr, rr_len, dname_len)+2;
|
||||
d->rr_data[i] = (uint8_t*)regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
ldns_wirerr_get_rdatawl(rr, rr_len, dname_len), d->rr_len[i]);
|
||||
if(!d->rr_data[i]) {
|
||||
ldns_rr_free(rr);
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if first entry, fill the key structure */
|
||||
if(i==0) {
|
||||
rk->rk.type = htons(ldns_rr_get_type(rr));
|
||||
rk->rk.rrset_class = htons(ldns_rr_get_class(rr));
|
||||
ldns_buffer_clear(buf);
|
||||
status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot dname2buffer: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
ldns_buffer_flip(buf);
|
||||
rk->rk.dname_len = ldns_buffer_limit(buf);
|
||||
rk->rk.dname = regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
rk->rk.type = htons(ldns_wirerr_get_type(rr, rr_len, dname_len));
|
||||
rk->rk.rrset_class = htons(ldns_wirerr_get_class(rr, rr_len, dname_len));
|
||||
rk->rk.dname_len = dname_len;
|
||||
rk->rk.dname = regional_alloc_init(region, rr, dname_len);
|
||||
if(!rk->rk.dname) {
|
||||
log_warn("error out of memory");
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ldns_rr_free(rr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -618,13 +526,13 @@ load_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** read qinfo from next three words */
|
||||
static char*
|
||||
load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
struct regional* region)
|
||||
load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
{
|
||||
/* s is part of the buf */
|
||||
char* s = str;
|
||||
ldns_rr* rr;
|
||||
ldns_status status;
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t rr_len = sizeof(rr), dname_len = 0;
|
||||
int status;
|
||||
|
||||
/* skip three words */
|
||||
s = strchr(str, ' ');
|
||||
@ -638,26 +546,17 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
s++;
|
||||
|
||||
/* parse them */
|
||||
status = ldns_rr_new_question_frm_str(&rr, str, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
status = ldns_str2wire_rr_question_buf(str, rr, &rr_len, &dname_len,
|
||||
NULL, 0, NULL, 0);
|
||||
if(status != 0) {
|
||||
log_warn("error cannot parse: %s %s",
|
||||
ldns_get_errorstr_by_id(status), str);
|
||||
ldns_get_errorstr_parse(status), str);
|
||||
return NULL;
|
||||
}
|
||||
qinfo->qtype = ldns_rr_get_type(rr);
|
||||
qinfo->qclass = ldns_rr_get_class(rr);
|
||||
ldns_buffer_clear(buf);
|
||||
status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
|
||||
ldns_rr_free(rr);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot dname2wire: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
return NULL;
|
||||
}
|
||||
ldns_buffer_flip(buf);
|
||||
qinfo->qname_len = ldns_buffer_limit(buf);
|
||||
qinfo->qname = (uint8_t*)regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
qinfo->qtype = ldns_wirerr_get_type(rr, rr_len, dname_len);
|
||||
qinfo->qclass = ldns_wirerr_get_class(rr, rr_len, dname_len);
|
||||
qinfo->qname_len = dname_len;
|
||||
qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len);
|
||||
if(!qinfo->qname) {
|
||||
log_warn("error out of memory");
|
||||
return NULL;
|
||||
@ -685,7 +584,7 @@ load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker,
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = load_qinfo(s, &qinfo, buf, region);
|
||||
s = load_qinfo(s, &qinfo, region);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@ -731,7 +630,7 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
return 0;
|
||||
}
|
||||
s += 4;
|
||||
s = load_qinfo(s, &qinf, buf, region);
|
||||
s = load_qinfo(s, &qinf, region);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -61,7 +61,6 @@
|
||||
#include "nss.h"
|
||||
#endif
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/remote.h"
|
||||
@ -80,6 +79,7 @@
|
||||
#include "util/random.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/net_help.h"
|
||||
#include "ldns/keyraw.h"
|
||||
#include <signal.h>
|
||||
|
||||
/** How many quit requests happened. */
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <ldns/ldns.h>
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
@ -75,6 +74,10 @@
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include "ldns/parseutil.h"
|
||||
#include "ldns/wire2str.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
@ -912,17 +915,20 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset)
|
||||
static int
|
||||
parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
uint8_t nm[LDNS_MAX_DOMAINLEN+1];
|
||||
size_t nmlen = sizeof(nm);
|
||||
int status;
|
||||
*res = NULL;
|
||||
*len = 0;
|
||||
*labs = 0;
|
||||
rdf = ldns_dname_new_frm_str(str);
|
||||
if(!rdf) {
|
||||
ssl_printf(ssl, "error cannot parse name %s\n", str);
|
||||
status = ldns_str2wire_dname_buf(str, nm, &nmlen);
|
||||
if(status != 0) {
|
||||
ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", str,
|
||||
LDNS_WIREPARSE_OFFSET(status),
|
||||
ldns_get_errorstr_parse(status));
|
||||
return 0;
|
||||
}
|
||||
*res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
|
||||
ldns_rdf_deep_free(rdf);
|
||||
*res = memdup(nm, nmlen);
|
||||
if(!*res) {
|
||||
ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
@ -1022,8 +1028,7 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||
static void
|
||||
do_data_add(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
if(!local_zones_add_RR(worker->daemon->local_zones, arg,
|
||||
worker->env.scratch_buffer)) {
|
||||
if(!local_zones_add_RR(worker->daemon->local_zones, arg)) {
|
||||
ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
|
||||
return;
|
||||
}
|
||||
@ -1388,9 +1393,9 @@ ssl_print_name_dp(SSL* ssl, char* str, uint8_t* nm, uint16_t dclass,
|
||||
struct delegpt_addr* a;
|
||||
int f = 0;
|
||||
if(str) { /* print header for forward, stub */
|
||||
char* c = ldns_rr_class2str(dclass);
|
||||
char* c = ldns_wire2str_class(dclass);
|
||||
dname_str(nm, buf);
|
||||
if(!ssl_printf(ssl, "%s %s %s: ", buf, c, str)) {
|
||||
if(!ssl_printf(ssl, "%s %s %s: ", buf, (c?c:"CLASS??"), str)) {
|
||||
free(c);
|
||||
return 0;
|
||||
}
|
||||
@ -1780,10 +1785,11 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m,
|
||||
if(m->sub_set.count == 0)
|
||||
snprintf(buf, len, " (empty_list)");
|
||||
RBTREE_FOR(sub, struct mesh_state_ref*, &m->sub_set) {
|
||||
char* t = ldns_rr_type2str(sub->s->s.qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(sub->s->s.qinfo.qclass);
|
||||
char* t = ldns_wire2str_type(sub->s->s.qinfo.qtype);
|
||||
char* c = ldns_wire2str_class(sub->s->s.qinfo.qclass);
|
||||
dname_str(sub->s->s.qinfo.qname, nm);
|
||||
snprintf(buf, len, " %s %s %s", t, c, nm);
|
||||
snprintf(buf, len, " %s %s %s", (t?t:"TYPE??"),
|
||||
(c?c:"CLASS??"), nm);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
free(t);
|
||||
@ -1812,13 +1818,14 @@ do_dump_requestlist(SSL* ssl, struct worker* worker)
|
||||
mesh = worker->env.mesh;
|
||||
if(!mesh) return;
|
||||
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
|
||||
char* t = ldns_rr_type2str(m->s.qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(m->s.qinfo.qclass);
|
||||
char* t = ldns_wire2str_type(m->s.qinfo.qtype);
|
||||
char* c = ldns_wire2str_class(m->s.qinfo.qclass);
|
||||
dname_str(m->s.qinfo.qname, buf);
|
||||
get_mesh_age(m, timebuf, sizeof(timebuf), &worker->env);
|
||||
get_mesh_status(mesh, m, statbuf, sizeof(statbuf));
|
||||
if(!ssl_printf(ssl, "%3d %4s %2s %s %s %s\n",
|
||||
num, t, c, buf, timebuf, statbuf)) {
|
||||
num, (t?t:"TYPE??"), (c?c:"CLASS??"), buf, timebuf,
|
||||
statbuf)) {
|
||||
free(t);
|
||||
free(c);
|
||||
return;
|
||||
@ -1978,17 +1985,25 @@ do_list_local_data(SSL* ssl, struct worker* worker)
|
||||
struct local_zone* z;
|
||||
struct local_data* d;
|
||||
struct local_rrset* p;
|
||||
char* s = (char*)ldns_buffer_begin(worker->env.scratch_buffer);
|
||||
size_t slen = ldns_buffer_capacity(worker->env.scratch_buffer);
|
||||
lock_quick_lock(&zones->lock);
|
||||
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
|
||||
lock_rw_rdlock(&z->lock);
|
||||
RBTREE_FOR(d, struct local_data*, &z->data) {
|
||||
for(p = d->rrsets; p; p = p->next) {
|
||||
ldns_rr_list* rr = packed_rrset_to_rr_list(
|
||||
p->rrset, worker->env.scratch_buffer);
|
||||
char* str = ldns_rr_list2str(rr);
|
||||
(void)ssl_printf(ssl, "%s", str);
|
||||
free(str);
|
||||
ldns_rr_list_free(rr);
|
||||
struct packed_rrset_data* d =
|
||||
(struct packed_rrset_data*)p->rrset->entry.data;
|
||||
size_t i;
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(!packed_rr_to_string(p->rrset, i,
|
||||
0, s, slen)) {
|
||||
if(!ssl_printf(ssl, "BADRR\n"))
|
||||
return;
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s\n", s))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
|
@ -40,7 +40,6 @@
|
||||
* numbers. These 'statistics' may be of interest to the operator.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "daemon/stats.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
@ -51,6 +50,7 @@
|
||||
#include "util/timehist.h"
|
||||
#include "util/net_help.h"
|
||||
#include "validator/validator.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
|
@ -43,12 +43,12 @@
|
||||
#ifndef DAEMON_STATS_H
|
||||
#define DAEMON_STATS_H
|
||||
#include "util/timehist.h"
|
||||
#include <ldns/buffer.h>
|
||||
struct worker;
|
||||
struct config_file;
|
||||
struct comm_point;
|
||||
struct comm_reply;
|
||||
struct edns_data;
|
||||
struct ldns_buffer;
|
||||
|
||||
/** number of qtype that is stored for in array */
|
||||
#define STATS_QTYPE_NUM 256
|
||||
@ -230,6 +230,6 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
* @param stats: the stats
|
||||
* @param buf: buffer with rcode. If buffer is length0: not counted.
|
||||
*/
|
||||
void server_stats_insrcode(struct server_stats* stats, ldns_buffer* buf);
|
||||
void server_stats_insrcode(struct server_stats* stats, struct ldns_buffer* buf);
|
||||
|
||||
#endif /* DAEMON_STATS_H */
|
||||
|
@ -162,8 +162,8 @@ static void usage()
|
||||
#endif
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
get_event_sys(&evnm, &evsys, &evmethod);
|
||||
printf("linked libs: %s %s (it uses %s), ldns %s, %s\n",
|
||||
evnm, evsys, evmethod, ldns_version(),
|
||||
printf("linked libs: %s %s (it uses %s), %s\n",
|
||||
evnm, evsys, evmethod,
|
||||
#ifdef HAVE_SSL
|
||||
SSLeay_version(SSLEAY_VERSION)
|
||||
#elif defined(HAVE_NSS)
|
||||
|
@ -40,7 +40,6 @@
|
||||
* pending requests.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/random.h"
|
||||
@ -70,6 +69,7 @@
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "validator/autotrust.h"
|
||||
#include "validator/val_anchor.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
|
@ -3,6 +3,8 @@
|
||||
interface port 53 can be used at the same time, and one of the
|
||||
daemons is unbound.
|
||||
- iana portlist update.
|
||||
- separate ldns into core ldns inside ldns/ subdirectory. No more
|
||||
--with-ldns is needed and unbound does not rely on libldns.
|
||||
|
||||
22 Oct 2013: Wouter
|
||||
- Patch from Neel Goyal: Add an API call to set an event base on an
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/net_help.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
struct delegpt*
|
||||
delegpt_create(struct regional* region)
|
||||
|
@ -40,15 +40,14 @@
|
||||
* Keep track of forward zones and config settings.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/rdata.h>
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/rr.h>
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/str2wire.h"
|
||||
|
||||
int
|
||||
fwd_cmp(const void* k1, const void* k2)
|
||||
@ -180,22 +179,23 @@ static struct delegpt*
|
||||
read_fwds_name(struct config_stub* s)
|
||||
{
|
||||
struct delegpt* dp;
|
||||
ldns_rdf* rdf;
|
||||
uint8_t* dname;
|
||||
size_t dname_len;
|
||||
if(!s->name) {
|
||||
log_err("forward zone without a name (use name \".\" to forward everything)");
|
||||
return NULL;
|
||||
}
|
||||
rdf = ldns_dname_new_frm_str(s->name);
|
||||
if(!rdf) {
|
||||
dname = ldns_str2wire_dname(s->name, &dname_len);
|
||||
if(!dname) {
|
||||
log_err("cannot parse forward zone name %s", s->name);
|
||||
return NULL;
|
||||
}
|
||||
if(!(dp=delegpt_create_mlc(ldns_rdf_data(rdf)))) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!(dp=delegpt_create_mlc(dname))) {
|
||||
free(dname);
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(dname);
|
||||
return dp;
|
||||
}
|
||||
|
||||
@ -204,21 +204,22 @@ static int
|
||||
read_fwds_host(struct config_stub* s, struct delegpt* dp)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
ldns_rdf* rdf;
|
||||
uint8_t* dname;
|
||||
size_t dname_len;
|
||||
for(p = s->hosts; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
rdf = ldns_dname_new_frm_str(p->str);
|
||||
if(!rdf) {
|
||||
dname = ldns_str2wire_dname(p->str, &dname_len);
|
||||
if(!dname) {
|
||||
log_err("cannot parse forward %s server name: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0)) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!delegpt_add_ns_mlc(dp, dname, 0)) {
|
||||
free(dname);
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(dname);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -290,19 +291,20 @@ static int
|
||||
make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
{
|
||||
struct config_stub* s;
|
||||
uint8_t* dname;
|
||||
size_t dname_len;
|
||||
for(s = cfg->stubs; s; s = s->next) {
|
||||
ldns_rdf* rdf = ldns_dname_new_frm_str(s->name);
|
||||
if(!rdf) {
|
||||
dname = ldns_str2wire_dname(s->name, &dname_len);
|
||||
if(!dname) {
|
||||
log_err("cannot parse stub name '%s'", s->name);
|
||||
return 0;
|
||||
}
|
||||
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN,
|
||||
ldns_rdf_data(rdf))) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) {
|
||||
free(dname);
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(dname);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -40,14 +40,15 @@
|
||||
* Keep track of stub and root hints, and read those from config.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/rr.h>
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include "ldns/wire2str.h"
|
||||
|
||||
struct iter_hints*
|
||||
hints_create(void)
|
||||
@ -92,19 +93,20 @@ ah(struct delegpt* dp, const char* sv, const char* ip)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
ldns_rdf* rdf = ldns_dname_new_frm_str(sv);
|
||||
if(!rdf) {
|
||||
size_t dname_len;
|
||||
uint8_t* dname = ldns_str2wire_dname(sv, &dname_len);
|
||||
if(!dname) {
|
||||
log_err("could not parse %s", sv);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0) ||
|
||||
if(!delegpt_add_ns_mlc(dp, dname, 0) ||
|
||||
!extstrtoaddr(ip, &addr, &addrlen) ||
|
||||
!delegpt_add_target_mlc(dp, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
|
||||
!delegpt_add_target_mlc(dp, dname, dname_len,
|
||||
&addr, addrlen, 0, 0)) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(dname);
|
||||
return 0;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(dname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -186,22 +188,23 @@ static struct delegpt*
|
||||
read_stubs_name(struct config_stub* s)
|
||||
{
|
||||
struct delegpt* dp;
|
||||
ldns_rdf* rdf;
|
||||
size_t dname_len;
|
||||
uint8_t* dname;
|
||||
if(!s->name) {
|
||||
log_err("stub zone without a name");
|
||||
return NULL;
|
||||
}
|
||||
rdf = ldns_dname_new_frm_str(s->name);
|
||||
if(!rdf) {
|
||||
dname = ldns_str2wire_dname(s->name, &dname_len);
|
||||
if(!dname) {
|
||||
log_err("cannot parse stub zone name %s", s->name);
|
||||
return NULL;
|
||||
}
|
||||
if(!(dp=delegpt_create_mlc(ldns_rdf_data(rdf)))) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!(dp=delegpt_create_mlc(dname))) {
|
||||
free(dname);
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(dname);
|
||||
return dp;
|
||||
}
|
||||
|
||||
@ -210,21 +213,22 @@ static int
|
||||
read_stubs_host(struct config_stub* s, struct delegpt* dp)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
ldns_rdf* rdf;
|
||||
size_t dname_len;
|
||||
uint8_t* dname;
|
||||
for(p = s->hosts; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
rdf = ldns_dname_new_frm_str(p->str);
|
||||
if(!rdf) {
|
||||
dname = ldns_str2wire_dname(p->str, &dname_len);
|
||||
if(!dname) {
|
||||
log_err("cannot parse stub %s nameserver name: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0)) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!delegpt_add_ns_mlc(dp, dname, 0)) {
|
||||
free(dname);
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(dname);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -279,13 +283,11 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
|
||||
static int
|
||||
read_root_hints(struct iter_hints* hints, char* fname)
|
||||
{
|
||||
int lineno = 0;
|
||||
uint32_t default_ttl = 0;
|
||||
ldns_rdf* origin = NULL;
|
||||
ldns_rdf* prev_rr = NULL;
|
||||
struct ldns_file_parse_state pstate;
|
||||
struct delegpt* dp;
|
||||
ldns_rr* rr = NULL;
|
||||
ldns_status status;
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t rr_len, dname_len;
|
||||
int status;
|
||||
uint16_t c = LDNS_RR_CLASS_IN;
|
||||
FILE* f = fopen(fname, "r");
|
||||
if(!f) {
|
||||
@ -300,77 +302,78 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
return 0;
|
||||
}
|
||||
verbose(VERB_QUERY, "Reading root hints from %s", fname);
|
||||
memset(&pstate, 0, sizeof(pstate));
|
||||
pstate.lineno = 1;
|
||||
dp->has_parent_side_NS = 1;
|
||||
while(!feof(f)) {
|
||||
status = ldns_rr_new_frm_fp_l(&rr, f,
|
||||
&default_ttl, &origin, &prev_rr, &lineno);
|
||||
if(status == LDNS_STATUS_SYNTAX_EMPTY ||
|
||||
status == LDNS_STATUS_SYNTAX_TTL ||
|
||||
status == LDNS_STATUS_SYNTAX_ORIGIN)
|
||||
continue;
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("reading root hints %s %d: %s", fname,
|
||||
lineno, ldns_get_errorstr_by_id(status));
|
||||
rr_len = sizeof(rr);
|
||||
dname_len = 0;
|
||||
status = ldns_fp2wire_rr_buf(f, rr, &rr_len, &dname_len,
|
||||
&pstate);
|
||||
if(status != 0) {
|
||||
log_err("reading root hints %s %d:%d: %s", fname,
|
||||
pstate.lineno, LDNS_WIREPARSE_OFFSET(status),
|
||||
ldns_get_errorstr_parse(status));
|
||||
goto stop_read;
|
||||
}
|
||||
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
|
||||
if(!delegpt_add_ns_mlc(dp,
|
||||
ldns_rdf_data(ldns_rr_rdf(rr, 0)), 0)) {
|
||||
if(rr_len == 0)
|
||||
continue; /* EMPTY line, TTL or ORIGIN */
|
||||
if(ldns_wirerr_get_type(rr, rr_len, dname_len)
|
||||
== LDNS_RR_TYPE_NS) {
|
||||
if(!delegpt_add_ns_mlc(dp, ldns_wirerr_get_rdata(rr,
|
||||
rr_len, dname_len), 0)) {
|
||||
log_err("out of memory reading root hints");
|
||||
goto stop_read;
|
||||
}
|
||||
c = ldns_rr_get_class(rr);
|
||||
c = ldns_wirerr_get_class(rr, rr_len, dname_len);
|
||||
if(!dp->name) {
|
||||
if(!delegpt_set_name_mlc(dp,
|
||||
ldns_rdf_data(ldns_rr_owner(rr)))){
|
||||
if(!delegpt_set_name_mlc(dp, rr)) {
|
||||
log_err("out of memory.");
|
||||
goto stop_read;
|
||||
}
|
||||
}
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A) {
|
||||
} else if(ldns_wirerr_get_type(rr, rr_len, dname_len)
|
||||
== LDNS_RR_TYPE_A && ldns_wirerr_get_rdatalen(rr,
|
||||
rr_len, dname_len) == INET_SIZE) {
|
||||
struct sockaddr_in sa;
|
||||
socklen_t len = (socklen_t)sizeof(sa);
|
||||
memset(&sa, 0, len);
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
memmove(&sa.sin_addr,
|
||||
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET_SIZE);
|
||||
if(!delegpt_add_target_mlc(dp,
|
||||
ldns_rdf_data(ldns_rr_owner(rr)),
|
||||
ldns_rdf_size(ldns_rr_owner(rr)),
|
||||
ldns_wirerr_get_rdata(rr, rr_len, dname_len),
|
||||
INET_SIZE);
|
||||
if(!delegpt_add_target_mlc(dp, rr, dname_len,
|
||||
(struct sockaddr_storage*)&sa, len,
|
||||
0, 0)) {
|
||||
log_err("out of memory reading root hints");
|
||||
goto stop_read;
|
||||
}
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
|
||||
} else if(ldns_wirerr_get_type(rr, rr_len, dname_len)
|
||||
== LDNS_RR_TYPE_AAAA && ldns_wirerr_get_rdatalen(rr,
|
||||
rr_len, dname_len) == INET6_SIZE) {
|
||||
struct sockaddr_in6 sa;
|
||||
socklen_t len = (socklen_t)sizeof(sa);
|
||||
memset(&sa, 0, len);
|
||||
sa.sin6_family = AF_INET6;
|
||||
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
memmove(&sa.sin6_addr,
|
||||
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET6_SIZE);
|
||||
if(!delegpt_add_target_mlc(dp,
|
||||
ldns_rdf_data(ldns_rr_owner(rr)),
|
||||
ldns_rdf_size(ldns_rr_owner(rr)),
|
||||
ldns_wirerr_get_rdata(rr, rr_len, dname_len),
|
||||
INET6_SIZE);
|
||||
if(!delegpt_add_target_mlc(dp, rr, dname_len,
|
||||
(struct sockaddr_storage*)&sa, len,
|
||||
0, 0)) {
|
||||
log_err("out of memory reading root hints");
|
||||
goto stop_read;
|
||||
}
|
||||
} else {
|
||||
log_warn("root hints %s:%d skipping type %d",
|
||||
fname, lineno, ldns_rr_get_type(rr));
|
||||
char buf[17];
|
||||
ldns_wire2str_type_buf(ldns_wirerr_get_type(rr,
|
||||
rr_len, dname_len), buf, sizeof(buf));
|
||||
log_warn("root hints %s:%d skipping type %s",
|
||||
fname, pstate.lineno, buf);
|
||||
}
|
||||
|
||||
ldns_rr_free(rr);
|
||||
}
|
||||
|
||||
if (origin)
|
||||
ldns_rdf_deep_free(origin);
|
||||
if (prev_rr)
|
||||
ldns_rdf_deep_free(prev_rr);
|
||||
fclose(f);
|
||||
if(!dp->name) {
|
||||
log_warn("root hints %s: no NS content", fname);
|
||||
@ -384,10 +387,6 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
return 1;
|
||||
|
||||
stop_read:
|
||||
if (origin)
|
||||
ldns_rdf_deep_free(origin);
|
||||
if (prev_rr)
|
||||
ldns_rdf_deep_free(prev_rr);
|
||||
delegpt_free_mlc(dp);
|
||||
fclose(f);
|
||||
return 0;
|
||||
|
@ -41,7 +41,6 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ldns/dname.h>
|
||||
#include "iterator/iter_priv.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/log.h"
|
||||
@ -50,6 +49,8 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
struct iter_priv* priv_create(void)
|
||||
{
|
||||
@ -110,23 +111,21 @@ static int read_names(struct iter_priv* priv, struct config_file* cfg)
|
||||
/* parse names, report errors, insert into tree */
|
||||
struct config_strlist* p;
|
||||
struct name_tree_node* n;
|
||||
uint8_t* nm;
|
||||
uint8_t* nm, *nmr;
|
||||
size_t nm_len;
|
||||
int nm_labs;
|
||||
ldns_rdf* rdf;
|
||||
|
||||
for(p = cfg->private_domain; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
rdf = ldns_dname_new_frm_str(p->str);
|
||||
if(!rdf) {
|
||||
nm = ldns_str2wire_dname(p->str, &nm_len);
|
||||
if(!nm) {
|
||||
log_err("cannot parse private-domain: %s", p->str);
|
||||
return 0;
|
||||
}
|
||||
nm = ldns_rdf_data(rdf);
|
||||
nm_labs = dname_count_size_labels(nm, &nm_len);
|
||||
nm = (uint8_t*)regional_alloc_init(priv->region, nm, nm_len);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!nm) {
|
||||
nmr = (uint8_t*)regional_alloc_init(priv->region, nm, nm_len);
|
||||
free(nm);
|
||||
if(!nmr) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
@ -136,7 +135,7 @@ static int read_names(struct iter_priv* priv, struct config_file* cfg)
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(!name_tree_insert(&priv->n, n, nm, nm_len, nm_labs,
|
||||
if(!name_tree_insert(&priv->n, n, nmr, nm_len, nm_labs,
|
||||
LDNS_RR_CLASS_IN)) {
|
||||
verbose(VERB_QUERY, "ignoring duplicate "
|
||||
"private-domain: %s", p->str);
|
||||
|
@ -43,7 +43,7 @@
|
||||
#ifndef ITERATOR_ITER_PRIV_H
|
||||
#define ITERATOR_ITER_PRIV_H
|
||||
#include "util/rbtree.h"
|
||||
#include <ldns/buffer.h>
|
||||
struct ldns_buffer;
|
||||
struct iter_env;
|
||||
struct config_file;
|
||||
struct regional;
|
||||
@ -99,7 +99,7 @@ int priv_apply_cfg(struct iter_priv* priv, struct config_file* cfg);
|
||||
* @param rrset: the rrset to examine, A or AAAA.
|
||||
* @return true if the rrset is bad and should be removed.
|
||||
*/
|
||||
int priv_rrset_bad(struct iter_priv* priv, ldns_buffer* pkt,
|
||||
int priv_rrset_bad(struct iter_priv* priv, struct ldns_buffer* pkt,
|
||||
struct rrset_parse* rrset);
|
||||
|
||||
/**
|
||||
|
@ -40,12 +40,13 @@
|
||||
* one of the response types.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/packet.h>
|
||||
#include "iterator/iter_resptype.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/pkthdr.h"
|
||||
|
||||
enum response_type
|
||||
response_type_from_cache(struct dns_msg* msg,
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "util/data/dname.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/alloc.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
/** RRset flag used during scrubbing. The RRset is OK. */
|
||||
#define RRSET_SCRUB_OK 0x80
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef ITERATOR_ITER_SCRUB_H
|
||||
#define ITERATOR_ITER_SCRUB_H
|
||||
#include <ldns/buffer.h>
|
||||
struct ldns_buffer;
|
||||
struct msg_parse;
|
||||
struct query_info;
|
||||
struct regional;
|
||||
@ -62,7 +62,7 @@ struct iter_env;
|
||||
* @param ie: iterator module environment data.
|
||||
* @return: false if the message is total waste. true if scrubbed with success.
|
||||
*/
|
||||
int scrub_message(ldns_buffer* pkt, struct msg_parse* msg,
|
||||
int scrub_message(struct ldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct query_info* qinfo, uint8_t* zonename, struct regional* regional,
|
||||
struct module_env* env, struct iter_env* ie);
|
||||
|
||||
|
@ -63,6 +63,8 @@
|
||||
#include "validator/val_kcache.h"
|
||||
#include "validator/val_kentry.h"
|
||||
#include "validator/val_utils.h"
|
||||
#include "validator/val_sigcrypt.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
/** time when nameserver glue is said to be 'recent' */
|
||||
#define SUSPICION_RECENT_EXPIRY 86400
|
||||
@ -682,7 +684,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
|
||||
}
|
||||
|
||||
int
|
||||
reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch)
|
||||
reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
if(p->flags != q->flags ||
|
||||
@ -697,27 +699,12 @@ reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch)
|
||||
return 0;
|
||||
for(i=0; i<p->rrset_count; i++) {
|
||||
if(!rrset_equal(p->rrsets[i], q->rrsets[i])) {
|
||||
/* fallback procedure: try to sort and canonicalize */
|
||||
ldns_rr_list* pl, *ql;
|
||||
pl = packed_rrset_to_rr_list(p->rrsets[i], scratch);
|
||||
ql = packed_rrset_to_rr_list(q->rrsets[i], scratch);
|
||||
if(!pl || !ql) {
|
||||
ldns_rr_list_deep_free(pl);
|
||||
ldns_rr_list_deep_free(ql);
|
||||
if(!rrset_canonical_equal(region, p->rrsets[i],
|
||||
q->rrsets[i])) {
|
||||
regional_free_all(region);
|
||||
return 0;
|
||||
}
|
||||
ldns_rr_list2canonical(pl);
|
||||
ldns_rr_list2canonical(ql);
|
||||
ldns_rr_list_sort(pl);
|
||||
ldns_rr_list_sort(ql);
|
||||
if(ldns_rr_list_compare(pl, ql) != 0) {
|
||||
ldns_rr_list_deep_free(pl);
|
||||
ldns_rr_list_deep_free(ql);
|
||||
return 0;
|
||||
}
|
||||
ldns_rr_list_deep_free(pl);
|
||||
ldns_rr_list_deep_free(ql);
|
||||
continue;
|
||||
regional_free_all(region);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
@ -43,7 +43,7 @@
|
||||
#ifndef ITERATOR_ITER_UTILS_H
|
||||
#define ITERATOR_ITER_UTILS_H
|
||||
#include "iterator/iter_resptype.h"
|
||||
#include <ldns/buffer.h>
|
||||
struct ldns_buffer;
|
||||
struct iter_env;
|
||||
struct iter_hints;
|
||||
struct iter_forwards;
|
||||
@ -102,7 +102,7 @@ struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
|
||||
* @param regional: regional to use for allocation.
|
||||
* @return newly allocated dns_msg, or NULL on memory error.
|
||||
*/
|
||||
struct dns_msg* dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct dns_msg* dns_alloc_msg(struct ldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct regional* regional);
|
||||
|
||||
/**
|
||||
@ -216,10 +216,10 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
|
||||
* @param p: reply one. The reply has rrset data pointers in region.
|
||||
* Does not check rrset-IDs
|
||||
* @param q: reply two
|
||||
* @param buf: scratch buffer.
|
||||
* @param region: scratch buffer.
|
||||
* @return if one and two are equal.
|
||||
*/
|
||||
int reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* buf);
|
||||
int reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region);
|
||||
|
||||
/**
|
||||
* Store parent-side rrset in seperate rrset cache entries for later
|
||||
|
@ -41,7 +41,6 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
@ -62,6 +61,10 @@
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/config_file.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/wire2str.h"
|
||||
#include "ldns/parseutil.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
int
|
||||
iter_init(struct module_env* env, int id)
|
||||
@ -2815,7 +2818,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
} else {
|
||||
/* check if reply is the same, otherwise, fail */
|
||||
if(!reply_equal(iq->response->rep, iq->caps_reply,
|
||||
qstate->env->scratch_buffer)) {
|
||||
qstate->env->scratch)) {
|
||||
verbose(VERB_DETAIL, "Capsforid fallback: "
|
||||
"getting different replies, failed");
|
||||
outbound_list_remove(&iq->outlist, outbound);
|
||||
|
368
ldns/keyraw.c
Normal file
368
ldns/keyraw.c
Normal file
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* keyraw.c - raw key operations and conversions
|
||||
*
|
||||
* (c) NLnet Labs, 2004-2008
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Implementation of raw DNSKEY functions (work on wire rdata).
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/keyraw.h"
|
||||
#include "ldns/rrdef.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/md5.h>
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
# include <openssl/engine.h>
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
size_t
|
||||
ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
||||
const size_t len, int alg)
|
||||
{
|
||||
/* for DSA keys */
|
||||
uint8_t t;
|
||||
|
||||
/* for RSA keys */
|
||||
uint16_t exp;
|
||||
uint16_t int16;
|
||||
|
||||
switch ((ldns_algorithm)alg) {
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
if (len > 0) {
|
||||
t = keydata[0];
|
||||
return (64 + t*8)*8;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case LDNS_RSAMD5:
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_RSASHA256:
|
||||
case LDNS_RSASHA512:
|
||||
#endif
|
||||
if (len > 0) {
|
||||
if (keydata[0] == 0) {
|
||||
/* big exponent */
|
||||
if (len > 3) {
|
||||
memmove(&int16, keydata + 1, 2);
|
||||
exp = ntohs(int16);
|
||||
return (len - exp - 3)*8;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
exp = keydata[0];
|
||||
return (len-exp-1)*8;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_GOST
|
||||
case LDNS_ECC_GOST:
|
||||
return 512;
|
||||
#endif
|
||||
#ifdef USE_ECDSA
|
||||
case LDNS_ECDSAP256SHA256:
|
||||
return 256;
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
return 384;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize)
|
||||
{
|
||||
if(keysize < 4) {
|
||||
return 0;
|
||||
}
|
||||
/* look at the algorithm field, copied from 2535bis */
|
||||
if (key[3] == LDNS_RSAMD5) {
|
||||
uint16_t ac16 = 0;
|
||||
if (keysize > 4) {
|
||||
memmove(&ac16, key + keysize - 3, 2);
|
||||
}
|
||||
ac16 = ntohs(ac16);
|
||||
return (uint16_t) ac16;
|
||||
} else {
|
||||
size_t i;
|
||||
uint32_t ac32 = 0;
|
||||
for (i = 0; i < keysize; ++i) {
|
||||
ac32 += (i & 1) ? key[i] : key[i] << 8;
|
||||
}
|
||||
ac32 += (ac32 >> 16) & 0xFFFF;
|
||||
return (uint16_t) (ac32 & 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef USE_GOST
|
||||
/** store GOST engine reference loaded into OpenSSL library */
|
||||
ENGINE* ldns_gost_engine = NULL;
|
||||
|
||||
int
|
||||
ldns_key_EVP_load_gost_id(void)
|
||||
{
|
||||
static int gost_id = 0;
|
||||
const EVP_PKEY_ASN1_METHOD* meth;
|
||||
ENGINE* e;
|
||||
|
||||
if(gost_id) return gost_id;
|
||||
|
||||
/* see if configuration loaded gost implementation from other engine*/
|
||||
meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
|
||||
if(meth) {
|
||||
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
|
||||
return gost_id;
|
||||
}
|
||||
|
||||
/* see if engine can be loaded already */
|
||||
e = ENGINE_by_id("gost");
|
||||
if(!e) {
|
||||
/* load it ourself, in case statically linked */
|
||||
ENGINE_load_builtin_engines();
|
||||
ENGINE_load_dynamic();
|
||||
e = ENGINE_by_id("gost");
|
||||
}
|
||||
if(!e) {
|
||||
/* no gost engine in openssl */
|
||||
return 0;
|
||||
}
|
||||
if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
|
||||
ENGINE_finish(e);
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
|
||||
if(!meth) {
|
||||
/* algo not found */
|
||||
ENGINE_finish(e);
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
/* Note: do not ENGINE_finish and ENGINE_free the acquired engine
|
||||
* on some platforms this frees up the meth and unloads gost stuff */
|
||||
ldns_gost_engine = e;
|
||||
|
||||
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
|
||||
return gost_id;
|
||||
}
|
||||
|
||||
void ldns_key_EVP_unload_gost(void)
|
||||
{
|
||||
if(ldns_gost_engine) {
|
||||
ENGINE_finish(ldns_gost_engine);
|
||||
ENGINE_free(ldns_gost_engine);
|
||||
ldns_gost_engine = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* USE_GOST */
|
||||
|
||||
DSA *
|
||||
ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
|
||||
{
|
||||
uint8_t T;
|
||||
uint16_t length;
|
||||
uint16_t offset;
|
||||
DSA *dsa;
|
||||
BIGNUM *Q; BIGNUM *P;
|
||||
BIGNUM *G; BIGNUM *Y;
|
||||
|
||||
if(len == 0)
|
||||
return NULL;
|
||||
T = (uint8_t)key[0];
|
||||
length = (64 + T * 8);
|
||||
offset = 1;
|
||||
|
||||
if (T > 8) {
|
||||
return NULL;
|
||||
}
|
||||
if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
|
||||
return NULL;
|
||||
|
||||
Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
|
||||
offset += SHA_DIGEST_LENGTH;
|
||||
|
||||
P = BN_bin2bn(key+offset, (int)length, NULL);
|
||||
offset += length;
|
||||
|
||||
G = BN_bin2bn(key+offset, (int)length, NULL);
|
||||
offset += length;
|
||||
|
||||
Y = BN_bin2bn(key+offset, (int)length, NULL);
|
||||
offset += length;
|
||||
|
||||
/* create the key and set its properties */
|
||||
if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
|
||||
BN_free(Q);
|
||||
BN_free(P);
|
||||
BN_free(G);
|
||||
BN_free(Y);
|
||||
return NULL;
|
||||
}
|
||||
#ifndef S_SPLINT_S
|
||||
dsa->p = P;
|
||||
dsa->q = Q;
|
||||
dsa->g = G;
|
||||
dsa->pub_key = Y;
|
||||
#endif /* splint */
|
||||
|
||||
return dsa;
|
||||
}
|
||||
|
||||
RSA *
|
||||
ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
|
||||
{
|
||||
uint16_t offset;
|
||||
uint16_t exp;
|
||||
uint16_t int16;
|
||||
RSA *rsa;
|
||||
BIGNUM *modulus;
|
||||
BIGNUM *exponent;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
if (key[0] == 0) {
|
||||
if(len < 3)
|
||||
return NULL;
|
||||
memmove(&int16, key+1, 2);
|
||||
exp = ntohs(int16);
|
||||
offset = 3;
|
||||
} else {
|
||||
exp = key[0];
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
/* key length at least one */
|
||||
if(len < (size_t)offset + exp + 1)
|
||||
return NULL;
|
||||
|
||||
/* Exponent */
|
||||
exponent = BN_new();
|
||||
if(!exponent) return NULL;
|
||||
(void) BN_bin2bn(key+offset, (int)exp, exponent);
|
||||
offset += exp;
|
||||
|
||||
/* Modulus */
|
||||
modulus = BN_new();
|
||||
if(!modulus) {
|
||||
BN_free(exponent);
|
||||
return NULL;
|
||||
}
|
||||
/* length of the buffer must match the key length! */
|
||||
(void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
|
||||
|
||||
rsa = RSA_new();
|
||||
if(!rsa) {
|
||||
BN_free(exponent);
|
||||
BN_free(modulus);
|
||||
return NULL;
|
||||
}
|
||||
#ifndef S_SPLINT_S
|
||||
rsa->n = modulus;
|
||||
rsa->e = exponent;
|
||||
#endif /* splint */
|
||||
|
||||
return rsa;
|
||||
}
|
||||
|
||||
#ifdef USE_GOST
|
||||
EVP_PKEY*
|
||||
ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
|
||||
{
|
||||
/* prefix header for X509 encoding */
|
||||
uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
|
||||
0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
|
||||
0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
|
||||
0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
|
||||
unsigned char encoded[37+64];
|
||||
const unsigned char* pp;
|
||||
if(keylen != 64) {
|
||||
/* key wrong size */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create evp_key */
|
||||
memmove(encoded, asn, 37);
|
||||
memmove(encoded+37, key, 64);
|
||||
pp = (unsigned char*)&encoded[0];
|
||||
|
||||
return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
|
||||
}
|
||||
#endif /* USE_GOST */
|
||||
|
||||
#ifdef USE_ECDSA
|
||||
EVP_PKEY*
|
||||
ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
|
||||
{
|
||||
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
|
||||
const unsigned char* pp = buf;
|
||||
EVP_PKEY *evp_key;
|
||||
EC_KEY *ec;
|
||||
/* check length, which uncompressed must be 2 bignums */
|
||||
if(algo == LDNS_ECDSAP256SHA256) {
|
||||
if(keylen != 2*256/8) return NULL;
|
||||
ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
} else if(algo == LDNS_ECDSAP384SHA384) {
|
||||
if(keylen != 2*384/8) return NULL;
|
||||
ec = EC_KEY_new_by_curve_name(NID_secp384r1);
|
||||
} else ec = NULL;
|
||||
if(!ec) return NULL;
|
||||
if(keylen+1 > sizeof(buf))
|
||||
return NULL; /* sanity check */
|
||||
/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
|
||||
* of openssl) for uncompressed data */
|
||||
buf[0] = POINT_CONVERSION_UNCOMPRESSED;
|
||||
memmove(buf+1, key, keylen);
|
||||
if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
|
||||
EC_KEY_free(ec);
|
||||
return NULL;
|
||||
}
|
||||
evp_key = EVP_PKEY_new();
|
||||
if(!evp_key) {
|
||||
EC_KEY_free(ec);
|
||||
return NULL;
|
||||
}
|
||||
if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
|
||||
EVP_PKEY_free(evp_key);
|
||||
EC_KEY_free(ec);
|
||||
return NULL;
|
||||
}
|
||||
return evp_key;
|
||||
}
|
||||
#endif /* USE_ECDSA */
|
||||
|
||||
int
|
||||
ldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
|
||||
const EVP_MD* md)
|
||||
{
|
||||
EVP_MD_CTX* ctx;
|
||||
ctx = EVP_MD_CTX_create();
|
||||
if(!ctx)
|
||||
return 0;
|
||||
if(!EVP_DigestInit_ex(ctx, md, NULL) ||
|
||||
!EVP_DigestUpdate(ctx, data, len) ||
|
||||
!EVP_DigestFinal_ex(ctx, dest, NULL)) {
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
return 0;
|
||||
}
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
return 1;
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
112
ldns/keyraw.h
Normal file
112
ldns/keyraw.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* keyraw.h -- raw key and signature access and conversion
|
||||
*
|
||||
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* See LICENSE for the license.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* raw key and signature access and conversion
|
||||
*
|
||||
* Since those functions heavily rely op cryptographic operations,
|
||||
* this module is dependent on openssl.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LDNS_KEYRAW_H
|
||||
#define LDNS_KEYRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if LDNS_BUILD_CONFIG_HAVE_SSL
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/evp.h>
|
||||
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
|
||||
|
||||
/**
|
||||
* get the length of the keydata in bits
|
||||
* \param[in] keydata the raw key data
|
||||
* \param[in] len the length of the keydata
|
||||
* \param[in] alg the cryptographic algorithm this is a key for
|
||||
* \return the keysize in bits, or 0 on error
|
||||
*/
|
||||
size_t ldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
|
||||
const size_t len, int alg);
|
||||
|
||||
/**
|
||||
* Calculates keytag of DNSSEC key, operates on wireformat rdata.
|
||||
* \param[in] key the key as uncompressed wireformat rdata.
|
||||
* \param[in] keysize length of key data.
|
||||
* \return the keytag
|
||||
*/
|
||||
uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize);
|
||||
|
||||
#if LDNS_BUILD_CONFIG_HAVE_SSL
|
||||
/**
|
||||
* Get the PKEY id for GOST, loads GOST into openssl as a side effect.
|
||||
* Only available if GOST is compiled into the library and openssl.
|
||||
* \return the gost id for EVP_CTX creation.
|
||||
*/
|
||||
int ldns_key_EVP_load_gost_id(void);
|
||||
|
||||
/** Release the engine reference held for the GOST engine. */
|
||||
void ldns_key_EVP_unload_gost(void);
|
||||
|
||||
/**
|
||||
* Like ldns_key_buf2dsa, but uses raw buffer.
|
||||
* \param[in] key the uncompressed wireformat of the key.
|
||||
* \param[in] len length of key data
|
||||
* \return a DSA * structure with the key material
|
||||
*/
|
||||
DSA *ldns_key_buf2dsa_raw(unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
||||
* Only available if ldns was compiled with GOST.
|
||||
* \param[in] key data to convert
|
||||
* \param[in] keylen length of the key data
|
||||
* \return the key or NULL on error.
|
||||
*/
|
||||
EVP_PKEY* ldns_gost2pkey_raw(unsigned char* key, size_t keylen);
|
||||
|
||||
/**
|
||||
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
||||
* Only available if ldns was compiled with ECDSA.
|
||||
* \param[in] key data to convert
|
||||
* \param[in] keylen length of the key data
|
||||
* \param[in] algo precise algorithm to initialize ECC group values.
|
||||
* \return the key or NULL on error.
|
||||
*/
|
||||
EVP_PKEY* ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
|
||||
|
||||
/**
|
||||
* Like ldns_key_buf2rsa, but uses raw buffer.
|
||||
* \param[in] key the uncompressed wireformat of the key.
|
||||
* \param[in] len length of key data
|
||||
* \return a RSA * structure with the key material
|
||||
*/
|
||||
RSA *ldns_key_buf2rsa_raw(unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Utility function to calculate hash using generic EVP_MD pointer.
|
||||
* \param[in] data the data to hash.
|
||||
* \param[in] len length of data.
|
||||
* \param[out] dest the destination of the hash, must be large enough.
|
||||
* \param[in] md the message digest to use.
|
||||
* \return true if worked, false on failure.
|
||||
*/
|
||||
int ldns_digest_evp(unsigned char* data, unsigned int len,
|
||||
unsigned char* dest, const EVP_MD* md);
|
||||
|
||||
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LDNS_KEYRAW_H */
|
451
ldns/parse.c
Normal file
451
ldns/parse.c
Normal file
@ -0,0 +1,451 @@
|
||||
/*
|
||||
* a generic (simple) parser. Use to parse rr's, private key
|
||||
* information and /etc/resolv.conf files
|
||||
*
|
||||
* a Net::DNS like library for C
|
||||
* LibDNS Team @ NLnet Labs
|
||||
* (c) NLnet Labs, 2005-2006
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/parse.h"
|
||||
#include "ldns/parseutil.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <strings.h>
|
||||
|
||||
ldns_lookup_table ldns_directive_types[] = {
|
||||
{ LDNS_DIR_TTL, "$TTL" },
|
||||
{ LDNS_DIR_ORIGIN, "$ORIGIN" },
|
||||
{ LDNS_DIR_INCLUDE, "$INCLUDE" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/* add max_limit here? */
|
||||
ssize_t
|
||||
ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
|
||||
{
|
||||
return ldns_fget_token_l(f, token, delim, limit, NULL);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
|
||||
{
|
||||
int c, prev_c;
|
||||
int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
|
||||
int com, quoted;
|
||||
char *t;
|
||||
size_t i;
|
||||
const char *d;
|
||||
const char *del;
|
||||
|
||||
/* standard delimeters */
|
||||
if (!delim) {
|
||||
/* from isspace(3) */
|
||||
del = LDNS_PARSE_NORMAL;
|
||||
} else {
|
||||
del = delim;
|
||||
}
|
||||
|
||||
p = 0;
|
||||
i = 0;
|
||||
com = 0;
|
||||
quoted = 0;
|
||||
prev_c = 0;
|
||||
t = token;
|
||||
if (del[0] == '"') {
|
||||
quoted = 1;
|
||||
}
|
||||
while ((c = getc(f)) != EOF) {
|
||||
if (c == '\r') /* carriage return */
|
||||
c = ' ';
|
||||
if (c == '(' && prev_c != '\\' && !quoted) {
|
||||
/* this only counts for non-comments */
|
||||
if (com == 0) {
|
||||
p++;
|
||||
}
|
||||
prev_c = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ')' && prev_c != '\\' && !quoted) {
|
||||
/* this only counts for non-comments */
|
||||
if (com == 0) {
|
||||
p--;
|
||||
}
|
||||
prev_c = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p < 0) {
|
||||
/* more ) then ( - close off the string */
|
||||
*t = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do something with comments ; */
|
||||
if (c == ';' && quoted == 0) {
|
||||
if (prev_c != '\\') {
|
||||
com = 1;
|
||||
}
|
||||
}
|
||||
if (c == '\"' && com == 0 && prev_c != '\\') {
|
||||
quoted = 1 - quoted;
|
||||
}
|
||||
|
||||
if (c == '\n' && com != 0) {
|
||||
/* comments */
|
||||
com = 0;
|
||||
*t = ' ';
|
||||
if (line_nr) {
|
||||
*line_nr = *line_nr + 1;
|
||||
}
|
||||
if (p == 0 && i > 0) {
|
||||
goto tokenread;
|
||||
} else {
|
||||
prev_c = c;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (com == 1) {
|
||||
*t = ' ';
|
||||
prev_c = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\n' && p != 0 && t > token) {
|
||||
/* in parentheses */
|
||||
if (line_nr) {
|
||||
*line_nr = *line_nr + 1;
|
||||
}
|
||||
*t++ = ' ';
|
||||
prev_c = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check if we hit the delim */
|
||||
for (d = del; *d; d++) {
|
||||
if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
|
||||
if (c == '\n' && line_nr) {
|
||||
*line_nr = *line_nr + 1;
|
||||
}
|
||||
goto tokenread;
|
||||
}
|
||||
}
|
||||
if (c != '\0' && c != '\n') {
|
||||
i++;
|
||||
}
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
if (c != '\0' && c != '\n') {
|
||||
*t++ = c;
|
||||
}
|
||||
if (c == '\\' && prev_c == '\\')
|
||||
prev_c = 0;
|
||||
else prev_c = c;
|
||||
}
|
||||
*t = '\0';
|
||||
if (c == EOF) {
|
||||
return (ssize_t)i;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
/* nothing read */
|
||||
return -1;
|
||||
}
|
||||
if (p != 0) {
|
||||
return -1;
|
||||
}
|
||||
return (ssize_t)i;
|
||||
|
||||
tokenread:
|
||||
ldns_fskipcs_l(f, del, line_nr);
|
||||
*t = '\0';
|
||||
if (p != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (ssize_t)i;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
|
||||
const char *d_del, size_t data_limit)
|
||||
{
|
||||
return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
|
||||
data_limit, NULL);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data,
|
||||
const char *d_del, size_t data_limit, int *line_nr)
|
||||
{
|
||||
/* we assume: keyword|sep|data */
|
||||
char *fkeyword;
|
||||
ssize_t i;
|
||||
|
||||
if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
|
||||
return -1;
|
||||
fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN);
|
||||
if(!fkeyword)
|
||||
return -1;
|
||||
|
||||
i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
|
||||
if(i==0 || i==-1) {
|
||||
free(fkeyword);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* case??? i instead of strlen? */
|
||||
if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
|
||||
/* whee! */
|
||||
/* printf("%s\n%s\n", "Matching keyword", fkeyword); */
|
||||
i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
|
||||
free(fkeyword);
|
||||
return i;
|
||||
} else {
|
||||
/*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
|
||||
free(fkeyword);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
|
||||
{
|
||||
return ldns_bget_token_par(b, token, delim, limit, NULL, NULL);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ldns_bget_token_par(ldns_buffer *b, char *token, const char *delim,
|
||||
size_t limit, int* par, const char* skipw)
|
||||
{
|
||||
int c, lc;
|
||||
int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
|
||||
int com, quoted;
|
||||
char *t;
|
||||
size_t i;
|
||||
const char *d;
|
||||
const char *del;
|
||||
|
||||
/* standard delimiters */
|
||||
if (!delim) {
|
||||
/* from isspace(3) */
|
||||
del = LDNS_PARSE_NORMAL;
|
||||
} else {
|
||||
del = delim;
|
||||
}
|
||||
|
||||
p = (par?*par:0);
|
||||
i = 0;
|
||||
com = 0;
|
||||
quoted = 0;
|
||||
t = token;
|
||||
lc = 0;
|
||||
if (del[0] == '"') {
|
||||
quoted = 1;
|
||||
}
|
||||
|
||||
while ((c = ldns_bgetc(b)) != EOF) {
|
||||
if (c == '\r') /* carriage return */
|
||||
c = ' ';
|
||||
if (c == '(' && lc != '\\' && !quoted) {
|
||||
/* this only counts for non-comments */
|
||||
if (com == 0) {
|
||||
if(par) (*par)++;
|
||||
p++;
|
||||
}
|
||||
lc = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ')' && lc != '\\' && !quoted) {
|
||||
/* this only counts for non-comments */
|
||||
if (com == 0) {
|
||||
if(par) (*par)--;
|
||||
p--;
|
||||
}
|
||||
lc = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p < 0) {
|
||||
/* more ) then ( */
|
||||
*t = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do something with comments ; */
|
||||
if (c == ';' && quoted == 0) {
|
||||
if (lc != '\\') {
|
||||
com = 1;
|
||||
}
|
||||
}
|
||||
if (c == '"' && com == 0 && lc != '\\') {
|
||||
quoted = 1 - quoted;
|
||||
}
|
||||
|
||||
if (c == '\n' && com != 0) {
|
||||
/* comments */
|
||||
com = 0;
|
||||
*t = ' ';
|
||||
lc = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (com == 1) {
|
||||
*t = ' ';
|
||||
lc = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\n' && p != 0) {
|
||||
/* in parentheses */
|
||||
/* do not write ' ' if we want to skip spaces */
|
||||
if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' '))))
|
||||
*t++ = ' ';
|
||||
lc = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check to skip whitespace at start, but also after ( */
|
||||
if(skipw && i==0 && !com && !quoted && lc != '\\') {
|
||||
if(strchr(skipw, c)) {
|
||||
lc = c;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if we hit the delim */
|
||||
for (d = del; *d; d++) {
|
||||
/* we can only exit if no parens or user tracks them */
|
||||
if (c == *d && lc != '\\' && (p == 0 || par)) {
|
||||
goto tokenread;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
*t++ = c;
|
||||
|
||||
if (c == '\\' && lc == '\\') {
|
||||
lc = 0;
|
||||
} else {
|
||||
lc = c;
|
||||
}
|
||||
}
|
||||
*t = '\0';
|
||||
if (i == 0) {
|
||||
/* nothing read */
|
||||
return -1;
|
||||
}
|
||||
if (!par && p != 0) {
|
||||
return -1;
|
||||
}
|
||||
return (ssize_t)i;
|
||||
|
||||
tokenread:
|
||||
ldns_bskipcs(b, del);
|
||||
*t = '\0';
|
||||
|
||||
if (!par && p != 0) {
|
||||
return -1;
|
||||
}
|
||||
return (ssize_t)i;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ldns_bskipcs(ldns_buffer *buffer, const char *s)
|
||||
{
|
||||
int found;
|
||||
char c;
|
||||
const char *d;
|
||||
|
||||
while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
|
||||
c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
|
||||
found = 0;
|
||||
for (d = s; *d; d++) {
|
||||
if (*d == c) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (found && buffer->_limit > buffer->_position) {
|
||||
buffer->_position += sizeof(char);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ldns_fskipcs(FILE *fp, const char *s)
|
||||
{
|
||||
ldns_fskipcs_l(fp, s, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
|
||||
{
|
||||
int found;
|
||||
int c;
|
||||
const char *d;
|
||||
|
||||
while ((c = fgetc(fp)) != EOF) {
|
||||
if (line_nr && c == '\n') {
|
||||
*line_nr = *line_nr + 1;
|
||||
}
|
||||
found = 0;
|
||||
for (d = s; *d; d++) {
|
||||
if (*d == c) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
/* with getc, we've read too far */
|
||||
ungetc(c, fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char
|
||||
*data, const char *d_del, size_t data_limit)
|
||||
{
|
||||
/* we assume: keyword|sep|data */
|
||||
char *fkeyword;
|
||||
ssize_t i;
|
||||
|
||||
if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
|
||||
return -1;
|
||||
fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN);
|
||||
if(!fkeyword)
|
||||
return -1; /* out of memory */
|
||||
|
||||
i = ldns_bget_token(b, fkeyword, k_del, data_limit);
|
||||
if(i==0 || i==-1) {
|
||||
free(fkeyword);
|
||||
return -1; /* nothing read */
|
||||
}
|
||||
|
||||
/* case??? */
|
||||
if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
|
||||
free(fkeyword);
|
||||
/* whee, the match! */
|
||||
/* retrieve it's data */
|
||||
i = ldns_bget_token(b, data, d_del, 0);
|
||||
return i;
|
||||
} else {
|
||||
free(fkeyword);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
184
ldns/parse.h
Normal file
184
ldns/parse.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* parse.h
|
||||
*
|
||||
* a Net::DNS like library for C
|
||||
* LibDNS Team @ NLnet Labs
|
||||
* (c) NLnet Labs, 2005-2006
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
#ifndef LDNS_PARSE_H
|
||||
#define LDNS_PARSE_H
|
||||
|
||||
struct ldns_buffer;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LDNS_PARSE_SKIP_SPACE "\f\n\r\v"
|
||||
#define LDNS_PARSE_NORMAL " \f\n\r\t\v"
|
||||
#define LDNS_PARSE_NO_NL " \t"
|
||||
#define LDNS_MAX_LINELEN 10230
|
||||
#define LDNS_MAX_KEYWORDLEN 32
|
||||
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Contains some low-level parsing functions, mostly used in the _frm_str
|
||||
* family of functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* different type of directives in zone files
|
||||
* We now deal with $TTL, $ORIGIN and $INCLUDE.
|
||||
* The latter is not implemented in ldns (yet)
|
||||
*/
|
||||
enum ldns_enum_directive
|
||||
{
|
||||
LDNS_DIR_TTL,
|
||||
LDNS_DIR_ORIGIN,
|
||||
LDNS_DIR_INCLUDE
|
||||
};
|
||||
typedef enum ldns_enum_directive ldns_directive;
|
||||
|
||||
/**
|
||||
* returns a token/char from the stream F.
|
||||
* This function deals with ( and ) in the stream,
|
||||
* and ignores them when encountered
|
||||
* \param[in] *f the file to read from
|
||||
* \param[out] *token the read token is put here
|
||||
* \param[in] *delim chars at which the parsing should stop
|
||||
* \param[in] *limit how much to read. If 0 the builtin maximum is used
|
||||
* \return 0 on error of EOF of the stream F. Otherwise return the length of what is read
|
||||
*/
|
||||
ssize_t ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit);
|
||||
|
||||
/**
|
||||
* returns a token/char from the stream F.
|
||||
* This function deals with ( and ) in the stream,
|
||||
* and ignores when it finds them.
|
||||
* \param[in] *f the file to read from
|
||||
* \param[out] *token the token is put here
|
||||
* \param[in] *delim chars at which the parsing should stop
|
||||
* \param[in] *limit how much to read. If 0 use builtin maximum
|
||||
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
|
||||
* \return 0 on error of EOF of F otherwise return the length of what is read
|
||||
*/
|
||||
ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr);
|
||||
|
||||
/**
|
||||
* returns a token/char from the buffer b.
|
||||
* This function deals with ( and ) in the buffer,
|
||||
* and ignores when it finds them.
|
||||
* \param[in] *b the buffer to read from
|
||||
* \param[out] *token the token is put here
|
||||
* \param[in] *delim chars at which the parsing should stop
|
||||
* \param[in] *limit how much to read. If 0 the builtin maximum is used
|
||||
* \param[in] *par if you pass nonNULL, set to 0 on first call, the parenthesis
|
||||
* state is stored in it, for use on next call. User must check it is back
|
||||
* to zero after last bget in string (for parse error). If you pass NULL,
|
||||
* the entire parenthesized string is read in.
|
||||
* \param[in] skipw string with whitespace to skip before the start of the
|
||||
* token, like " ", or " \t", or NULL for none.
|
||||
* \returns 0 on error of EOF of b. Otherwise return the length of what is read
|
||||
*/
|
||||
ssize_t ldns_bget_token_par(struct ldns_buffer *b, char *token, const char *delim, size_t limit, int* par, const char* skipw);
|
||||
|
||||
/**
|
||||
* returns a token/char from the buffer b.
|
||||
* This function deals with ( and ) in the buffer,
|
||||
* and ignores when it finds them.
|
||||
* \param[in] *b the buffer to read from
|
||||
* \param[out] *token the token is put here
|
||||
* \param[in] *delim chars at which the parsing should stop
|
||||
* \param[in] *limit how much to read. If 0 the builtin maximum is used
|
||||
* \returns 0 on error of EOF of b. Otherwise return the length of what is read
|
||||
*/
|
||||
ssize_t ldns_bget_token(struct ldns_buffer *b, char *token, const char *delim, size_t limit);
|
||||
|
||||
/*
|
||||
* searches for keyword and delim in a file. Gives everything back
|
||||
* after the keyword + k_del until we hit d_del
|
||||
* \param[in] f file pointer to read from
|
||||
* \param[in] keyword keyword to look for
|
||||
* \param[in] k_del keyword delimeter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimeter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
|
||||
/*
|
||||
* searches for keyword and delim. Gives everything back
|
||||
* after the keyword + k_del until we hit d_del
|
||||
* \param[in] f file pointer to read from
|
||||
* \param[in] keyword keyword to look for
|
||||
* \param[in] k_del keyword delimeter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimeter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] line_nr pointer to an integer containing the current line number (for
|
||||
debugging purposes)
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit, int *line_nr);
|
||||
|
||||
/*
|
||||
* searches for keyword and delim in a buffer. Gives everything back
|
||||
* after the keyword + k_del until we hit d_del
|
||||
* \param[in] b buffer pointer to read from
|
||||
* \param[in] keyword keyword to look for
|
||||
* \param[in] k_del keyword delimeter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimeter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t ldns_bget_keyword_data(struct ldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
|
||||
/**
|
||||
* returns the next character from a buffer. Advances the position pointer with 1.
|
||||
* When end of buffer is reached returns EOF. This is the buffer's equivalent
|
||||
* for getc().
|
||||
* \param[in] *buffer buffer to read from
|
||||
* \return EOF on failure otherwise return the character
|
||||
*/
|
||||
int ldns_bgetc(struct ldns_buffer *buffer);
|
||||
|
||||
/**
|
||||
* skips all of the characters in the given string in the buffer, moving
|
||||
* the position to the first character that is not in *s.
|
||||
* \param[in] *buffer buffer to use
|
||||
* \param[in] *s characters to skip
|
||||
* \return void
|
||||
*/
|
||||
void ldns_bskipcs(struct ldns_buffer *buffer, const char *s);
|
||||
|
||||
/**
|
||||
* skips all of the characters in the given string in the fp, moving
|
||||
* the position to the first character that is not in *s.
|
||||
* \param[in] *fp file to use
|
||||
* \param[in] *s characters to skip
|
||||
* \return void
|
||||
*/
|
||||
void ldns_fskipcs(FILE *fp, const char *s);
|
||||
|
||||
|
||||
/**
|
||||
* skips all of the characters in the given string in the fp, moving
|
||||
* the position to the first character that is not in *s.
|
||||
* \param[in] *fp file to use
|
||||
* \param[in] *s characters to skip
|
||||
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
|
||||
* \return void
|
||||
*/
|
||||
void ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LDNS_PARSE_H */
|
726
ldns/parseutil.c
Normal file
726
ldns/parseutil.c
Normal file
@ -0,0 +1,726 @@
|
||||
/*
|
||||
* parseutil.c - parse utilities for string and wire conversion
|
||||
*
|
||||
* (c) NLnet Labs, 2004-2006
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Utility functions for parsing, base32(DNS variant) and base64 encoding
|
||||
* and decoding, Hex, Time units, Escape codes.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/parseutil.h"
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
ldns_lookup_table *
|
||||
ldns_lookup_by_name(ldns_lookup_table *table, const char *name)
|
||||
{
|
||||
while (table->name != NULL) {
|
||||
if (strcasecmp(name, table->name) == 0)
|
||||
return table;
|
||||
table++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ldns_lookup_table *
|
||||
ldns_lookup_by_id(ldns_lookup_table *table, int id)
|
||||
{
|
||||
while (table->name != NULL) {
|
||||
if (table->id == id)
|
||||
return table;
|
||||
table++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Number of days per month (except for February in leap years). */
|
||||
static const int mdays[] = {
|
||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
|
||||
#define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y)))
|
||||
#define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) - 1 ) : ((x) / (y)))
|
||||
|
||||
static int
|
||||
is_leap_year(int year)
|
||||
{
|
||||
return LDNS_MOD(year, 4) == 0 && (LDNS_MOD(year, 100) != 0
|
||||
|| LDNS_MOD(year, 400) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
leap_days(int y1, int y2)
|
||||
{
|
||||
--y1;
|
||||
--y2;
|
||||
return (LDNS_DIV(y2, 4) - LDNS_DIV(y1, 4)) -
|
||||
(LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) +
|
||||
(LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400));
|
||||
}
|
||||
|
||||
/*
|
||||
* Code adapted from Python 2.4.1 sources (Lib/calendar.py).
|
||||
*/
|
||||
time_t
|
||||
ldns_mktime_from_utc(const struct tm *tm)
|
||||
{
|
||||
int year = 1900 + tm->tm_year;
|
||||
time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
|
||||
time_t hours;
|
||||
time_t minutes;
|
||||
time_t seconds;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tm->tm_mon; ++i) {
|
||||
days += mdays[i];
|
||||
}
|
||||
if (tm->tm_mon > 1 && is_leap_year(year)) {
|
||||
++days;
|
||||
}
|
||||
days += tm->tm_mday - 1;
|
||||
|
||||
hours = days * 24 + tm->tm_hour;
|
||||
minutes = hours * 60 + tm->tm_min;
|
||||
seconds = minutes * 60 + tm->tm_sec;
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
#if SIZEOF_TIME_T <= 4
|
||||
|
||||
static void
|
||||
ldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result)
|
||||
{
|
||||
int year = 1970;
|
||||
int new_year;
|
||||
|
||||
while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) {
|
||||
new_year = year + (int) LDNS_DIV(days, 365);
|
||||
days -= (new_year - year) * 365;
|
||||
days -= leap_days(year, new_year);
|
||||
year = new_year;
|
||||
}
|
||||
result->tm_year = year;
|
||||
result->tm_yday = (int) days;
|
||||
}
|
||||
|
||||
/* Number of days per month in a leap year. */
|
||||
static const int leap_year_mdays[] = {
|
||||
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
|
||||
static void
|
||||
ldns_mon_and_mday_from_year_and_yday(struct tm *result)
|
||||
{
|
||||
int idays = result->tm_yday;
|
||||
const int *mon_lengths = is_leap_year(result->tm_year) ?
|
||||
leap_year_mdays : mdays;
|
||||
|
||||
result->tm_mon = 0;
|
||||
while (idays >= mon_lengths[result->tm_mon]) {
|
||||
idays -= mon_lengths[result->tm_mon++];
|
||||
}
|
||||
result->tm_mday = idays + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ldns_wday_from_year_and_yday(struct tm *result)
|
||||
{
|
||||
result->tm_wday = 4 /* 1-1-1970 was a thursday */
|
||||
+ LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7)
|
||||
+ leap_days(1970, result->tm_year)
|
||||
+ result->tm_yday;
|
||||
result->tm_wday = LDNS_MOD(result->tm_wday, 7);
|
||||
if (result->tm_wday < 0) {
|
||||
result->tm_wday += 7;
|
||||
}
|
||||
}
|
||||
|
||||
static struct tm *
|
||||
ldns_gmtime64_r(int64_t clock, struct tm *result)
|
||||
{
|
||||
result->tm_isdst = 0;
|
||||
result->tm_sec = (int) LDNS_MOD(clock, 60);
|
||||
clock = LDNS_DIV(clock, 60);
|
||||
result->tm_min = (int) LDNS_MOD(clock, 60);
|
||||
clock = LDNS_DIV(clock, 60);
|
||||
result->tm_hour = (int) LDNS_MOD(clock, 24);
|
||||
clock = LDNS_DIV(clock, 24);
|
||||
|
||||
ldns_year_and_yday_from_days_since_epoch(clock, result);
|
||||
ldns_mon_and_mday_from_year_and_yday(result);
|
||||
ldns_wday_from_year_and_yday(result);
|
||||
result->tm_year -= 1900;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* SIZEOF_TIME_T <= 4 */
|
||||
|
||||
static int64_t
|
||||
ldns_serial_arithmitics_time(int32_t time, time_t now)
|
||||
{
|
||||
int32_t offset = time - (int32_t) now;
|
||||
return (int64_t) now + offset;
|
||||
}
|
||||
|
||||
struct tm *
|
||||
ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result)
|
||||
{
|
||||
#if SIZEOF_TIME_T <= 4
|
||||
int64_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
|
||||
return ldns_gmtime64_r(secs_since_epoch, result);
|
||||
#else
|
||||
time_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
|
||||
return gmtime_r(&secs_since_epoch, result);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
ldns_hexdigit_to_int(char ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a': case 'A': return 10;
|
||||
case 'b': case 'B': return 11;
|
||||
case 'c': case 'C': return 12;
|
||||
case 'd': case 'D': return 13;
|
||||
case 'e': case 'E': return 14;
|
||||
case 'f': case 'F': return 15;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ldns_str2period(const char *nptr, const char **endptr)
|
||||
{
|
||||
int sign = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t seconds = 0;
|
||||
|
||||
for(*endptr = nptr; **endptr; (*endptr)++) {
|
||||
switch (**endptr) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
break;
|
||||
case '-':
|
||||
if(sign == 0) {
|
||||
sign = -1;
|
||||
} else {
|
||||
return seconds;
|
||||
}
|
||||
break;
|
||||
case '+':
|
||||
if(sign == 0) {
|
||||
sign = 1;
|
||||
} else {
|
||||
return seconds;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
seconds += i;
|
||||
i = 0;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
seconds += i * 60;
|
||||
i = 0;
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
seconds += i * 60 * 60;
|
||||
i = 0;
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
seconds += i * 60 * 60 * 24;
|
||||
i = 0;
|
||||
break;
|
||||
case 'w':
|
||||
case 'W':
|
||||
seconds += i * 60 * 60 * 24 * 7;
|
||||
i = 0;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
i *= 10;
|
||||
i += (**endptr - '0');
|
||||
break;
|
||||
default:
|
||||
seconds += i;
|
||||
/* disregard signedness */
|
||||
return seconds;
|
||||
}
|
||||
}
|
||||
seconds += i;
|
||||
/* disregard signedness */
|
||||
return seconds;
|
||||
}
|
||||
|
||||
int
|
||||
ldns_parse_escape(uint8_t *ch_p, const char** str_p)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
if ((*str_p)[0] && isdigit((*str_p)[0]) &&
|
||||
(*str_p)[1] && isdigit((*str_p)[1]) &&
|
||||
(*str_p)[2] && isdigit((*str_p)[2])) {
|
||||
|
||||
val = (uint16_t)(((*str_p)[0] - '0') * 100 +
|
||||
((*str_p)[1] - '0') * 10 +
|
||||
((*str_p)[2] - '0'));
|
||||
|
||||
if (val > 255) {
|
||||
goto error;
|
||||
}
|
||||
*ch_p = (uint8_t)val;
|
||||
*str_p += 3;
|
||||
return 1;
|
||||
|
||||
} else if ((*str_p)[0] && !isdigit((*str_p)[0])) {
|
||||
|
||||
*ch_p = (uint8_t)*(*str_p)++;
|
||||
return 1;
|
||||
}
|
||||
error:
|
||||
*str_p = NULL;
|
||||
return 0; /* LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE */
|
||||
}
|
||||
|
||||
/** parse one character, with escape codes */
|
||||
int
|
||||
ldns_parse_char(uint8_t *ch_p, const char** str_p)
|
||||
{
|
||||
switch (**str_p) {
|
||||
|
||||
case '\0': return 0;
|
||||
|
||||
case '\\': *str_p += 1;
|
||||
return ldns_parse_escape(ch_p, str_p);
|
||||
|
||||
default: *ch_p = (uint8_t)*(*str_p)++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ldns_b32_ntop_calculate_size(size_t src_data_length)
|
||||
{
|
||||
return src_data_length == 0 ? 0 : ((src_data_length - 1) / 5 + 1) * 8;
|
||||
}
|
||||
|
||||
size_t ldns_b32_ntop_calculate_size_no_padding(size_t src_data_length)
|
||||
{
|
||||
return ((src_data_length + 3) * 8 / 5) - 4;
|
||||
}
|
||||
|
||||
static int
|
||||
ldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||
int extended_hex, int add_padding)
|
||||
{
|
||||
size_t ret_sz;
|
||||
const char* b32 = extended_hex ? "0123456789abcdefghijklmnopqrstuv"
|
||||
: "abcdefghijklmnopqrstuvwxyz234567";
|
||||
|
||||
size_t c = 0; /* c is used to carry partial base32 character over
|
||||
* byte boundaries for sizes with a remainder.
|
||||
* (i.e. src_sz % 5 != 0)
|
||||
*/
|
||||
|
||||
ret_sz = add_padding ? ldns_b32_ntop_calculate_size(src_sz)
|
||||
: ldns_b32_ntop_calculate_size_no_padding(src_sz);
|
||||
|
||||
/* Do we have enough space? */
|
||||
if (dst_sz < ret_sz + 1)
|
||||
return -1;
|
||||
|
||||
/* We know the size; terminate the string */
|
||||
dst[ret_sz] = '\0';
|
||||
|
||||
/* First process all chunks of five */
|
||||
while (src_sz >= 5) {
|
||||
/* 00000... ........ ........ ........ ........ */
|
||||
dst[0] = b32[(src[0] ) >> 3];
|
||||
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
dst[1] = b32[(src[0] & 0x07) << 2 | src[1] >> 6];
|
||||
|
||||
/* ........ ..22222. ........ ........ ........ */
|
||||
dst[2] = b32[(src[1] & 0x3e) >> 1];
|
||||
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
dst[3] = b32[(src[1] & 0x01) << 4 | src[2] >> 4];
|
||||
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
dst[4] = b32[(src[2] & 0x0f) << 1 | src[3] >> 7];
|
||||
|
||||
/* ........ ........ ........ .55555.. ........ */
|
||||
dst[5] = b32[(src[3] & 0x7c) >> 2];
|
||||
|
||||
/* ........ ........ ........ ......66 666..... */
|
||||
dst[6] = b32[(src[3] & 0x03) << 3 | src[4] >> 5];
|
||||
|
||||
/* ........ ........ ........ ........ ...77777 */
|
||||
dst[7] = b32[(src[4] & 0x1f) ];
|
||||
|
||||
src_sz -= 5;
|
||||
src += 5;
|
||||
dst += 8;
|
||||
}
|
||||
/* Process what remains */
|
||||
switch (src_sz) {
|
||||
case 4: /* ........ ........ ........ ......66 666..... */
|
||||
dst[6] = b32[(src[3] & 0x03) << 3];
|
||||
|
||||
/* ........ ........ ........ .55555.. ........ */
|
||||
dst[5] = b32[(src[3] & 0x7c) >> 2];
|
||||
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
c = src[3] >> 7 ;
|
||||
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
|
||||
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
c = src[2] >> 4 ;
|
||||
case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
|
||||
|
||||
/* ........ ..22222. ........ ........ ........ */
|
||||
dst[2] = b32[(src[1] & 0x3e) >> 1];
|
||||
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
c = src[1] >> 6 ;
|
||||
case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
|
||||
|
||||
/* 00000... ........ ........ ........ ........ */
|
||||
dst[0] = b32[ src[0] >> 3];
|
||||
}
|
||||
/* Add padding */
|
||||
if (add_padding) {
|
||||
switch (src_sz) {
|
||||
case 1: dst[2] = '=';
|
||||
dst[3] = '=';
|
||||
case 2: dst[4] = '=';
|
||||
case 3: dst[5] = '=';
|
||||
dst[6] = '=';
|
||||
case 4: dst[7] = '=';
|
||||
}
|
||||
}
|
||||
return (int)ret_sz;
|
||||
}
|
||||
|
||||
int
|
||||
ldns_b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
|
||||
{
|
||||
return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, 0, 1);
|
||||
}
|
||||
|
||||
int
|
||||
ldns_b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
|
||||
char* dst, size_t dst_sz)
|
||||
{
|
||||
return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, 1, 1);
|
||||
}
|
||||
|
||||
size_t ldns_b32_pton_calculate_size(size_t src_text_length)
|
||||
{
|
||||
return src_text_length * 5 / 8;
|
||||
}
|
||||
|
||||
static int
|
||||
ldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
|
||||
int extended_hex, int check_padding)
|
||||
{
|
||||
size_t i = 0;
|
||||
char ch = '\0';
|
||||
uint8_t buf[8];
|
||||
uint8_t* start = dst;
|
||||
|
||||
while (src_sz) {
|
||||
/* Collect 8 characters in buf (if possible) */
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
||||
do {
|
||||
ch = *src++;
|
||||
--src_sz;
|
||||
|
||||
} while (isspace(ch) && src_sz > 0);
|
||||
|
||||
if (ch == '=' || ch == '\0')
|
||||
break;
|
||||
|
||||
else if (extended_hex)
|
||||
|
||||
if (ch >= '0' && ch <= '9')
|
||||
buf[i] = (uint8_t)ch - '0';
|
||||
else if (ch >= 'a' && ch <= 'v')
|
||||
buf[i] = (uint8_t)ch - 'a' + 10;
|
||||
else if (ch >= 'A' && ch <= 'V')
|
||||
buf[i] = (uint8_t)ch - 'A' + 10;
|
||||
else
|
||||
return -1;
|
||||
|
||||
else if (ch >= 'a' && ch <= 'z')
|
||||
buf[i] = (uint8_t)ch - 'a';
|
||||
else if (ch >= 'A' && ch <= 'Z')
|
||||
buf[i] = (uint8_t)ch - 'A';
|
||||
else if (ch >= '2' && ch <= '7')
|
||||
buf[i] = (uint8_t)ch - '2' + 26;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
/* Less that 8 characters. We're done. */
|
||||
if (i < 8)
|
||||
break;
|
||||
|
||||
/* Enough space available at the destination? */
|
||||
if (dst_sz < 5)
|
||||
return -1;
|
||||
|
||||
/* 00000... ........ ........ ........ ........ */
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
dst[0] = buf[0] << 3 | buf[1] >> 2;
|
||||
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
/* ........ ..22222. ........ ........ ........ */
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
|
||||
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
dst[2] = buf[3] << 4 | buf[4] >> 1;
|
||||
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
/* ........ ........ ........ .55555.. ........ */
|
||||
/* ........ ........ ........ ......66 666..... */
|
||||
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
|
||||
|
||||
/* ........ ........ ........ ......66 666..... */
|
||||
/* ........ ........ ........ ........ ...77777 */
|
||||
dst[4] = buf[6] << 5 | buf[7];
|
||||
|
||||
dst += 5;
|
||||
dst_sz -= 5;
|
||||
}
|
||||
/* Not ending on a eight byte boundary? */
|
||||
if (i > 0 && i < 8) {
|
||||
|
||||
/* Enough space available at the destination? */
|
||||
if (dst_sz < (i + 1) / 2)
|
||||
return -1;
|
||||
|
||||
switch (i) {
|
||||
case 7: /* ........ ........ ........ ......66 666..... */
|
||||
/* ........ ........ ........ .55555.. ........ */
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
|
||||
|
||||
case 5: /* ........ ........ ....4444 4....... ........ */
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
dst[2] = buf[3] << 4 | buf[4] >> 1;
|
||||
|
||||
case 4: /* ........ .......3 3333.... ........ ........ */
|
||||
/* ........ ..22222. ........ ........ ........ */
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
|
||||
|
||||
case 2: /* .....111 11...... ........ ........ ........ */
|
||||
/* 00000... ........ ........ ........ ........ */
|
||||
dst[0] = buf[0] << 3 | buf[1] >> 2;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
dst += (i + 1) / 2;
|
||||
|
||||
if (check_padding) {
|
||||
/* Check remaining padding characters */
|
||||
if (ch != '=')
|
||||
return -1;
|
||||
|
||||
/* One down, 8 - i - 1 more to come... */
|
||||
for (i = 8 - i - 1; i > 0; i--) {
|
||||
|
||||
do {
|
||||
if (src_sz == 0)
|
||||
return -1;
|
||||
ch = *src++;
|
||||
src_sz--;
|
||||
|
||||
} while (isspace(ch));
|
||||
|
||||
if (ch != '=')
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dst - start;
|
||||
}
|
||||
|
||||
int
|
||||
ldns_b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
|
||||
{
|
||||
return ldns_b32_pton_base(src, src_sz, dst, dst_sz, 0, 1);
|
||||
}
|
||||
|
||||
int
|
||||
ldns_b32_pton_extended_hex(const char* src, size_t src_sz,
|
||||
uint8_t* dst, size_t dst_sz)
|
||||
{
|
||||
return ldns_b32_pton_base(src, src_sz, dst, dst_sz, 1, 1);
|
||||
}
|
||||
|
||||
size_t ldns_b64_ntop_calculate_size(size_t srcsize)
|
||||
{
|
||||
return ((((srcsize + 2) / 3) * 4) + 1);
|
||||
}
|
||||
|
||||
/* RFC 1521, section 5.2.
|
||||
*
|
||||
* The encoding process represents 24-bit groups of input bits as output
|
||||
* strings of 4 encoded characters. Proceeding from left to right, a
|
||||
* 24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
* These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
* of which is translated into a single digit in the base64 alphabet.
|
||||
*
|
||||
* This routine does not insert spaces or linebreaks after 76 characters.
|
||||
*/
|
||||
int ldns_b64_ntop(uint8_t const *src, size_t srclength,
|
||||
char *target, size_t targsize)
|
||||
{
|
||||
const char* b64 =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const char pad64 = '=';
|
||||
size_t i = 0, o = 0;
|
||||
if(targsize < ldns_b64_ntop_calculate_size(srclength))
|
||||
return -1;
|
||||
/* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */
|
||||
while(i+3 <= srclength) {
|
||||
if(o+4 > targsize) return -1;
|
||||
target[o] = b64[src[i] >> 2];
|
||||
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
|
||||
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) | (src[i+2]>>6) ];
|
||||
target[o+3] = b64[ (src[i+2]&0x3f) ];
|
||||
i += 3;
|
||||
o += 4;
|
||||
}
|
||||
/* remainder */
|
||||
switch(srclength - i) {
|
||||
case 2:
|
||||
/* two at end, converted into A B C = */
|
||||
target[o] = b64[src[i] >> 2];
|
||||
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
|
||||
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ];
|
||||
target[o+3] = pad64;
|
||||
i += 2;
|
||||
o += 4;
|
||||
break;
|
||||
case 1:
|
||||
/* one at end, converted into A B = = */
|
||||
target[o] = b64[src[i] >> 2];
|
||||
target[o+1] = b64[ ((src[i]&0x03)<<4) ];
|
||||
target[o+2] = pad64;
|
||||
target[o+3] = pad64;
|
||||
i += 1;
|
||||
o += 4;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* nothing */
|
||||
break;
|
||||
}
|
||||
/* assert: i == srclength */
|
||||
if(o+1 > targsize) return -1;
|
||||
target[o] = 0;
|
||||
return (int)o;
|
||||
}
|
||||
|
||||
size_t ldns_b64_pton_calculate_size(size_t srcsize)
|
||||
{
|
||||
return (((((srcsize + 3) / 4) * 3)) + 1);
|
||||
}
|
||||
|
||||
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
|
||||
{
|
||||
const uint8_t pad64 = 64; /* is 64th in the b64 array */
|
||||
const char* s = src;
|
||||
uint8_t in[4];
|
||||
size_t o = 0, incount = 0;
|
||||
|
||||
while(*s) {
|
||||
/* skip any character that is not base64 */
|
||||
/* conceptually we do:
|
||||
const char* b64 = pad'=' is appended to array
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
const char* d = strchr(b64, *s++);
|
||||
and use d-b64;
|
||||
*/
|
||||
char d = *s++;
|
||||
if(d <= 'Z' && d >= 'A')
|
||||
d -= 'A';
|
||||
else if(d <= 'z' && d >= 'a')
|
||||
d = d - 'a' + 26;
|
||||
else if(d <= '9' && d >= '0')
|
||||
d = d - '0' + 52;
|
||||
else if(d == '+')
|
||||
d = 62;
|
||||
else if(d == '/')
|
||||
d = 63;
|
||||
else if(d == '=')
|
||||
d = 64;
|
||||
else continue;
|
||||
in[incount++] = (uint8_t)d;
|
||||
if(incount != 4)
|
||||
continue;
|
||||
/* process whole block of 4 characters into 3 output bytes */
|
||||
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */
|
||||
if(o+1 > targsize)
|
||||
return -1;
|
||||
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
|
||||
o += 1;
|
||||
break; /* we are done */
|
||||
} else if(in[3] == pad64) { /* A B C = */
|
||||
if(o+2 > targsize)
|
||||
return -1;
|
||||
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
|
||||
target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2);
|
||||
o += 2;
|
||||
break; /* we are done */
|
||||
} else {
|
||||
if(o+3 > targsize)
|
||||
return -1;
|
||||
/* write xxxxxxyy yyyyzzzz zzwwwwww */
|
||||
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
|
||||
target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2);
|
||||
target[o+2]= ((in[2]&0x03)<<6) | in[3];
|
||||
o += 3;
|
||||
}
|
||||
incount = 0;
|
||||
}
|
||||
return (int)o;
|
||||
}
|
148
ldns/parseutil.h
Normal file
148
ldns/parseutil.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* parseutil.h - parse utilities for string and wire conversion
|
||||
*
|
||||
* (c) NLnet Labs, 2004
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Utility functions for parsing, base32(DNS variant) and base64 encoding
|
||||
* and decoding, Hex, Time units, Escape codes.
|
||||
*/
|
||||
|
||||
#ifndef LDNS_PARSEUTIL_H
|
||||
#define LDNS_PARSEUTIL_H
|
||||
struct tm;
|
||||
|
||||
/**
|
||||
* A general purpose lookup table
|
||||
*
|
||||
* Lookup tables are arrays of (id, name) pairs,
|
||||
* So you can for instance lookup the RCODE 3, which is "NXDOMAIN",
|
||||
* and vice versa. The lookup tables themselves are defined wherever needed,
|
||||
* for instance in host2str.c
|
||||
*/
|
||||
struct ldns_struct_lookup_table {
|
||||
int id;
|
||||
const char *name;
|
||||
};
|
||||
typedef struct ldns_struct_lookup_table ldns_lookup_table;
|
||||
|
||||
/**
|
||||
* Looks up the table entry by name, returns NULL if not found.
|
||||
* \param[in] table the lookup table to search in
|
||||
* \param[in] name what to search for
|
||||
* \return the item found
|
||||
*/
|
||||
ldns_lookup_table *ldns_lookup_by_name(ldns_lookup_table table[],
|
||||
const char *name);
|
||||
/**
|
||||
* Looks up the table entry by id, returns NULL if not found.
|
||||
* \param[in] table the lookup table to search in
|
||||
* \param[in] id what to search for
|
||||
* \return the item found
|
||||
*/
|
||||
ldns_lookup_table *ldns_lookup_by_id(ldns_lookup_table table[], int id);
|
||||
|
||||
/**
|
||||
* Convert TM to seconds since epoch (midnight, January 1st, 1970).
|
||||
* Like timegm(3), which is not always available.
|
||||
* \param[in] tm a struct tm* with the date
|
||||
* \return the seconds since epoch
|
||||
*/
|
||||
time_t ldns_mktime_from_utc(const struct tm *tm);
|
||||
|
||||
/**
|
||||
* The function interprets time as the number of seconds since epoch
|
||||
* with respect to now using serial arithmitics (rfc1982).
|
||||
* That number of seconds is then converted to broken-out time information.
|
||||
* This is especially usefull when converting the inception and expiration
|
||||
* fields of RRSIG records.
|
||||
*
|
||||
* \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
|
||||
* to be intepreted as a serial arithmitics number relative to now.
|
||||
* \param[in] now number of seconds since epoch (midnight, January 1st, 1970)
|
||||
* to which the time value is compared to determine the final value.
|
||||
* \param[out] result the struct with the broken-out time information
|
||||
* \return result on success or NULL on error
|
||||
*/
|
||||
struct tm * ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result);
|
||||
|
||||
/**
|
||||
* converts a ttl value (like 5d2h) to a long.
|
||||
* \param[in] nptr the start of the string
|
||||
* \param[out] endptr points to the last char in case of error
|
||||
* \return the convert duration value
|
||||
*/
|
||||
uint32_t ldns_str2period(const char *nptr, const char **endptr);
|
||||
|
||||
/**
|
||||
* Returns the int value of the given (hex) digit
|
||||
* \param[in] ch the hex char to convert
|
||||
* \return the converted decimal value
|
||||
*/
|
||||
int ldns_hexdigit_to_int(char ch);
|
||||
|
||||
/**
|
||||
* calculates the size needed to store the result of b64_ntop
|
||||
*/
|
||||
size_t ldns_b64_ntop_calculate_size(size_t srcsize);
|
||||
|
||||
int ldns_b64_ntop(uint8_t const *src, size_t srclength,
|
||||
char *target, size_t targsize);
|
||||
|
||||
/**
|
||||
* calculates the size needed to store the result of ldns_b64_pton
|
||||
*/
|
||||
size_t ldns_b64_pton_calculate_size(size_t srcsize);
|
||||
|
||||
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
|
||||
|
||||
/**
|
||||
* calculates the size needed to store the result of b32_ntop
|
||||
*/
|
||||
size_t ldns_b32_ntop_calculate_size(size_t src_data_length);
|
||||
|
||||
size_t ldns_b32_ntop_calculate_size_no_padding(size_t src_data_length);
|
||||
|
||||
int ldns_b32_ntop(const uint8_t* src_data, size_t src_data_length,
|
||||
char* target_text_buffer, size_t target_text_buffer_size);
|
||||
|
||||
int ldns_b32_ntop_extended_hex(const uint8_t* src_data, size_t src_data_length,
|
||||
char* target_text_buffer, size_t target_text_buffer_size);
|
||||
|
||||
/**
|
||||
* calculates the size needed to store the result of b32_pton
|
||||
*/
|
||||
size_t ldns_b32_pton_calculate_size(size_t src_text_length);
|
||||
|
||||
int ldns_b32_pton(const char* src_text, size_t src_text_length,
|
||||
uint8_t* target_data_buffer, size_t target_data_buffer_size);
|
||||
|
||||
int ldns_b32_pton_extended_hex(const char* src_text, size_t src_text_length,
|
||||
uint8_t* target_data_buffer, size_t target_data_buffer_size);
|
||||
|
||||
/*
|
||||
* Checks whether the escaped value at **s is an octal value or
|
||||
* a 'normally' escaped character (and not eos)
|
||||
*
|
||||
* @param ch_p: the parsed character
|
||||
* @param str_p: the string. moved along for characters read.
|
||||
* The string pointer at *s is increased by either 0 (on error), 1 (on
|
||||
* normal escapes), or 3 (on octals)
|
||||
*
|
||||
* @return 0 on error
|
||||
*/
|
||||
int ldns_parse_escape(uint8_t *ch_p, const char** str_p);
|
||||
|
||||
/**
|
||||
* Parse one character, with escape codes,
|
||||
* @param ch_p: the parsed character
|
||||
* @param str_p: the string. moved along for characters read.
|
||||
* @return 0 on error
|
||||
*/
|
||||
int ldns_parse_char(uint8_t *ch_p, const char** str_p);
|
||||
|
||||
#endif /* LDNS_PARSEUTIL_H */
|
158
ldns/pkthdr.h
Normal file
158
ldns/pkthdr.h
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* pkthdr.h - packet header from wire conversion routines
|
||||
*
|
||||
* a Net::DNS like library for C
|
||||
*
|
||||
* (c) NLnet Labs, 2005-2006
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Contains functions that translate dns data from the wire format (as sent
|
||||
* by servers and clients) to the internal structures for the packet header.
|
||||
*/
|
||||
|
||||
#ifndef LDNS_PKTHDR_H
|
||||
#define LDNS_PKTHDR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The length of the header */
|
||||
#define LDNS_HEADER_SIZE 12
|
||||
|
||||
/* First octet of flags */
|
||||
#define LDNS_RD_MASK 0x01U
|
||||
#define LDNS_RD_SHIFT 0
|
||||
#define LDNS_RD_WIRE(wirebuf) (*(wirebuf+2) & LDNS_RD_MASK)
|
||||
#define LDNS_RD_SET(wirebuf) (*(wirebuf+2) |= LDNS_RD_MASK)
|
||||
#define LDNS_RD_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_RD_MASK)
|
||||
|
||||
#define LDNS_TC_MASK 0x02U
|
||||
#define LDNS_TC_SHIFT 1
|
||||
#define LDNS_TC_WIRE(wirebuf) (*(wirebuf+2) & LDNS_TC_MASK)
|
||||
#define LDNS_TC_SET(wirebuf) (*(wirebuf+2) |= LDNS_TC_MASK)
|
||||
#define LDNS_TC_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_TC_MASK)
|
||||
|
||||
#define LDNS_AA_MASK 0x04U
|
||||
#define LDNS_AA_SHIFT 2
|
||||
#define LDNS_AA_WIRE(wirebuf) (*(wirebuf+2) & LDNS_AA_MASK)
|
||||
#define LDNS_AA_SET(wirebuf) (*(wirebuf+2) |= LDNS_AA_MASK)
|
||||
#define LDNS_AA_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_AA_MASK)
|
||||
|
||||
#define LDNS_OPCODE_MASK 0x78U
|
||||
#define LDNS_OPCODE_SHIFT 3
|
||||
#define LDNS_OPCODE_WIRE(wirebuf) ((*(wirebuf+2) & LDNS_OPCODE_MASK) >> LDNS_OPCODE_SHIFT)
|
||||
#define LDNS_OPCODE_SET(wirebuf, opcode) \
|
||||
(*(wirebuf+2) = ((*(wirebuf+2)) & ~LDNS_OPCODE_MASK) | ((opcode) << LDNS_OPCODE_SHIFT))
|
||||
|
||||
#define LDNS_QR_MASK 0x80U
|
||||
#define LDNS_QR_SHIFT 7
|
||||
#define LDNS_QR_WIRE(wirebuf) (*(wirebuf+2) & LDNS_QR_MASK)
|
||||
#define LDNS_QR_SET(wirebuf) (*(wirebuf+2) |= LDNS_QR_MASK)
|
||||
#define LDNS_QR_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_QR_MASK)
|
||||
|
||||
/* Second octet of flags */
|
||||
#define LDNS_RCODE_MASK 0x0fU
|
||||
#define LDNS_RCODE_SHIFT 0
|
||||
#define LDNS_RCODE_WIRE(wirebuf) (*(wirebuf+3) & LDNS_RCODE_MASK)
|
||||
#define LDNS_RCODE_SET(wirebuf, rcode) \
|
||||
(*(wirebuf+3) = ((*(wirebuf+3)) & ~LDNS_RCODE_MASK) | (rcode))
|
||||
|
||||
#define LDNS_CD_MASK 0x10U
|
||||
#define LDNS_CD_SHIFT 4
|
||||
#define LDNS_CD_WIRE(wirebuf) (*(wirebuf+3) & LDNS_CD_MASK)
|
||||
#define LDNS_CD_SET(wirebuf) (*(wirebuf+3) |= LDNS_CD_MASK)
|
||||
#define LDNS_CD_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_CD_MASK)
|
||||
|
||||
#define LDNS_AD_MASK 0x20U
|
||||
#define LDNS_AD_SHIFT 5
|
||||
#define LDNS_AD_WIRE(wirebuf) (*(wirebuf+3) & LDNS_AD_MASK)
|
||||
#define LDNS_AD_SET(wirebuf) (*(wirebuf+3) |= LDNS_AD_MASK)
|
||||
#define LDNS_AD_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_AD_MASK)
|
||||
|
||||
#define LDNS_Z_MASK 0x40U
|
||||
#define LDNS_Z_SHIFT 6
|
||||
#define LDNS_Z_WIRE(wirebuf) (*(wirebuf+3) & LDNS_Z_MASK)
|
||||
#define LDNS_Z_SET(wirebuf) (*(wirebuf+3) |= LDNS_Z_MASK)
|
||||
#define LDNS_Z_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_Z_MASK)
|
||||
|
||||
#define LDNS_RA_MASK 0x80U
|
||||
#define LDNS_RA_SHIFT 7
|
||||
#define LDNS_RA_WIRE(wirebuf) (*(wirebuf+3) & LDNS_RA_MASK)
|
||||
#define LDNS_RA_SET(wirebuf) (*(wirebuf+3) |= LDNS_RA_MASK)
|
||||
#define LDNS_RA_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_RA_MASK)
|
||||
|
||||
/* Query ID */
|
||||
#define LDNS_ID_WIRE(wirebuf) (ldns_read_uint16(wirebuf))
|
||||
#define LDNS_ID_SET(wirebuf, id) (ldns_write_uint16(wirebuf, id))
|
||||
|
||||
/* Counter of the question section */
|
||||
#define LDNS_QDCOUNT_OFF 4
|
||||
/*
|
||||
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
|
||||
*/
|
||||
#define LDNS_QDCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF))
|
||||
|
||||
/* Counter of the answer section */
|
||||
#define LDNS_ANCOUNT_OFF 6
|
||||
#define LDNS_ANCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF))
|
||||
|
||||
/* Counter of the authority section */
|
||||
#define LDNS_NSCOUNT_OFF 8
|
||||
#define LDNS_NSCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF))
|
||||
|
||||
/* Counter of the additional section */
|
||||
#define LDNS_ARCOUNT_OFF 10
|
||||
#define LDNS_ARCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF))
|
||||
|
||||
/**
|
||||
* The sections of a packet
|
||||
*/
|
||||
enum ldns_enum_pkt_section {
|
||||
LDNS_SECTION_QUESTION = 0,
|
||||
LDNS_SECTION_ANSWER = 1,
|
||||
LDNS_SECTION_AUTHORITY = 2,
|
||||
LDNS_SECTION_ADDITIONAL = 3,
|
||||
/** bogus section, if not interested */
|
||||
LDNS_SECTION_ANY = 4,
|
||||
/** used to get all non-question rrs from a packet */
|
||||
LDNS_SECTION_ANY_NOQUESTION = 5
|
||||
};
|
||||
typedef enum ldns_enum_pkt_section ldns_pkt_section;
|
||||
|
||||
/* opcodes for pkt's */
|
||||
enum ldns_enum_pkt_opcode {
|
||||
LDNS_PACKET_QUERY = 0,
|
||||
LDNS_PACKET_IQUERY = 1,
|
||||
LDNS_PACKET_STATUS = 2, /* there is no 3?? DNS is weird */
|
||||
LDNS_PACKET_NOTIFY = 4,
|
||||
LDNS_PACKET_UPDATE = 5
|
||||
};
|
||||
typedef enum ldns_enum_pkt_opcode ldns_pkt_opcode;
|
||||
|
||||
/* rcodes for pkts */
|
||||
enum ldns_enum_pkt_rcode {
|
||||
LDNS_RCODE_NOERROR = 0,
|
||||
LDNS_RCODE_FORMERR = 1,
|
||||
LDNS_RCODE_SERVFAIL = 2,
|
||||
LDNS_RCODE_NXDOMAIN = 3,
|
||||
LDNS_RCODE_NOTIMPL = 4,
|
||||
LDNS_RCODE_REFUSED = 5,
|
||||
LDNS_RCODE_YXDOMAIN = 6,
|
||||
LDNS_RCODE_YXRRSET = 7,
|
||||
LDNS_RCODE_NXRRSET = 8,
|
||||
LDNS_RCODE_NOTAUTH = 9,
|
||||
LDNS_RCODE_NOTZONE = 10
|
||||
};
|
||||
typedef enum ldns_enum_pkt_rcode ldns_pkt_rcode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LDNS_PKTHDR_H */
|
778
ldns/rrdef.c
Normal file
778
ldns/rrdef.c
Normal file
@ -0,0 +1,778 @@
|
||||
/* rrdef.c
|
||||
*
|
||||
* access functions to rr definitions list.
|
||||
* a Net::DNS like library for C
|
||||
* LibDNS Team @ NLnet Labs
|
||||
*
|
||||
* (c) NLnet Labs, 2004-2006
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Defines resource record types and constants.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/parseutil.h"
|
||||
|
||||
/* classes */
|
||||
static ldns_lookup_table ldns_rr_classes_data[] = {
|
||||
{ LDNS_RR_CLASS_IN, "IN" },
|
||||
{ LDNS_RR_CLASS_CH, "CH" },
|
||||
{ LDNS_RR_CLASS_HS, "HS" },
|
||||
{ LDNS_RR_CLASS_NONE, "NONE" },
|
||||
{ LDNS_RR_CLASS_ANY, "ANY" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
ldns_lookup_table* ldns_rr_classes = ldns_rr_classes_data;
|
||||
|
||||
/* types */
|
||||
static const ldns_rdf_type type_0_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
|
||||
static const ldns_rdf_type type_a_wireformat[] = { LDNS_RDF_TYPE_A };
|
||||
static const ldns_rdf_type type_ns_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_md_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_mf_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_cname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_soa_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_INT32,
|
||||
LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD,
|
||||
LDNS_RDF_TYPE_PERIOD
|
||||
};
|
||||
static const ldns_rdf_type type_mb_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_mg_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_mr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_wks_wireformat[] = {
|
||||
LDNS_RDF_TYPE_A, LDNS_RDF_TYPE_WKS
|
||||
};
|
||||
static const ldns_rdf_type type_ptr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_hinfo_wireformat[] = {
|
||||
LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
|
||||
};
|
||||
static const ldns_rdf_type type_minfo_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_mx_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_rp_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_afsdb_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_x25_wireformat[] = { LDNS_RDF_TYPE_STR };
|
||||
static const ldns_rdf_type type_isdn_wireformat[] = {
|
||||
LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
|
||||
};
|
||||
static const ldns_rdf_type type_rt_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_nsap_wireformat[] = {
|
||||
LDNS_RDF_TYPE_NSAP
|
||||
};
|
||||
static const ldns_rdf_type type_nsap_ptr_wireformat[] = {
|
||||
LDNS_RDF_TYPE_STR
|
||||
};
|
||||
static const ldns_rdf_type type_sig_wireformat[] = {
|
||||
LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
|
||||
LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
|
||||
};
|
||||
static const ldns_rdf_type type_key_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
|
||||
};
|
||||
static const ldns_rdf_type type_px_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_gpos_wireformat[] = {
|
||||
LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
|
||||
};
|
||||
static const ldns_rdf_type type_aaaa_wireformat[] = { LDNS_RDF_TYPE_AAAA };
|
||||
static const ldns_rdf_type type_loc_wireformat[] = { LDNS_RDF_TYPE_LOC };
|
||||
static const ldns_rdf_type type_nxt_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_UNKNOWN
|
||||
};
|
||||
static const ldns_rdf_type type_eid_wireformat[] = {
|
||||
LDNS_RDF_TYPE_HEX
|
||||
};
|
||||
static const ldns_rdf_type type_nimloc_wireformat[] = {
|
||||
LDNS_RDF_TYPE_HEX
|
||||
};
|
||||
static const ldns_rdf_type type_srv_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_atma_wireformat[] = {
|
||||
LDNS_RDF_TYPE_ATMA
|
||||
};
|
||||
static const ldns_rdf_type type_naptr_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_kx_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
static const ldns_rdf_type type_cert_wireformat[] = {
|
||||
LDNS_RDF_TYPE_CERT_ALG, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_B64
|
||||
};
|
||||
static const ldns_rdf_type type_a6_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
|
||||
static const ldns_rdf_type type_dname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
|
||||
static const ldns_rdf_type type_sink_wireformat[] = { LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
|
||||
};
|
||||
static const ldns_rdf_type type_apl_wireformat[] = {
|
||||
LDNS_RDF_TYPE_APL
|
||||
};
|
||||
static const ldns_rdf_type type_ds_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
|
||||
};
|
||||
static const ldns_rdf_type type_sshfp_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
|
||||
};
|
||||
static const ldns_rdf_type type_ipseckey_wireformat[] = {
|
||||
LDNS_RDF_TYPE_IPSECKEY
|
||||
};
|
||||
static const ldns_rdf_type type_rrsig_wireformat[] = {
|
||||
LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
|
||||
LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
|
||||
};
|
||||
static const ldns_rdf_type type_nsec_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_NSEC
|
||||
};
|
||||
static const ldns_rdf_type type_dhcid_wireformat[] = {
|
||||
LDNS_RDF_TYPE_B64
|
||||
};
|
||||
static const ldns_rdf_type type_talink_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
/* nsec3 is some vars, followed by same type of data of nsec */
|
||||
static const ldns_rdf_type type_nsec3_wireformat[] = {
|
||||
/* LDNS_RDF_TYPE_NSEC3_VARS, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC*/
|
||||
LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_NSEC3_SALT, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC
|
||||
};
|
||||
|
||||
static const ldns_rdf_type type_nsec3param_wireformat[] = {
|
||||
/* LDNS_RDF_TYPE_NSEC3_PARAMS_VARS*/
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_NSEC3_SALT
|
||||
};
|
||||
|
||||
static const ldns_rdf_type type_dnskey_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_ALG,
|
||||
LDNS_RDF_TYPE_B64
|
||||
};
|
||||
static const ldns_rdf_type type_tkey_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME,
|
||||
LDNS_RDF_TYPE_TIME,
|
||||
LDNS_RDF_TYPE_TIME,
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_INT16_DATA,
|
||||
LDNS_RDF_TYPE_INT16_DATA,
|
||||
};
|
||||
static const ldns_rdf_type type_tsig_wireformat[] = {
|
||||
LDNS_RDF_TYPE_DNAME,
|
||||
LDNS_RDF_TYPE_TSIGTIME,
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_INT16_DATA,
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_INT16_DATA
|
||||
};
|
||||
static const ldns_rdf_type type_tlsa_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_HEX
|
||||
};
|
||||
|
||||
/**
|
||||
* With HIP, wire and presentation format are out of step.
|
||||
* In presentation format, we have:
|
||||
* - a PK algorithm presented as integer in range [0..255]
|
||||
* - a variable length HIT field presented as hexstring
|
||||
* - a variable length Public Key field presented as Base64
|
||||
*
|
||||
* Unfortunately in the wireformat the lengths of the variable
|
||||
* length HIT and Public Key fields do not directly preceed them.
|
||||
* In stead we have:
|
||||
* - 1 byte HIT length: h
|
||||
* - 1 byte PK algorithm
|
||||
* - 2 bytes Public Key length: p
|
||||
* - h bytes HIT
|
||||
* - p bytes Public Key
|
||||
*
|
||||
* In ldns those deviations from the conventions for rdata fields are best
|
||||
* tackeled by letting the array refered to by the descriptor for HIP represent
|
||||
* host format only.
|
||||
*
|
||||
* BEWARE! Unlike other RR types, actual HIP wire format does not directly
|
||||
* follow the RDF types enumerated in the array pointed to by _wireformat in
|
||||
* its descriptor record.
|
||||
*/
|
||||
static const ldns_rdf_type type_hip_hostformat[] = {
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_HEX,
|
||||
LDNS_RDF_TYPE_B64
|
||||
};
|
||||
|
||||
static const ldns_rdf_type type_nid_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_ILNP64
|
||||
};
|
||||
static const ldns_rdf_type type_l32_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_A
|
||||
};
|
||||
static const ldns_rdf_type type_l64_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_ILNP64
|
||||
};
|
||||
static const ldns_rdf_type type_lp_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_DNAME
|
||||
};
|
||||
#ifdef DRAFT_RRTYPES
|
||||
static const ldns_rdf_type type_eui48_wireformat[] = {
|
||||
LDNS_RDF_TYPE_EUI48
|
||||
};
|
||||
static const ldns_rdf_type type_eui64_wireformat[] = {
|
||||
LDNS_RDF_TYPE_EUI64
|
||||
};
|
||||
static const ldns_rdf_type type_uri_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
LDNS_RDF_TYPE_LONG_STR
|
||||
};
|
||||
#endif
|
||||
static const ldns_rdf_type type_caa_wireformat[] = {
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
LDNS_RDF_TYPE_TAG,
|
||||
LDNS_RDF_TYPE_LONG_STR
|
||||
};
|
||||
|
||||
/* All RR's defined in 1035 are well known and can thus
|
||||
* be compressed. See RFC3597. These RR's are:
|
||||
* CNAME HINFO MB MD MF MG MINFO MR MX NULL NS PTR SOA TXT
|
||||
*/
|
||||
static ldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
/* 0 */
|
||||
{ 0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 1 */
|
||||
{LDNS_RR_TYPE_A, "A", 1, 1, type_a_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 2 */
|
||||
{LDNS_RR_TYPE_NS, "NS", 1, 1, type_ns_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 3 */
|
||||
{LDNS_RR_TYPE_MD, "MD", 1, 1, type_md_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 4 */
|
||||
{LDNS_RR_TYPE_MF, "MF", 1, 1, type_mf_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 5 */
|
||||
{LDNS_RR_TYPE_CNAME, "CNAME", 1, 1, type_cname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 6 */
|
||||
{LDNS_RR_TYPE_SOA, "SOA", 7, 7, type_soa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
|
||||
/* 7 */
|
||||
{LDNS_RR_TYPE_MB, "MB", 1, 1, type_mb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 8 */
|
||||
{LDNS_RR_TYPE_MG, "MG", 1, 1, type_mg_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 9 */
|
||||
{LDNS_RR_TYPE_MR, "MR", 1, 1, type_mr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 10 */
|
||||
{LDNS_RR_TYPE_NULL, "NULL", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 11 */
|
||||
{LDNS_RR_TYPE_WKS, "WKS", 2, 2, type_wks_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 12 */
|
||||
{LDNS_RR_TYPE_PTR, "PTR", 1, 1, type_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 13 */
|
||||
{LDNS_RR_TYPE_HINFO, "HINFO", 2, 2, type_hinfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 14 */
|
||||
{LDNS_RR_TYPE_MINFO, "MINFO", 2, 2, type_minfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
|
||||
/* 15 */
|
||||
{LDNS_RR_TYPE_MX, "MX", 2, 2, type_mx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
|
||||
/* 16 */
|
||||
{LDNS_RR_TYPE_TXT, "TXT", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 17 */
|
||||
{LDNS_RR_TYPE_RP, "RP", 2, 2, type_rp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
|
||||
/* 18 */
|
||||
{LDNS_RR_TYPE_AFSDB, "AFSDB", 2, 2, type_afsdb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 19 */
|
||||
{LDNS_RR_TYPE_X25, "X25", 1, 1, type_x25_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 20 */
|
||||
{LDNS_RR_TYPE_ISDN, "ISDN", 1, 2, type_isdn_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 21 */
|
||||
{LDNS_RR_TYPE_RT, "RT", 2, 2, type_rt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 22 */
|
||||
{LDNS_RR_TYPE_NSAP, "NSAP", 1, 1, type_nsap_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 23 */
|
||||
{LDNS_RR_TYPE_NSAP_PTR, "NSAP-PTR", 1, 1, type_nsap_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 24 */
|
||||
{LDNS_RR_TYPE_SIG, "SIG", 9, 9, type_sig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 25 */
|
||||
{LDNS_RR_TYPE_KEY, "KEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 26 */
|
||||
{LDNS_RR_TYPE_PX, "PX", 3, 3, type_px_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
|
||||
/* 27 */
|
||||
{LDNS_RR_TYPE_GPOS, "GPOS", 3, 3, type_gpos_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 28 */
|
||||
{LDNS_RR_TYPE_AAAA, "AAAA", 1, 1, type_aaaa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 29 */
|
||||
{LDNS_RR_TYPE_LOC, "LOC", 1, 1, type_loc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 30 */
|
||||
{LDNS_RR_TYPE_NXT, "NXT", 2, 2, type_nxt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 31 */
|
||||
{LDNS_RR_TYPE_EID, "EID", 1, 1, type_eid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 32 */
|
||||
{LDNS_RR_TYPE_NIMLOC, "NIMLOC", 1, 1, type_nimloc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 33 */
|
||||
{LDNS_RR_TYPE_SRV, "SRV", 4, 4, type_srv_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 34 */
|
||||
{LDNS_RR_TYPE_ATMA, "ATMA", 1, 1, type_atma_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 35 */
|
||||
{LDNS_RR_TYPE_NAPTR, "NAPTR", 6, 6, type_naptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 36 */
|
||||
{LDNS_RR_TYPE_KX, "KX", 2, 2, type_kx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 37 */
|
||||
{LDNS_RR_TYPE_CERT, "CERT", 4, 4, type_cert_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 38 */
|
||||
{LDNS_RR_TYPE_A6, "A6", 1, 1, type_a6_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 39 */
|
||||
{LDNS_RR_TYPE_DNAME, "DNAME", 1, 1, type_dname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 40 */
|
||||
{LDNS_RR_TYPE_SINK, "SINK", 1, 1, type_sink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 41 */
|
||||
{LDNS_RR_TYPE_OPT, "OPT", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 42 */
|
||||
{LDNS_RR_TYPE_APL, "APL", 0, 0, type_apl_wireformat, LDNS_RDF_TYPE_APL, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 43 */
|
||||
{LDNS_RR_TYPE_DS, "DS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 44 */
|
||||
{LDNS_RR_TYPE_SSHFP, "SSHFP", 3, 3, type_sshfp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 45 */
|
||||
{LDNS_RR_TYPE_IPSECKEY, "IPSECKEY", 1, 1, type_ipseckey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 46 */
|
||||
{LDNS_RR_TYPE_RRSIG, "RRSIG", 9, 9, type_rrsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 47 */
|
||||
{LDNS_RR_TYPE_NSEC, "NSEC", 1, 2, type_nsec_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* 48 */
|
||||
{LDNS_RR_TYPE_DNSKEY, "DNSKEY", 4, 4, type_dnskey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 49 */
|
||||
{LDNS_RR_TYPE_DHCID, "DHCID", 1, 1, type_dhcid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 50 */
|
||||
{LDNS_RR_TYPE_NSEC3, "NSEC3", 5, 6, type_nsec3_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 51 */
|
||||
{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 52 */
|
||||
{LDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* 55
|
||||
* Hip ends with 0 or more Rendezvous Servers represented as dname's.
|
||||
* Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field
|
||||
* set to 0.
|
||||
*
|
||||
* BEWARE! Unlike other RR types, actual HIP wire format does not
|
||||
* directly follow the RDF types enumerated in the array pointed to
|
||||
* by _wireformat. For more info see type_hip_hostformat declaration.
|
||||
*/
|
||||
{LDNS_RR_TYPE_HIP, "HIP", 3, 3, type_hip_hostformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 56 */
|
||||
{LDNS_RR_TYPE_NINFO, "NINFO", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 57 */
|
||||
{LDNS_RR_TYPE_RKEY, "RKEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
/* 58 */
|
||||
{LDNS_RR_TYPE_TALINK, "TALINK", 2, 2, type_talink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
|
||||
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 59 */
|
||||
{LDNS_RR_TYPE_CDS, "CDS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE59", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
|
||||
{LDNS_RR_TYPE_NULL, "TYPE60", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE61", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE62", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* 99 */
|
||||
{LDNS_RR_TYPE_SPF, "SPF", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* UINFO [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* UID [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* GID [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* UNSPEC [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* 104 */
|
||||
{LDNS_RR_TYPE_NID, "NID", 2, 2, type_nid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 105 */
|
||||
{LDNS_RR_TYPE_L32, "L32", 2, 2, type_l32_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 106 */
|
||||
{LDNS_RR_TYPE_L64, "L64", 2, 2, type_l64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 107 */
|
||||
{LDNS_RR_TYPE_LP, "LP", 2, 2, type_lp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 108 */
|
||||
{LDNS_RR_TYPE_EUI48, "EUI48", 1, 1, type_eui48_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 109 */
|
||||
{LDNS_RR_TYPE_EUI64, "EUI64", 1, 1, type_eui64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE108", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE109", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
|
||||
{LDNS_RR_TYPE_NULL, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
|
||||
* So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
|
||||
*/
|
||||
/* 249 */
|
||||
{LDNS_RR_TYPE_TKEY, "TKEY", 7, 7, type_tkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
|
||||
* So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
|
||||
*/
|
||||
/* 250 */
|
||||
{LDNS_RR_TYPE_TSIG, "TSIG", 7, 7, type_tsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
|
||||
|
||||
/* IXFR: A request for a transfer of an incremental zone transfer */
|
||||
{LDNS_RR_TYPE_IXFR, "IXFR", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* AXFR: A request for a transfer of an entire zone */
|
||||
{LDNS_RR_TYPE_AXFR, "AXFR", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* MAILB: A request for mailbox-related records (MB, MG or MR) */
|
||||
{LDNS_RR_TYPE_MAILB, "MAILB", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* MAILA: A request for mail agent RRs (Obsolete - see MX) */
|
||||
{LDNS_RR_TYPE_MAILA, "MAILA", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* ANY: A request for all (available) records */
|
||||
{LDNS_RR_TYPE_ANY, "ANY", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 256 */
|
||||
{LDNS_RR_TYPE_URI, "URI", 3, 3, type_uri_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE256", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
/* 257 */
|
||||
{LDNS_RR_TYPE_CAA, "CAA", 3, 3, type_caa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* split in array, no longer contiguous */
|
||||
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 32768 */
|
||||
{LDNS_RR_TYPE_TA, "TA", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
/* 32769 */
|
||||
{LDNS_RR_TYPE_DLV, "DLV", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }
|
||||
};
|
||||
|
||||
/**
|
||||
* \def LDNS_RDATA_FIELD_DESCRIPTORS_COUNT
|
||||
* computes the number of rdata fields
|
||||
*/
|
||||
#define LDNS_RDATA_FIELD_DESCRIPTORS_COUNT \
|
||||
(sizeof(rdata_field_descriptors)/sizeof(rdata_field_descriptors[0]))
|
||||
|
||||
const ldns_rr_descriptor *
|
||||
ldns_rr_descript(uint16_t type)
|
||||
{
|
||||
size_t i;
|
||||
if (type < LDNS_RDATA_FIELD_DESCRIPTORS_COMMON) {
|
||||
return &rdata_field_descriptors[type];
|
||||
} else {
|
||||
/* because not all array index equals type code */
|
||||
for (i = LDNS_RDATA_FIELD_DESCRIPTORS_COMMON;
|
||||
i < LDNS_RDATA_FIELD_DESCRIPTORS_COUNT;
|
||||
i++) {
|
||||
if (rdata_field_descriptors[i]._type == type) {
|
||||
return &rdata_field_descriptors[i];
|
||||
}
|
||||
}
|
||||
return &rdata_field_descriptors[0];
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor)
|
||||
{
|
||||
if (descriptor) {
|
||||
return descriptor->_minimum;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor)
|
||||
{
|
||||
if (descriptor) {
|
||||
if (descriptor->_variable != LDNS_RDF_TYPE_NONE) {
|
||||
/* Should really be SIZE_MAX... bad FreeBSD. */
|
||||
return UINT_MAX;
|
||||
} else {
|
||||
return descriptor->_maximum;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ldns_rdf_type
|
||||
ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor,
|
||||
size_t index)
|
||||
{
|
||||
assert(descriptor != NULL);
|
||||
assert(index < descriptor->_maximum
|
||||
|| descriptor->_variable != LDNS_RDF_TYPE_NONE);
|
||||
if (index < descriptor->_maximum) {
|
||||
return descriptor->_wireformat[index];
|
||||
} else {
|
||||
return descriptor->_variable;
|
||||
}
|
||||
}
|
||||
|
||||
ldns_rr_type
|
||||
ldns_get_rr_type_by_name(const char *name)
|
||||
{
|
||||
unsigned int i;
|
||||
const char *desc_name;
|
||||
const ldns_rr_descriptor *desc;
|
||||
|
||||
/* TYPEXX representation */
|
||||
if (strlen(name) > 4 && strncasecmp(name, "TYPE", 4) == 0) {
|
||||
return atoi(name + 4);
|
||||
}
|
||||
|
||||
/* Normal types */
|
||||
for (i = 0; i < (unsigned int) LDNS_RDATA_FIELD_DESCRIPTORS_COUNT; i++) {
|
||||
desc = &rdata_field_descriptors[i];
|
||||
desc_name = desc->_name;
|
||||
if(desc_name &&
|
||||
strlen(name) == strlen(desc_name) &&
|
||||
strncasecmp(name, desc_name, strlen(desc_name)) == 0) {
|
||||
/* because not all array index equals type code */
|
||||
return desc->_type;
|
||||
}
|
||||
}
|
||||
|
||||
/* special cases for query types */
|
||||
if (strlen(name) == 4 && strncasecmp(name, "IXFR", 4) == 0) {
|
||||
return 251;
|
||||
} else if (strlen(name) == 4 && strncasecmp(name, "AXFR", 4) == 0) {
|
||||
return 252;
|
||||
} else if (strlen(name) == 5 && strncasecmp(name, "MAILB", 5) == 0) {
|
||||
return 253;
|
||||
} else if (strlen(name) == 5 && strncasecmp(name, "MAILA", 5) == 0) {
|
||||
return 254;
|
||||
} else if (strlen(name) == 3 && strncasecmp(name, "ANY", 3) == 0) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ldns_rr_class
|
||||
ldns_get_rr_class_by_name(const char *name)
|
||||
{
|
||||
ldns_lookup_table *lt;
|
||||
|
||||
/* CLASSXX representation */
|
||||
if (strlen(name) > 5 && strncasecmp(name, "CLASS", 5) == 0) {
|
||||
return atoi(name + 5);
|
||||
}
|
||||
|
||||
/* Normal types */
|
||||
lt = ldns_lookup_by_name(ldns_rr_classes, name);
|
||||
|
||||
if (lt) {
|
||||
return lt->id;
|
||||
}
|
||||
return 0;
|
||||
}
|
500
ldns/rrdef.h
Normal file
500
ldns/rrdef.h
Normal file
@ -0,0 +1,500 @@
|
||||
/*
|
||||
* rrdef.h
|
||||
*
|
||||
* RR definitions
|
||||
*
|
||||
* a Net::DNS like library for C
|
||||
*
|
||||
* (c) NLnet Labs, 2005-2006
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Defines resource record types and constants.
|
||||
*/
|
||||
|
||||
#ifndef LDNS_RRDEF_H
|
||||
#define LDNS_RRDEF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Maximum length of a dname label */
|
||||
#define LDNS_MAX_LABELLEN 63
|
||||
/** Maximum length of a complete dname */
|
||||
#define LDNS_MAX_DOMAINLEN 255
|
||||
/** Maximum number of pointers in 1 dname */
|
||||
#define LDNS_MAX_POINTERS 65535
|
||||
/** The bytes TTL, CLASS and length use up in an rr */
|
||||
#define LDNS_RR_OVERHEAD 10
|
||||
|
||||
#define LDNS_DNSSEC_KEYPROTO 3
|
||||
#define LDNS_KEY_ZONE_KEY 0x0100 /* set for ZSK&KSK, rfc 4034 */
|
||||
#define LDNS_KEY_SEP_KEY 0x0001 /* set for KSK, rfc 4034 */
|
||||
#define LDNS_KEY_REVOKE_KEY 0x0080 /* used to revoke KSK, rfc 5011 */
|
||||
|
||||
/* The first fields are contiguous and can be referenced instantly */
|
||||
#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 258
|
||||
|
||||
/** lookuptable for rr types */
|
||||
extern struct ldns_struct_lookup_table* ldns_rr_classes;
|
||||
|
||||
/**
|
||||
* The different RR classes.
|
||||
*/
|
||||
enum ldns_enum_rr_class
|
||||
{
|
||||
/** the Internet */
|
||||
LDNS_RR_CLASS_IN = 1,
|
||||
/** Chaos class */
|
||||
LDNS_RR_CLASS_CH = 3,
|
||||
/** Hesiod (Dyer 87) */
|
||||
LDNS_RR_CLASS_HS = 4,
|
||||
/** None class, dynamic update */
|
||||
LDNS_RR_CLASS_NONE = 254,
|
||||
/** Any class */
|
||||
LDNS_RR_CLASS_ANY = 255,
|
||||
|
||||
LDNS_RR_CLASS_FIRST = 0,
|
||||
LDNS_RR_CLASS_LAST = 65535,
|
||||
LDNS_RR_CLASS_COUNT = LDNS_RR_CLASS_LAST - LDNS_RR_CLASS_FIRST + 1
|
||||
};
|
||||
typedef enum ldns_enum_rr_class ldns_rr_class;
|
||||
|
||||
/**
|
||||
* Used to specify whether compression is allowed.
|
||||
*/
|
||||
enum ldns_enum_rr_compress
|
||||
{
|
||||
/** compression is allowed */
|
||||
LDNS_RR_COMPRESS,
|
||||
LDNS_RR_NO_COMPRESS
|
||||
};
|
||||
typedef enum ldns_enum_rr_compress ldns_rr_compress;
|
||||
|
||||
/**
|
||||
* The different RR types.
|
||||
*/
|
||||
enum ldns_enum_rr_type
|
||||
{
|
||||
/** a host address */
|
||||
LDNS_RR_TYPE_A = 1,
|
||||
/** an authoritative name server */
|
||||
LDNS_RR_TYPE_NS = 2,
|
||||
/** a mail destination (Obsolete - use MX) */
|
||||
LDNS_RR_TYPE_MD = 3,
|
||||
/** a mail forwarder (Obsolete - use MX) */
|
||||
LDNS_RR_TYPE_MF = 4,
|
||||
/** the canonical name for an alias */
|
||||
LDNS_RR_TYPE_CNAME = 5,
|
||||
/** marks the start of a zone of authority */
|
||||
LDNS_RR_TYPE_SOA = 6,
|
||||
/** a mailbox domain name (EXPERIMENTAL) */
|
||||
LDNS_RR_TYPE_MB = 7,
|
||||
/** a mail group member (EXPERIMENTAL) */
|
||||
LDNS_RR_TYPE_MG = 8,
|
||||
/** a mail rename domain name (EXPERIMENTAL) */
|
||||
LDNS_RR_TYPE_MR = 9,
|
||||
/** a null RR (EXPERIMENTAL) */
|
||||
LDNS_RR_TYPE_NULL = 10,
|
||||
/** a well known service description */
|
||||
LDNS_RR_TYPE_WKS = 11,
|
||||
/** a domain name pointer */
|
||||
LDNS_RR_TYPE_PTR = 12,
|
||||
/** host information */
|
||||
LDNS_RR_TYPE_HINFO = 13,
|
||||
/** mailbox or mail list information */
|
||||
LDNS_RR_TYPE_MINFO = 14,
|
||||
/** mail exchange */
|
||||
LDNS_RR_TYPE_MX = 15,
|
||||
/** text strings */
|
||||
LDNS_RR_TYPE_TXT = 16,
|
||||
/** RFC1183 */
|
||||
LDNS_RR_TYPE_RP = 17,
|
||||
/** RFC1183 */
|
||||
LDNS_RR_TYPE_AFSDB = 18,
|
||||
/** RFC1183 */
|
||||
LDNS_RR_TYPE_X25 = 19,
|
||||
/** RFC1183 */
|
||||
LDNS_RR_TYPE_ISDN = 20,
|
||||
/** RFC1183 */
|
||||
LDNS_RR_TYPE_RT = 21,
|
||||
/** RFC1706 */
|
||||
LDNS_RR_TYPE_NSAP = 22,
|
||||
/** RFC1348 */
|
||||
LDNS_RR_TYPE_NSAP_PTR = 23,
|
||||
/** 2535typecode */
|
||||
LDNS_RR_TYPE_SIG = 24,
|
||||
/** 2535typecode */
|
||||
LDNS_RR_TYPE_KEY = 25,
|
||||
/** RFC2163 */
|
||||
LDNS_RR_TYPE_PX = 26,
|
||||
/** RFC1712 */
|
||||
LDNS_RR_TYPE_GPOS = 27,
|
||||
/** ipv6 address */
|
||||
LDNS_RR_TYPE_AAAA = 28,
|
||||
/** LOC record RFC1876 */
|
||||
LDNS_RR_TYPE_LOC = 29,
|
||||
/** 2535typecode */
|
||||
LDNS_RR_TYPE_NXT = 30,
|
||||
/** draft-ietf-nimrod-dns-01.txt */
|
||||
LDNS_RR_TYPE_EID = 31,
|
||||
/** draft-ietf-nimrod-dns-01.txt */
|
||||
LDNS_RR_TYPE_NIMLOC = 32,
|
||||
/** SRV record RFC2782 */
|
||||
LDNS_RR_TYPE_SRV = 33,
|
||||
/** http://www.jhsoft.com/rfc/af-saa-0069.000.rtf */
|
||||
LDNS_RR_TYPE_ATMA = 34,
|
||||
/** RFC2915 */
|
||||
LDNS_RR_TYPE_NAPTR = 35,
|
||||
/** RFC2230 */
|
||||
LDNS_RR_TYPE_KX = 36,
|
||||
/** RFC2538 */
|
||||
LDNS_RR_TYPE_CERT = 37,
|
||||
/** RFC2874 */
|
||||
LDNS_RR_TYPE_A6 = 38,
|
||||
/** RFC2672 */
|
||||
LDNS_RR_TYPE_DNAME = 39,
|
||||
/** dnsind-kitchen-sink-02.txt */
|
||||
LDNS_RR_TYPE_SINK = 40,
|
||||
/** Pseudo OPT record... */
|
||||
LDNS_RR_TYPE_OPT = 41,
|
||||
/** RFC3123 */
|
||||
LDNS_RR_TYPE_APL = 42,
|
||||
/** RFC4034, RFC3658 */
|
||||
LDNS_RR_TYPE_DS = 43,
|
||||
/** SSH Key Fingerprint */
|
||||
LDNS_RR_TYPE_SSHFP = 44, /* RFC 4255 */
|
||||
/** IPsec Key */
|
||||
LDNS_RR_TYPE_IPSECKEY = 45, /* RFC 4025 */
|
||||
/** DNSSEC */
|
||||
LDNS_RR_TYPE_RRSIG = 46, /* RFC 4034 */
|
||||
LDNS_RR_TYPE_NSEC = 47, /* RFC 4034 */
|
||||
LDNS_RR_TYPE_DNSKEY = 48, /* RFC 4034 */
|
||||
|
||||
LDNS_RR_TYPE_DHCID = 49, /* RFC 4701 */
|
||||
/* NSEC3 */
|
||||
LDNS_RR_TYPE_NSEC3 = 50, /* RFC 5155 */
|
||||
LDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
|
||||
LDNS_RR_TYPE_NSEC3PARAMS = 51,
|
||||
LDNS_RR_TYPE_TLSA = 52, /* RFC 6698 */
|
||||
|
||||
LDNS_RR_TYPE_HIP = 55, /* RFC 5205 */
|
||||
|
||||
/** draft-reid-dnsext-zs */
|
||||
LDNS_RR_TYPE_NINFO = 56,
|
||||
/** draft-reid-dnsext-rkey */
|
||||
LDNS_RR_TYPE_RKEY = 57,
|
||||
/** draft-ietf-dnsop-trust-history */
|
||||
LDNS_RR_TYPE_TALINK = 58,
|
||||
/** draft-barwood-dnsop-ds-publis */
|
||||
LDNS_RR_TYPE_CDS = 59,
|
||||
|
||||
LDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
|
||||
|
||||
LDNS_RR_TYPE_UINFO = 100,
|
||||
LDNS_RR_TYPE_UID = 101,
|
||||
LDNS_RR_TYPE_GID = 102,
|
||||
LDNS_RR_TYPE_UNSPEC = 103,
|
||||
|
||||
LDNS_RR_TYPE_NID = 104, /* RFC 6742 */
|
||||
LDNS_RR_TYPE_L32 = 105, /* RFC 6742 */
|
||||
LDNS_RR_TYPE_L64 = 106, /* RFC 6742 */
|
||||
LDNS_RR_TYPE_LP = 107, /* RFC 6742 */
|
||||
|
||||
/** draft-jabley-dnsext-eui48-eui64-rrtypes */
|
||||
LDNS_RR_TYPE_EUI48 = 108,
|
||||
LDNS_RR_TYPE_EUI64 = 109,
|
||||
|
||||
LDNS_RR_TYPE_TKEY = 249, /* RFC 2930 */
|
||||
LDNS_RR_TYPE_TSIG = 250,
|
||||
LDNS_RR_TYPE_IXFR = 251,
|
||||
LDNS_RR_TYPE_AXFR = 252,
|
||||
/** A request for mailbox-related records (MB, MG or MR) */
|
||||
LDNS_RR_TYPE_MAILB = 253,
|
||||
/** A request for mail agent RRs (Obsolete - see MX) */
|
||||
LDNS_RR_TYPE_MAILA = 254,
|
||||
/** any type (wildcard) */
|
||||
LDNS_RR_TYPE_ANY = 255,
|
||||
/** draft-faltstrom-uri-06 */
|
||||
LDNS_RR_TYPE_URI = 256,
|
||||
LDNS_RR_TYPE_CAA = 257, /* RFC 6844 */
|
||||
|
||||
/** DNSSEC Trust Authorities */
|
||||
LDNS_RR_TYPE_TA = 32768,
|
||||
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
|
||||
LDNS_RR_TYPE_DLV = 32769,
|
||||
|
||||
/* type codes from nsec3 experimental phase
|
||||
LDNS_RR_TYPE_NSEC3 = 65324,
|
||||
LDNS_RR_TYPE_NSEC3PARAMS = 65325, */
|
||||
LDNS_RR_TYPE_FIRST = 0,
|
||||
LDNS_RR_TYPE_LAST = 65535,
|
||||
LDNS_RR_TYPE_COUNT = LDNS_RR_TYPE_LAST - LDNS_RR_TYPE_FIRST + 1
|
||||
};
|
||||
typedef enum ldns_enum_rr_type ldns_rr_type;
|
||||
|
||||
/* RDATA */
|
||||
#define LDNS_MAX_RDFLEN 65535
|
||||
|
||||
#define LDNS_RDF_SIZE_BYTE 1
|
||||
#define LDNS_RDF_SIZE_WORD 2
|
||||
#define LDNS_RDF_SIZE_DOUBLEWORD 4
|
||||
#define LDNS_RDF_SIZE_6BYTES 6
|
||||
#define LDNS_RDF_SIZE_8BYTES 8
|
||||
#define LDNS_RDF_SIZE_16BYTES 16
|
||||
|
||||
#define LDNS_NSEC3_VARS_OPTOUT_MASK 0x01
|
||||
|
||||
#define LDNS_APL_IP4 1
|
||||
#define LDNS_APL_IP6 2
|
||||
#define LDNS_APL_MASK 0x7f
|
||||
#define LDNS_APL_NEGATION 0x80
|
||||
|
||||
/**
|
||||
* The different types of RDATA fields.
|
||||
*/
|
||||
enum ldns_enum_rdf_type
|
||||
{
|
||||
/** none */
|
||||
LDNS_RDF_TYPE_NONE,
|
||||
/** domain name */
|
||||
LDNS_RDF_TYPE_DNAME,
|
||||
/** 8 bits */
|
||||
LDNS_RDF_TYPE_INT8,
|
||||
/** 16 bits */
|
||||
LDNS_RDF_TYPE_INT16,
|
||||
/** 32 bits */
|
||||
LDNS_RDF_TYPE_INT32,
|
||||
/** A record */
|
||||
LDNS_RDF_TYPE_A,
|
||||
/** AAAA record */
|
||||
LDNS_RDF_TYPE_AAAA,
|
||||
/** txt string */
|
||||
LDNS_RDF_TYPE_STR,
|
||||
/** apl data */
|
||||
LDNS_RDF_TYPE_APL,
|
||||
/** b32 string */
|
||||
LDNS_RDF_TYPE_B32_EXT,
|
||||
/** b64 string */
|
||||
LDNS_RDF_TYPE_B64,
|
||||
/** hex string */
|
||||
LDNS_RDF_TYPE_HEX,
|
||||
/** nsec type codes */
|
||||
LDNS_RDF_TYPE_NSEC,
|
||||
/** a RR type */
|
||||
LDNS_RDF_TYPE_TYPE,
|
||||
/** a class */
|
||||
LDNS_RDF_TYPE_CLASS,
|
||||
/** certificate algorithm */
|
||||
LDNS_RDF_TYPE_CERT_ALG,
|
||||
/** a key algorithm */
|
||||
LDNS_RDF_TYPE_ALG,
|
||||
/** unknown types */
|
||||
LDNS_RDF_TYPE_UNKNOWN,
|
||||
/** time (32 bits) */
|
||||
LDNS_RDF_TYPE_TIME,
|
||||
/** period */
|
||||
LDNS_RDF_TYPE_PERIOD,
|
||||
/** tsig time 48 bits */
|
||||
LDNS_RDF_TYPE_TSIGTIME,
|
||||
/** skip 21 unused */
|
||||
/** variable length any type rdata where the length
|
||||
is specified by the first 2 bytes */
|
||||
LDNS_RDF_TYPE_INT16_DATA = 22,
|
||||
/** protocol and port bitmaps */
|
||||
LDNS_RDF_TYPE_SERVICE,
|
||||
/** location data */
|
||||
LDNS_RDF_TYPE_LOC,
|
||||
/** well known services */
|
||||
LDNS_RDF_TYPE_WKS,
|
||||
/** NSAP */
|
||||
LDNS_RDF_TYPE_NSAP,
|
||||
/** ATMA */
|
||||
LDNS_RDF_TYPE_ATMA,
|
||||
/** IPSECKEY */
|
||||
LDNS_RDF_TYPE_IPSECKEY,
|
||||
/** nsec3 hash salt */
|
||||
LDNS_RDF_TYPE_NSEC3_SALT,
|
||||
/** nsec3 base32 string (with length byte on wire */
|
||||
LDNS_RDF_TYPE_NSEC3_NEXT_OWNER,
|
||||
|
||||
/** 4 shorts represented as 4 * 16 bit hex numbers
|
||||
* seperated by colons. For NID and L64.
|
||||
*/
|
||||
LDNS_RDF_TYPE_ILNP64,
|
||||
|
||||
/** 6 * 8 bit hex numbers seperated by dashes. For EUI48. */
|
||||
LDNS_RDF_TYPE_EUI48,
|
||||
/** 8 * 8 bit hex numbers seperated by dashes. For EUI64. */
|
||||
LDNS_RDF_TYPE_EUI64,
|
||||
|
||||
/** A non-zero sequence of US-ASCII letters and numbers in lower case.
|
||||
* For CAA.
|
||||
*/
|
||||
LDNS_RDF_TYPE_TAG,
|
||||
|
||||
/** A <character-string> encoding of the value field as specified
|
||||
* [RFC1035], Section 5.1., encoded as remaining rdata.
|
||||
* For CAA.
|
||||
*/
|
||||
LDNS_RDF_TYPE_LONG_STR,
|
||||
|
||||
/* Aliases */
|
||||
LDNS_RDF_TYPE_BITMAP = LDNS_RDF_TYPE_NSEC
|
||||
};
|
||||
typedef enum ldns_enum_rdf_type ldns_rdf_type;
|
||||
|
||||
/**
|
||||
* Algorithms used in dns
|
||||
*/
|
||||
enum ldns_enum_algorithm
|
||||
{
|
||||
LDNS_RSAMD5 = 1, /* RFC 4034,4035 */
|
||||
LDNS_DH = 2,
|
||||
LDNS_DSA = 3,
|
||||
LDNS_ECC = 4,
|
||||
LDNS_RSASHA1 = 5,
|
||||
LDNS_DSA_NSEC3 = 6,
|
||||
LDNS_RSASHA1_NSEC3 = 7,
|
||||
LDNS_RSASHA256 = 8, /* RFC 5702 */
|
||||
LDNS_RSASHA512 = 10, /* RFC 5702 */
|
||||
LDNS_ECC_GOST = 12, /* RFC 5933 */
|
||||
LDNS_ECDSAP256SHA256 = 13, /* RFC 6605 */
|
||||
LDNS_ECDSAP384SHA384 = 14, /* RFC 6605 */
|
||||
LDNS_INDIRECT = 252,
|
||||
LDNS_PRIVATEDNS = 253,
|
||||
LDNS_PRIVATEOID = 254
|
||||
};
|
||||
typedef enum ldns_enum_algorithm ldns_algorithm;
|
||||
|
||||
/**
|
||||
* Hashing algorithms used in the DS record
|
||||
*/
|
||||
enum ldns_enum_hash
|
||||
{
|
||||
LDNS_SHA1 = 1, /* RFC 4034 */
|
||||
LDNS_SHA256 = 2, /* RFC 4509 */
|
||||
LDNS_HASH_GOST = 3, /* RFC 5933 */
|
||||
LDNS_SHA384 = 4 /* RFC 6605 */
|
||||
};
|
||||
typedef enum ldns_enum_hash ldns_hash;
|
||||
|
||||
/**
|
||||
* algorithms used in CERT rrs
|
||||
*/
|
||||
enum ldns_enum_cert_algorithm
|
||||
{
|
||||
LDNS_CERT_PKIX = 1,
|
||||
LDNS_CERT_SPKI = 2,
|
||||
LDNS_CERT_PGP = 3,
|
||||
LDNS_CERT_IPKIX = 4,
|
||||
LDNS_CERT_ISPKI = 5,
|
||||
LDNS_CERT_IPGP = 6,
|
||||
LDNS_CERT_ACPKIX = 7,
|
||||
LDNS_CERT_IACPKIX = 8,
|
||||
LDNS_CERT_URI = 253,
|
||||
LDNS_CERT_OID = 254
|
||||
};
|
||||
typedef enum ldns_enum_cert_algorithm ldns_cert_algorithm;
|
||||
|
||||
/**
|
||||
* EDNS option codes
|
||||
*/
|
||||
enum ldns_enum_edns_option
|
||||
{
|
||||
LDNS_EDNS_LLQ = 1, /* http://files.dns-sd.org/draft-sekar-dns-llq.txt */
|
||||
LDNS_EDNS_UL = 2, /* http://files.dns-sd.org/draft-sekar-dns-ul.txt */
|
||||
LDNS_EDNS_NSID = 3, /* RFC5001 */
|
||||
/* 4 draft-cheshire-edns0-owner-option */
|
||||
LDNS_EDNS_DAU = 5, /* RFC6975 */
|
||||
LDNS_EDNS_DHU = 6, /* RFC6975 */
|
||||
LDNS_EDNS_N3U = 7, /* RFC6975 */
|
||||
LDNS_EDNS_CLIENT_SUBNET = 8 /* draft-vandergaast-edns-client-subnet */
|
||||
};
|
||||
typedef enum ldns_edns_option ldns_edns_option;
|
||||
|
||||
#define LDNS_EDNS_MASK_DO_BIT 0x8000
|
||||
|
||||
/**
|
||||
* Contains all information about resource record types.
|
||||
*
|
||||
* This structure contains, for all rr types, the rdata fields that are defined.
|
||||
*/
|
||||
struct ldns_struct_rr_descriptor
|
||||
{
|
||||
/** Type of the RR that is described here */
|
||||
ldns_rr_type _type;
|
||||
/** Textual name of the RR type. */
|
||||
const char *_name;
|
||||
/** Minimum number of rdata fields in the RRs of this type. */
|
||||
uint8_t _minimum;
|
||||
/** Maximum number of rdata fields in the RRs of this type. */
|
||||
uint8_t _maximum;
|
||||
/** Wireformat specification for the rr, i.e. the types of rdata fields in their respective order. */
|
||||
const ldns_rdf_type *_wireformat;
|
||||
/** Special rdf types */
|
||||
ldns_rdf_type _variable;
|
||||
/** Specifies whether compression can be used for dnames in this RR type. */
|
||||
ldns_rr_compress _compress;
|
||||
/** The number of DNAMEs in the _wireformat string, for parsing. */
|
||||
uint8_t _dname_count;
|
||||
};
|
||||
typedef struct ldns_struct_rr_descriptor ldns_rr_descriptor;
|
||||
|
||||
/**
|
||||
* returns the resource record descriptor for the given rr type.
|
||||
*
|
||||
* \param[in] type the type value of the rr type
|
||||
*\return the ldns_rr_descriptor for this type
|
||||
*/
|
||||
const ldns_rr_descriptor *ldns_rr_descript(uint16_t type);
|
||||
|
||||
/**
|
||||
* returns the minimum number of rdata fields of the rr type this descriptor describes.
|
||||
*
|
||||
* \param[in] descriptor for an rr type
|
||||
* \return the minimum number of rdata fields
|
||||
*/
|
||||
size_t ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor);
|
||||
|
||||
/**
|
||||
* returns the maximum number of rdata fields of the rr type this descriptor describes.
|
||||
*
|
||||
* \param[in] descriptor for an rr type
|
||||
* \return the maximum number of rdata fields
|
||||
*/
|
||||
size_t ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor);
|
||||
|
||||
/**
|
||||
* returns the rdf type for the given rdata field number of the rr type for the given descriptor.
|
||||
*
|
||||
* \param[in] descriptor for an rr type
|
||||
* \param[in] field the field number
|
||||
* \return the rdf type for the field
|
||||
*/
|
||||
ldns_rdf_type ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor, size_t field);
|
||||
|
||||
/**
|
||||
* retrieves a rrtype by looking up its name.
|
||||
* \param[in] name a string with the name
|
||||
* \return the type which corresponds with the name
|
||||
*/
|
||||
ldns_rr_type ldns_get_rr_type_by_name(const char *name);
|
||||
|
||||
/**
|
||||
* retrieves a class by looking up its name.
|
||||
* \param[in] name string with the name
|
||||
* \return the cass which corresponds with the name
|
||||
*/
|
||||
ldns_rr_class ldns_get_rr_class_by_name(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LDNS_RRDEF_H */
|
189
ldns/sbuffer.c
Normal file
189
ldns/sbuffer.c
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* buffer.c -- generic memory buffer .
|
||||
*
|
||||
* Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* See LICENSE for the license.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains the definition of ldns_buffer, and functions to manipulate those.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
ldns_buffer *
|
||||
ldns_buffer_new(size_t capacity)
|
||||
{
|
||||
ldns_buffer *buffer = (ldns_buffer*)malloc(sizeof(ldns_buffer));
|
||||
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer->_data = (uint8_t *) malloc(capacity);
|
||||
if (!buffer->_data) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer->_position = 0;
|
||||
buffer->_limit = buffer->_capacity = capacity;
|
||||
buffer->_fixed = 0;
|
||||
buffer->_status_err = 0;
|
||||
|
||||
ldns_buffer_invariant(buffer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void
|
||||
ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
buffer->_position = 0;
|
||||
buffer->_limit = buffer->_capacity = size;
|
||||
buffer->_fixed = 0;
|
||||
buffer->_data = malloc(size);
|
||||
if(!buffer->_data) {
|
||||
buffer->_status_err = 1;
|
||||
return;
|
||||
}
|
||||
memcpy(buffer->_data, data, size);
|
||||
buffer->_status_err = 0;
|
||||
|
||||
ldns_buffer_invariant(buffer);
|
||||
}
|
||||
|
||||
void
|
||||
ldns_buffer_init_frm_data(ldns_buffer *buffer, void *data, size_t size)
|
||||
{
|
||||
memset(buffer, 0, sizeof(*buffer));
|
||||
buffer->_data = data;
|
||||
buffer->_capacity = buffer->_limit = size;
|
||||
buffer->_fixed = 1;
|
||||
}
|
||||
|
||||
int
|
||||
ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
|
||||
{
|
||||
void *data;
|
||||
|
||||
ldns_buffer_invariant(buffer);
|
||||
assert(buffer->_position <= capacity);
|
||||
|
||||
data = (uint8_t *) realloc(buffer->_data, capacity);
|
||||
if (!data) {
|
||||
buffer->_status_err = 1;
|
||||
return 0;
|
||||
} else {
|
||||
buffer->_data = data;
|
||||
buffer->_limit = buffer->_capacity = capacity;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
|
||||
{
|
||||
ldns_buffer_invariant(buffer);
|
||||
assert(!buffer->_fixed);
|
||||
if (buffer->_capacity < buffer->_position + amount) {
|
||||
size_t new_capacity = buffer->_capacity * 3 / 2;
|
||||
|
||||
if (new_capacity < buffer->_position + amount) {
|
||||
new_capacity = buffer->_position + amount;
|
||||
}
|
||||
if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
|
||||
buffer->_status_err = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
buffer->_limit = buffer->_capacity;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int written = 0;
|
||||
size_t remaining;
|
||||
|
||||
if (ldns_buffer_status_ok(buffer)) {
|
||||
ldns_buffer_invariant(buffer);
|
||||
assert(buffer->_limit == buffer->_capacity);
|
||||
|
||||
remaining = ldns_buffer_remaining(buffer);
|
||||
va_start(args, format);
|
||||
written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
|
||||
format, args);
|
||||
va_end(args);
|
||||
if (written == -1) {
|
||||
buffer->_status_err = 1;
|
||||
return -1;
|
||||
} else if ((size_t) written >= remaining) {
|
||||
if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
|
||||
buffer->_status_err = 1;
|
||||
return -1;
|
||||
}
|
||||
va_start(args, format);
|
||||
written = vsnprintf((char *) ldns_buffer_current(buffer),
|
||||
ldns_buffer_remaining(buffer), format, args);
|
||||
va_end(args);
|
||||
if (written == -1) {
|
||||
buffer->_status_err = 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buffer->_position += written;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
void
|
||||
ldns_buffer_free(ldns_buffer *buffer)
|
||||
{
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buffer->_fixed)
|
||||
free(buffer->_data);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void *
|
||||
ldns_buffer_export(ldns_buffer *buffer)
|
||||
{
|
||||
buffer->_fixed = 1;
|
||||
return buffer->_data;
|
||||
}
|
||||
|
||||
int
|
||||
ldns_bgetc(ldns_buffer *buffer)
|
||||
{
|
||||
if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
|
||||
ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
|
||||
/* ldns_buffer_rewind(buffer);*/
|
||||
return EOF;
|
||||
}
|
||||
return (int)ldns_buffer_read_u8(buffer);
|
||||
}
|
||||
|
||||
void
|
||||
ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
|
||||
{
|
||||
size_t tocopy = ldns_buffer_limit(from);
|
||||
|
||||
if(tocopy > ldns_buffer_capacity(result))
|
||||
tocopy = ldns_buffer_capacity(result);
|
||||
ldns_buffer_clear(result);
|
||||
ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
|
||||
ldns_buffer_flip(result);
|
||||
}
|
706
ldns/sbuffer.h
Normal file
706
ldns/sbuffer.h
Normal file
@ -0,0 +1,706 @@
|
||||
/*
|
||||
* buffer.h -- generic memory buffer.
|
||||
*
|
||||
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* See LICENSE for the license.
|
||||
*
|
||||
*
|
||||
* The buffer module implements a generic buffer. The API is based on
|
||||
* the java.nio.Buffer interface.
|
||||
*/
|
||||
|
||||
#ifndef LDNS_SBUFFER_H
|
||||
#define LDNS_SBUFFER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef S_SPLINT_S
|
||||
# define INLINE
|
||||
#else
|
||||
# ifdef SWIG
|
||||
# define INLINE static
|
||||
# else
|
||||
# define INLINE static inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy data allowing for unaligned accesses in network byte order
|
||||
* (big endian).
|
||||
*/
|
||||
INLINE uint16_t
|
||||
ldns_read_uint16(const void *src)
|
||||
{
|
||||
#ifdef ALLOW_UNALIGNED_ACCESSES
|
||||
return ntohs(*(uint16_t *) src);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *) src;
|
||||
return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE uint32_t
|
||||
ldns_read_uint32(const void *src)
|
||||
{
|
||||
#ifdef ALLOW_UNALIGNED_ACCESSES
|
||||
return ntohl(*(uint32_t *) src);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *) src;
|
||||
return ( ((uint32_t) p[0] << 24)
|
||||
| ((uint32_t) p[1] << 16)
|
||||
| ((uint32_t) p[2] << 8)
|
||||
| (uint32_t) p[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data allowing for unaligned accesses in network byte order
|
||||
* (big endian).
|
||||
*/
|
||||
INLINE void
|
||||
ldns_write_uint16(void *dst, uint16_t data)
|
||||
{
|
||||
#ifdef ALLOW_UNALIGNED_ACCESSES
|
||||
* (uint16_t *) dst = htons(data);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *) dst;
|
||||
p[0] = (uint8_t) ((data >> 8) & 0xff);
|
||||
p[1] = (uint8_t) (data & 0xff);
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE void
|
||||
ldns_write_uint32(void *dst, uint32_t data)
|
||||
{
|
||||
#ifdef ALLOW_UNALIGNED_ACCESSES
|
||||
* (uint32_t *) dst = htonl(data);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *) dst;
|
||||
p[0] = (uint8_t) ((data >> 24) & 0xff);
|
||||
p[1] = (uint8_t) ((data >> 16) & 0xff);
|
||||
p[2] = (uint8_t) ((data >> 8) & 0xff);
|
||||
p[3] = (uint8_t) (data & 0xff);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \file sbuffer.h
|
||||
*
|
||||
* This file contains the definition of ldns_buffer, and functions to manipulate those.
|
||||
*/
|
||||
|
||||
/**
|
||||
* implementation of buffers to ease operations
|
||||
*
|
||||
* ldns_buffers can contain arbitrary information, per octet. You can write
|
||||
* to the current end of a buffer, read from the current position, and
|
||||
* access any data within it.
|
||||
*/
|
||||
struct ldns_buffer
|
||||
{
|
||||
/** The current position used for reading/writing */
|
||||
size_t _position;
|
||||
|
||||
/** The read/write limit */
|
||||
size_t _limit;
|
||||
|
||||
/** The amount of data the buffer can contain */
|
||||
size_t _capacity;
|
||||
|
||||
/** The data contained in the buffer */
|
||||
uint8_t *_data;
|
||||
|
||||
/** If the buffer is fixed it cannot be resized */
|
||||
unsigned _fixed : 1;
|
||||
|
||||
/** The current state of the buffer. If writing to the buffer fails
|
||||
* for any reason, this value is changed. This way, you can perform
|
||||
* multiple writes in sequence and check for success afterwards. */
|
||||
unsigned _status_err : 1;
|
||||
};
|
||||
typedef struct ldns_buffer ldns_buffer;
|
||||
|
||||
#ifdef NDEBUG
|
||||
INLINE void
|
||||
ldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer))
|
||||
{
|
||||
}
|
||||
#else
|
||||
INLINE void
|
||||
ldns_buffer_invariant(ldns_buffer *buffer)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer->_position <= buffer->_limit);
|
||||
assert(buffer->_limit <= buffer->_capacity);
|
||||
assert(buffer->_data != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* creates a new buffer with the specified capacity.
|
||||
*
|
||||
* \param[in] capacity the size (in bytes) to allocate for the buffer
|
||||
* \return the created buffer
|
||||
*/
|
||||
ldns_buffer *ldns_buffer_new(size_t capacity);
|
||||
|
||||
/**
|
||||
* creates a buffer with the specified data. The data IS copied
|
||||
* and MEMORY allocations are done. The buffer is not fixed and can
|
||||
* be resized using buffer_reserve().
|
||||
*
|
||||
* \param[in] buffer pointer to the buffer to put the data in
|
||||
* \param[in] data the data to encapsulate in the buffer
|
||||
* \param[in] size the size of the data
|
||||
*/
|
||||
void ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* Setup a buffer with the data pointed to. No data copied, no memory allocs.
|
||||
* The buffer is fixed.
|
||||
* \param[in] buffer pointer to the buffer to put the data in
|
||||
* \param[in] data the data to encapsulate in the buffer
|
||||
* \param[in] size the size of the data
|
||||
*/
|
||||
void ldns_buffer_init_frm_data(ldns_buffer *buffer, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* clears the buffer and make it ready for writing. The buffer's limit
|
||||
* is set to the capacity and the position is set to 0.
|
||||
* \param[in] buffer the buffer to clear
|
||||
*/
|
||||
INLINE void ldns_buffer_clear(ldns_buffer *buffer)
|
||||
{
|
||||
ldns_buffer_invariant(buffer);
|
||||
|
||||
/* reset status here? */
|
||||
|
||||
buffer->_position = 0;
|
||||
buffer->_limit = buffer->_capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* makes the buffer ready for reading the data that has been written to
|
||||
* the buffer. The buffer's limit is set to the current position and
|
||||
* the position is set to 0.
|
||||
*
|
||||
* \param[in] buffer the buffer to flip
|
||||
* \return void
|
||||
*/
|
||||
INLINE void ldns_buffer_flip(ldns_buffer *buffer)
|
||||
{
|
||||
ldns_buffer_invariant(buffer);
|
||||
|
||||
buffer->_limit = buffer->_position;
|
||||
buffer->_position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* make the buffer ready for re-reading the data. The buffer's
|
||||
* position is reset to 0.
|
||||
* \param[in] buffer the buffer to rewind
|
||||
*/
|
||||
INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
|
||||
{
|
||||
ldns_buffer_invariant(buffer);
|
||||
|
||||
buffer->_position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the current position in the buffer (as a number of bytes)
|
||||
* \param[in] buffer the buffer
|
||||
* \return the current position
|
||||
*/
|
||||
INLINE size_t
|
||||
ldns_buffer_position(ldns_buffer *buffer)
|
||||
{
|
||||
return buffer->_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the buffer's position to MARK. The position must be less than
|
||||
* or equal to the buffer's limit.
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] mark the mark to use
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
|
||||
{
|
||||
assert(mark <= buffer->_limit);
|
||||
buffer->_position = mark;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the buffer's position by COUNT bytes. The position must not
|
||||
* be moved behind the buffer's limit or before the beginning of the
|
||||
* buffer.
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] count the count to use
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
|
||||
{
|
||||
assert(buffer->_position + count <= buffer->_limit);
|
||||
buffer->_position += count;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the maximum size of the buffer
|
||||
* \param[in] buffer
|
||||
* \return the size
|
||||
*/
|
||||
INLINE size_t
|
||||
ldns_buffer_limit(ldns_buffer *buffer)
|
||||
{
|
||||
return buffer->_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the buffer's limit. If the buffer's position is greater
|
||||
* than the new limit the position is set to the limit.
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] limit the new limit
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
|
||||
{
|
||||
assert(limit <= buffer->_capacity);
|
||||
buffer->_limit = limit;
|
||||
if (buffer->_position > buffer->_limit)
|
||||
buffer->_position = buffer->_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of bytes the buffer can hold.
|
||||
* \param[in] buffer the buffer
|
||||
* \return the number of bytes
|
||||
*/
|
||||
INLINE size_t
|
||||
ldns_buffer_capacity(ldns_buffer *buffer)
|
||||
{
|
||||
return buffer->_capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the buffer's capacity. The data is reallocated so any
|
||||
* pointers to the data may become invalid. The buffer's limit is set
|
||||
* to the buffer's new capacity.
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] capacity the capacity to use
|
||||
* \return whether this failed or succeeded
|
||||
*/
|
||||
int ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
|
||||
|
||||
/**
|
||||
* ensures BUFFER can contain at least AMOUNT more bytes. The buffer's
|
||||
* capacity is increased if necessary using buffer_set_capacity().
|
||||
*
|
||||
* The buffer's limit is always set to the (possibly increased)
|
||||
* capacity.
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] amount amount to use
|
||||
* \return whether this failed or succeeded
|
||||
*/
|
||||
int ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
|
||||
|
||||
/**
|
||||
* returns a pointer to the data at the indicated position.
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at position
|
||||
* \return the pointer to the data
|
||||
*/
|
||||
INLINE uint8_t *
|
||||
ldns_buffer_at(const ldns_buffer *buffer, size_t at)
|
||||
{
|
||||
assert(at <= buffer->_limit);
|
||||
return buffer->_data + at;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a pointer to the beginning of the buffer (the data at
|
||||
* position 0).
|
||||
* \param[in] buffer the buffer
|
||||
* \return the pointer
|
||||
*/
|
||||
INLINE uint8_t *
|
||||
ldns_buffer_begin(const ldns_buffer *buffer)
|
||||
{
|
||||
return ldns_buffer_at(buffer, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a pointer to the end of the buffer (the data at the buffer's
|
||||
* limit).
|
||||
* \param[in] buffer the buffer
|
||||
* \return the pointer
|
||||
*/
|
||||
INLINE uint8_t *
|
||||
ldns_buffer_end(ldns_buffer *buffer)
|
||||
{
|
||||
return ldns_buffer_at(buffer, buffer->_limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a pointer to the data at the buffer's current position.
|
||||
* \param[in] buffer the buffer
|
||||
* \return the pointer
|
||||
*/
|
||||
INLINE uint8_t *
|
||||
ldns_buffer_current(ldns_buffer *buffer)
|
||||
{
|
||||
return ldns_buffer_at(buffer, buffer->_position);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of bytes remaining between the indicated position and
|
||||
* the limit.
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at indicated position
|
||||
* \return number of bytes
|
||||
*/
|
||||
INLINE size_t
|
||||
ldns_buffer_remaining_at(ldns_buffer *buffer, size_t at)
|
||||
{
|
||||
ldns_buffer_invariant(buffer);
|
||||
assert(at <= buffer->_limit);
|
||||
return buffer->_limit - at;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of bytes remaining between the buffer's position and
|
||||
* limit.
|
||||
* \param[in] buffer the buffer
|
||||
* \return the number of bytes
|
||||
*/
|
||||
INLINE size_t
|
||||
ldns_buffer_remaining(ldns_buffer *buffer)
|
||||
{
|
||||
return ldns_buffer_remaining_at(buffer, buffer->_position);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the buffer has at least COUNT more bytes available.
|
||||
* Before reading or writing the caller needs to ensure enough space
|
||||
* is available!
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at indicated position
|
||||
* \param[in] count how much is available
|
||||
* \return true or false (as int?)
|
||||
*/
|
||||
INLINE int
|
||||
ldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count)
|
||||
{
|
||||
return count <= ldns_buffer_remaining_at(buffer, at);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the buffer has count bytes available at the current position
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] count how much is available
|
||||
* \return true or false (as int?)
|
||||
*/
|
||||
INLINE int
|
||||
ldns_buffer_available(ldns_buffer *buffer, size_t count)
|
||||
{
|
||||
return ldns_buffer_available_at(buffer, buffer->_position, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given data to the buffer at the specified position
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position (in number of bytes) to write the data at
|
||||
* \param[in] data pointer to the data to write to the buffer
|
||||
* \param[in] count the number of bytes of data to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, count));
|
||||
memcpy(buffer->_data + at, data, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes count bytes of data to the current position of the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] data the data to write
|
||||
* \param[in] count the lenght of the data to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
|
||||
{
|
||||
ldns_buffer_write_at(buffer, buffer->_position, data, count);
|
||||
buffer->_position += count;
|
||||
}
|
||||
|
||||
/**
|
||||
* copies the given (null-delimited) string to the specified position at the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position in the buffer
|
||||
* \param[in] str the string to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
|
||||
{
|
||||
ldns_buffer_write_at(buffer, at, str, strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* copies the given (null-delimited) string to the current position at the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] str the string to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
|
||||
{
|
||||
ldns_buffer_write(buffer, str, strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given byte of data at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position in the buffer
|
||||
* \param[in] data the 8 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
|
||||
buffer->_data[at] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given byte of data at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] data the 8 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
|
||||
{
|
||||
ldns_buffer_write_u8_at(buffer, buffer->_position, data);
|
||||
buffer->_position += sizeof(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given 2 byte integer at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position in the buffer
|
||||
* \param[in] data the 16 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
|
||||
ldns_write_uint16(buffer->_data + at, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given 2 byte integer at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] data the 16 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
|
||||
{
|
||||
ldns_buffer_write_u16_at(buffer, buffer->_position, data);
|
||||
buffer->_position += sizeof(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given 4 byte integer at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position in the buffer
|
||||
* \param[in] data the 32 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
|
||||
ldns_write_uint32(buffer->_data + at, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given 4 byte integer at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] data the 32 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
|
||||
{
|
||||
ldns_buffer_write_u32_at(buffer, buffer->_position, data);
|
||||
buffer->_position += sizeof(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* copies count bytes of data at the given position to the given data-array
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position in the buffer to start
|
||||
* \param[out] data buffer to copy to
|
||||
* \param[in] count the length of the data to copy
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, count));
|
||||
memcpy(data, buffer->_data + at, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* copies count bytes of data at the current position to the given data-array
|
||||
* \param[in] buffer the buffer
|
||||
* \param[out] data buffer to copy to
|
||||
* \param[in] count the length of the data to copy
|
||||
*/
|
||||
INLINE void
|
||||
ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
|
||||
{
|
||||
ldns_buffer_read_at(buffer, buffer->_position, data, count);
|
||||
buffer->_position += count;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the byte value at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position in the buffer
|
||||
* \return 1 byte integer
|
||||
*/
|
||||
INLINE uint8_t
|
||||
ldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
|
||||
return buffer->_data[at];
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the byte value at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \return 1 byte integer
|
||||
*/
|
||||
INLINE uint8_t
|
||||
ldns_buffer_read_u8(ldns_buffer *buffer)
|
||||
{
|
||||
uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
|
||||
buffer->_position += sizeof(uint8_t);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the 2-byte integer value at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at position in the buffer
|
||||
* \return 2 byte integer
|
||||
*/
|
||||
INLINE uint16_t
|
||||
ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
|
||||
return ldns_read_uint16(buffer->_data + at);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the 2-byte integer value at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \return 2 byte integer
|
||||
*/
|
||||
INLINE uint16_t
|
||||
ldns_buffer_read_u16(ldns_buffer *buffer)
|
||||
{
|
||||
uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
|
||||
buffer->_position += sizeof(uint16_t);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the 4-byte integer value at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at position in the buffer
|
||||
* \return 4 byte integer
|
||||
*/
|
||||
INLINE uint32_t
|
||||
ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
|
||||
{
|
||||
assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
|
||||
return ldns_read_uint32(buffer->_data + at);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the 4-byte integer value at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \return 4 byte integer
|
||||
*/
|
||||
INLINE uint32_t
|
||||
ldns_buffer_read_u32(ldns_buffer *buffer)
|
||||
{
|
||||
uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
|
||||
buffer->_position += sizeof(uint32_t);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the status of the buffer
|
||||
* \param[in] buffer
|
||||
* \return the status
|
||||
*/
|
||||
INLINE int
|
||||
ldns_buffer_status(ldns_buffer *buffer)
|
||||
{
|
||||
return (int)buffer->_status_err;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
|
||||
* \param[in] buffer the buffer
|
||||
* \return true or false
|
||||
*/
|
||||
INLINE int
|
||||
ldns_buffer_status_ok(ldns_buffer *buffer)
|
||||
{
|
||||
if (buffer) {
|
||||
return ldns_buffer_status(buffer) == 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* prints to the buffer, increasing the capacity if required using
|
||||
* buffer_reserve(). The buffer's position is set to the terminating '\\0'
|
||||
* Returns the number of characters written (not including the
|
||||
* terminating '\\0') or -1 on failure.
|
||||
*/
|
||||
int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
|
||||
ATTR_FORMAT(printf, 2, 3);
|
||||
|
||||
/**
|
||||
* frees the buffer.
|
||||
* \param[in] *buffer the buffer to be freed
|
||||
* \return void
|
||||
*/
|
||||
void ldns_buffer_free(ldns_buffer *buffer);
|
||||
|
||||
/**
|
||||
* Makes the buffer fixed and returns a pointer to the data. The
|
||||
* caller is responsible for free'ing the result.
|
||||
* \param[in] *buffer the buffer to be exported
|
||||
* \return void
|
||||
*/
|
||||
void *ldns_buffer_export(ldns_buffer *buffer);
|
||||
|
||||
/**
|
||||
* Copy contents of the from buffer to the result buffer and then flips
|
||||
* the result buffer. Data will be silently truncated if the result buffer is
|
||||
* too small.
|
||||
* \param[out] *result resulting buffer which is copied to.
|
||||
* \param[in] *from what to copy to result.
|
||||
*/
|
||||
void ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LDNS_SBUFFER_H */
|
1840
ldns/str2wire.c
Normal file
1840
ldns/str2wire.c
Normal file
File diff suppressed because it is too large
Load Diff
532
ldns/str2wire.h
Normal file
532
ldns/str2wire.h
Normal file
@ -0,0 +1,532 @@
|
||||
/**
|
||||
* str2wire.h - read txt presentation of RRs
|
||||
*
|
||||
* (c) NLnet Labs, 2005-2006
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Parses text to wireformat.
|
||||
*/
|
||||
|
||||
#ifndef LDNS_STR2WIRE_H
|
||||
#define LDNS_STR2WIRE_H
|
||||
|
||||
/* include rrdef for MAX_DOMAINLEN constant */
|
||||
#include <ldns/rrdef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
struct ldns_struct_lookup_table;
|
||||
|
||||
/** buffer to read an RR, cannot be larger than 64K because of packet size */
|
||||
#define LDNS_RR_BUF_SIZE 65535 /* bytes */
|
||||
#define LDNS_DEFAULT_TTL 3600
|
||||
|
||||
/*
|
||||
* To convert class and type to string see
|
||||
* ldns_get_rr_class_by_name(str)
|
||||
* ldns_get_rr_type_by_name(str)
|
||||
* from rrdef.h
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert text string into dname wireformat, mallocless, with user buffer.
|
||||
* @param str: the text string with the domain name.
|
||||
* @param buf: the result buffer, suggested size LDNS_MAX_DOMAINLEN+1
|
||||
* @param len: length of the buffer on input, length of the result on output.
|
||||
* @return 0 on success, otherwise an error.
|
||||
*/
|
||||
int ldns_str2wire_dname_buf(const char* str, uint8_t* buf, size_t* len);
|
||||
|
||||
/**
|
||||
* Same as ldns_str2wire_dname_buf, but concatenates origin if the domain
|
||||
* name is relative (does not end in '.').
|
||||
* @param str: the text string with the domain name.
|
||||
* @param buf: the result buffer, suggested size LDNS_MAX_DOMAINLEN+1
|
||||
* @param len: length of the buffer on input, length of the result on output.
|
||||
* @param origin: the origin to append or NULL (nothing is appended).
|
||||
* @param origin_len: length of origin.
|
||||
* @return 0 on success, otherwise an error.
|
||||
*/
|
||||
int ldns_str2wire_dname_buf_origin(const char* str, uint8_t* buf, size_t* len,
|
||||
uint8_t* origin, size_t origin_len);
|
||||
|
||||
/**
|
||||
* Convert text string into dname wireformat
|
||||
* @param str: the text string with the domain name.
|
||||
* @param len: returned length of wireformat.
|
||||
* @return wireformat dname (malloced) or NULL on failure.
|
||||
*/
|
||||
uint8_t* ldns_str2wire_dname(const char* str, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert text RR to wireformat, with user buffer.
|
||||
* @param str: the RR data in text presentation format.
|
||||
* @param rr: the buffer where the result is stored into. This buffer has
|
||||
* the wire-dname(uncompressed), type, class, ttl, rdatalen, rdata.
|
||||
* These values are probably not aligned, and in network format.
|
||||
* Use the ldns_wirerr_get_xxx functions to access them safely.
|
||||
* buffer size LDNS_RR_BUF_SIZE is suggested.
|
||||
* @param len: on input the length of the buffer, on output the amount of
|
||||
* the buffer used for the rr.
|
||||
* @param dname_len: if non-NULL, filled with the dname length as result.
|
||||
* Because after the dname you find the type, class, ttl, rdatalen, rdata.
|
||||
* @param default_ttl: TTL used if no TTL available.
|
||||
* @param origin: used for origin dname (if not NULL)
|
||||
* @param origin_len: length of origin.
|
||||
* @param prev: used for prev_rr dname (if not NULL)
|
||||
* @param prev_len: length of prev.
|
||||
* @return 0 on success, an error on failure.
|
||||
*/
|
||||
int ldns_str2wire_rr_buf(const char* str, uint8_t* rr, size_t* len,
|
||||
size_t* dname_len, uint32_t default_ttl, uint8_t* origin,
|
||||
size_t origin_len, uint8_t* prev, size_t prev_len);
|
||||
|
||||
/**
|
||||
* Same as ldns_str2wire_rr_buf, but there is no rdata, it returns an RR
|
||||
* with zero rdata and no ttl. It has name, type, class.
|
||||
* You can access those with the ldns_wirerr_get_type and class functions.
|
||||
* @param str: the RR data in text presentation format.
|
||||
* @param rr: the buffer where the result is stored into.
|
||||
* @param len: on input the length of the buffer, on output the amount of
|
||||
* the buffer used for the rr.
|
||||
* @param dname_len: if non-NULL, filled with the dname length as result.
|
||||
* Because after the dname you find the type, class, ttl, rdatalen, rdata.
|
||||
* @param origin: used for origin dname (if not NULL)
|
||||
* @param origin_len: length of origin.
|
||||
* @param prev: used for prev_rr dname (if not NULL)
|
||||
* @param prev_len: length of prev.
|
||||
* @return 0 on success, an error on failure.
|
||||
*/
|
||||
int ldns_str2wire_rr_question_buf(const char* str, uint8_t* rr, size_t* len,
|
||||
size_t* dname_len, uint8_t* origin, size_t origin_len, uint8_t* prev,
|
||||
size_t prev_len);
|
||||
|
||||
/**
|
||||
* Get the type of the RR.
|
||||
* @param rr: the RR in wire format.
|
||||
* @param len: rr length.
|
||||
* @param dname_len: dname length to skip.
|
||||
* @return type in host byteorder
|
||||
*/
|
||||
uint16_t ldns_wirerr_get_type(uint8_t* rr, size_t len, size_t dname_len);
|
||||
|
||||
/**
|
||||
* Get the class of the RR.
|
||||
* @param rr: the RR in wire format.
|
||||
* @param len: rr length.
|
||||
* @param dname_len: dname length to skip.
|
||||
* @return class in host byteorder
|
||||
*/
|
||||
uint16_t ldns_wirerr_get_class(uint8_t* rr, size_t len, size_t dname_len);
|
||||
|
||||
/**
|
||||
* Get the ttl of the RR.
|
||||
* @param rr: the RR in wire format.
|
||||
* @param len: rr length.
|
||||
* @param dname_len: dname length to skip.
|
||||
* @return ttl in host byteorder
|
||||
*/
|
||||
uint32_t ldns_wirerr_get_ttl(uint8_t* rr, size_t len, size_t dname_len);
|
||||
|
||||
/**
|
||||
* Get the rdata length of the RR.
|
||||
* @param rr: the RR in wire format.
|
||||
* @param len: rr length.
|
||||
* @param dname_len: dname length to skip.
|
||||
* @return rdata length in host byteorder
|
||||
* If the rdata length is larger than the rr-len allows, it is truncated.
|
||||
* So, that it is safe to read the data length returned
|
||||
* from this function from the rdata pointer of ldns_wirerr_get_rdata.
|
||||
*/
|
||||
uint16_t ldns_wirerr_get_rdatalen(uint8_t* rr, size_t len, size_t dname_len);
|
||||
|
||||
/**
|
||||
* Get the rdata pointer of the RR.
|
||||
* @param rr: the RR in wire format.
|
||||
* @param len: rr length.
|
||||
* @param dname_len: dname length to skip.
|
||||
* @return rdata pointer
|
||||
*/
|
||||
uint8_t* ldns_wirerr_get_rdata(uint8_t* rr, size_t len, size_t dname_len);
|
||||
|
||||
/**
|
||||
* Get the rdata pointer of the RR. prefixed with rdata length.
|
||||
* @param rr: the RR in wire format.
|
||||
* @param len: rr length.
|
||||
* @param dname_len: dname length to skip.
|
||||
* @return pointer to rdatalength, followed by the rdata.
|
||||
*/
|
||||
uint8_t* ldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
|
||||
|
||||
/**
|
||||
* Parse result codes
|
||||
*/
|
||||
#define LDNS_WIREPARSE_MASK 0x0fff
|
||||
#define LDNS_WIREPARSE_SHIFT 12
|
||||
#define LDNS_WIREPARSE_ERROR(e) ((e)&LDNS_WIREPARSE_MASK)
|
||||
#define LDNS_WIREPARSE_OFFSET(e) (((e)&~LDNS_WIREPARSE_MASK)>>LDNS_WIREPARSE_SHIFT)
|
||||
/* use lookuptable to get error string, ldns_wireparse_errors */
|
||||
#define LDNS_WIREPARSE_ERR_OK 0
|
||||
#define LDNS_WIREPARSE_ERR_GENERAL 342
|
||||
#define LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW 343
|
||||
#define LDNS_WIREPARSE_ERR_DOMAINNAME_UNDERFLOW 344
|
||||
#define LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL 345
|
||||
#define LDNS_WIREPARSE_ERR_LABEL_OVERFLOW 346
|
||||
#define LDNS_WIREPARSE_ERR_EMPTY_LABEL 347
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE 348
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX 349
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_TTL 350
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_TYPE 351
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_CLASS 352
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_RDATA 353
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_MISSING_VALUE 354
|
||||
#define LDNS_WIREPARSE_ERR_INVALID_STR 355
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_B64 356
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_B32_EXT 357
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_HEX 358
|
||||
#define LDNS_WIREPARSE_ERR_CERT_BAD_ALGORITHM 359
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_TIME 360
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_PERIOD 361
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_ILNP64 362
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_EUI48 363
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_EUI64 364
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_TAG 365
|
||||
#define LDNS_WIREPARSE_ERR_NOT_IMPL 366
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_INT 367
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_IP4 368
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_IP6 369
|
||||
#define LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW 370
|
||||
#define LDNS_WIREPARSE_ERR_INCLUDE 371
|
||||
#define LDNS_WIREPARSE_ERR_PARENTHESIS 372
|
||||
|
||||
/**
|
||||
* Get reference to a constant string for the (parse) error.
|
||||
* @param e: error return value
|
||||
* @return string.
|
||||
*/
|
||||
const char* ldns_get_errorstr_parse(int e);
|
||||
|
||||
/**
|
||||
* wire parse state for parsing files
|
||||
*/
|
||||
struct ldns_file_parse_state {
|
||||
/** the origin domain name, if len!=0. uncompressed wireformat */
|
||||
uint8_t origin[LDNS_MAX_DOMAINLEN+1];
|
||||
/** length of origin domain name, in bytes. 0 if not set. */
|
||||
size_t origin_len;
|
||||
/** the previous domain name, if len!=0. uncompressed wireformat*/
|
||||
uint8_t prev_rr[LDNS_MAX_DOMAINLEN+1];
|
||||
/** length of the previous domain name, in bytes. 0 if not set. */
|
||||
size_t prev_rr_len;
|
||||
/** default TTL, this is used if the text does not specify a TTL,
|
||||
* host byteorder */
|
||||
uint32_t default_ttl;
|
||||
/** line number information */
|
||||
int lineno;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read one RR from zonefile with buffer for the data.
|
||||
* @param in: file that is read from (one RR, multiple lines if it spans them).
|
||||
* @param rr: this is malloced by the user and the result is stored here,
|
||||
* if an RR is read. If no RR is read this is signalled with the
|
||||
* return len set to 0 (for ORIGIN, TTL directives).
|
||||
* @param len: on input, the length of the rr buffer. on output the rr len.
|
||||
* Buffer size of 64k should be enough.
|
||||
* @param dname_len: returns the length of the dname initial part of the rr.
|
||||
* @param parse_state: pass a pointer to user-allocated struct.
|
||||
* Contents are maintained by this function.
|
||||
* If you pass NULL then ORIGIN and TTL directives are not honored.
|
||||
* You can start out with a particular origin by pre-filling it.
|
||||
* otherwise, zero the structure before passing it.
|
||||
* lineno is incremented when a newline is passed by the parser,
|
||||
* you should initialize it at 1 at the start of the file.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
|
||||
struct ldns_file_parse_state* parse_state);
|
||||
|
||||
/**
|
||||
* Convert one rdf in rdata to wireformat and parse from string.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @param rdftype: the type of the rdf.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
|
||||
ldns_rdf_type rdftype);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_INT8 from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_int8_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_INT16 from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_int16_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_INT32 from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_int32_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_A from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_a_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_AAAA from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_aaaa_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_STR from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_str_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_APL from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_apl_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_B64 from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_b64_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_B32_EXT from string to wireformat.
|
||||
* And also LDNS_RDF_TYPE_NSEC3_NEXT_OWNER.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_b32_ext_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_HEX from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_NSEC from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_nsec_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_TYPE from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_type_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_CLASS from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_class_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_CERT_ALG from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_cert_alg_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_ALG from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_alg_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_TIME from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_time_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_PERIOD from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_LOC from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_WKS from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_NSAP from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_nsap_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_ATMA from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_atma_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_IPSECKEY from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_ipseckey_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_NSEC3_SALT from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_nsec3_salt_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_ILNP64 from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_ilnp64_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_EUI48 from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_eui48_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_EUI64 from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_eui64_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_TAG from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_tag_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_LONG_STR from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_long_str_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type LDNS_RDF_TYPE_INT16_DATA from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int ldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LDNS_STR2WIRE_H */
|
1925
ldns/wire2str.c
Normal file
1925
ldns/wire2str.c
Normal file
File diff suppressed because it is too large
Load Diff
973
ldns/wire2str.h
Normal file
973
ldns/wire2str.h
Normal file
@ -0,0 +1,973 @@
|
||||
/**
|
||||
* wire2str.h - txt presentation of RRs
|
||||
*
|
||||
* (c) NLnet Labs, 2005-2006
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Contains functions to translate the wireformat to text
|
||||
* representation, as well as functions to print them.
|
||||
*/
|
||||
|
||||
#ifndef LDNS_WIRE2STR_H
|
||||
#define LDNS_WIRE2STR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
struct ldns_struct_lookup_table;
|
||||
enum ldns_enum_rdf_type;
|
||||
|
||||
/* lookup tables for standard DNS stuff */
|
||||
/** Taken from RFC 2535, section 7. */
|
||||
extern struct ldns_struct_lookup_table* ldns_algorithms;
|
||||
/** DS record hash algorithms */
|
||||
extern struct ldns_struct_lookup_table* ldns_hashes;
|
||||
/** Taken from RFC 2538, section 2.1. */
|
||||
extern struct ldns_struct_lookup_table* ldns_cert_algorithms;
|
||||
/** Response codes */
|
||||
extern struct ldns_struct_lookup_table* ldns_rcodes;
|
||||
/** Operation codes */
|
||||
extern struct ldns_struct_lookup_table* ldns_opcodes;
|
||||
/** EDNS flags */
|
||||
extern struct ldns_struct_lookup_table* ldns_edns_flags;
|
||||
/** EDNS option codes */
|
||||
extern struct ldns_struct_lookup_table* ldns_edns_options;
|
||||
/** error string from wireparse */
|
||||
extern struct ldns_struct_lookup_table* ldns_wireparse_errors;
|
||||
|
||||
/**
|
||||
* Convert wireformat packet to a string representation
|
||||
* @param data: wireformat packet data (starting at ID bytes).
|
||||
* @param len: length of packet.
|
||||
* @return string(malloced) or NULL on failure.
|
||||
*/
|
||||
char* ldns_wire2str_pkt(uint8_t* data, size_t len);
|
||||
|
||||
/**
|
||||
* Convert wireformat RR to a string representation.
|
||||
* @param rr: the wireformat RR, in uncompressed form. Starts at the domain
|
||||
* name start, ends with the rdata of the RR.
|
||||
* @param len: length of the rr wireformat.
|
||||
* @return string(malloced) or NULL on failure.
|
||||
*/
|
||||
char* ldns_wire2str_rr(uint8_t* rr, size_t len);
|
||||
|
||||
/**
|
||||
* Conver wire dname to a string.
|
||||
* @param dname: the dname in uncompressed wireformat.
|
||||
* @param dname_len: length of the dname.
|
||||
* @return string or NULL on failure.
|
||||
*/
|
||||
char* ldns_wire2str_dname(uint8_t* dname, size_t dname_len);
|
||||
|
||||
/**
|
||||
* Convert wire RR type to a string, 'MX', 'TYPE1234'...
|
||||
* @param rrtype: the RR type in host order.
|
||||
* @return malloced string with the RR type or NULL on malloc failure.
|
||||
*/
|
||||
char* ldns_wire2str_type(uint16_t rrtype);
|
||||
|
||||
/**
|
||||
* Convert wire RR class to a string, 'IN', 'CLASS1'.
|
||||
* @param rrclass: the RR class in host order.
|
||||
* @return malloced string with the RR class or NULL on malloc failure.
|
||||
*/
|
||||
char* ldns_wire2str_class(uint16_t rrclass);
|
||||
|
||||
/**
|
||||
* Convert wire packet rcode to a string, 'NOERROR', 'NXDOMAIN'...
|
||||
* @param rcode: as integer, host order
|
||||
* @return malloced string with the rcode or NULL on malloc failure.
|
||||
*/
|
||||
char* ldns_wire2str_rcode(int rcode);
|
||||
|
||||
/**
|
||||
* Print to string, move string along for next content. With va_list.
|
||||
* @param str: string buffer. Adjusted at end to after the output.
|
||||
* @param slen: length of the string buffer. Adjusted at end.
|
||||
* @param format: printf format string.
|
||||
* @param args: arguments for printf.
|
||||
* @return number of characters needed. Can be larger than slen.
|
||||
*/
|
||||
int ldns_str_vprint(char** str, size_t* slen, const char* format, va_list args);
|
||||
|
||||
/**
|
||||
* Print to string, move string along for next content.
|
||||
* @param str: string buffer. Adjusted at end to after the output.
|
||||
* @param slen: length of the string buffer. Adjusted at end.
|
||||
* @param format: printf format string and arguments for it.
|
||||
* @return number of characters needed. Can be larger than slen.
|
||||
*/
|
||||
int ldns_str_print(char** str, size_t* slen, const char* format, ...)
|
||||
ATTR_FORMAT(printf, 3, 4);
|
||||
|
||||
/**
|
||||
* Convert wireformat packet to a string representation with user buffer
|
||||
* It appends every RR with default comments.
|
||||
* For more formatter options use the function: TBD(TODO)
|
||||
* @param data: wireformat packet data (starting at ID bytes).
|
||||
* @param data_len: length of packet.
|
||||
* @param str: the string buffer for the output.
|
||||
* If you pass NULL as the str the return value of the function is
|
||||
* the str_len you need for the entire packet. It does not include
|
||||
* the 0 byte at the end.
|
||||
* @param str_len: the size of the string buffer. If more is needed, it'll
|
||||
* silently truncate the output to fit in the buffer.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_pkt_buf(uint8_t* data, size_t data_len, char* str,
|
||||
size_t str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat packet to a string representation with user buffer
|
||||
* It appends every RR with default comments.
|
||||
* For more formatter options use the function: TBD(TODO)
|
||||
* @param data: wireformat packet data (starting at ID bytes).
|
||||
* @param data_len: length of packet.
|
||||
* @param str: the string buffer for the output.
|
||||
* @param str_len: the size of the string buffer.
|
||||
* @return number of characters for string.
|
||||
* returns the number of characters that are needed (except terminating null),
|
||||
* so it may return a value larger than str_len.
|
||||
* On error you get less output (i.e. shorter output in str (null terminated))
|
||||
* On exit the data, data_len, str and str_len values are adjusted to move them
|
||||
* from their original position along the input and output for the content
|
||||
* that has been consumed (and produced) by this function. If the end of the
|
||||
* output string is reached, *str_len is set to 0. The output string is null
|
||||
* terminated (shortening the output if necessary). If the end of the input
|
||||
* is reached *data_len is set to 0.
|
||||
*/
|
||||
int ldns_wire2str_pkt_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat rr to string, with user buffers. It shifts the arguments
|
||||
* to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param pkt: packet for decompression, if NULL no decompression.
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_rr_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, uint8_t* pkt, size_t pktlen);
|
||||
|
||||
/**
|
||||
* Scan wireformat question rr to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param pkt: packet for decompression, if NULL no decompression.
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_rrquestion_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, uint8_t* pkt, size_t pktlen);
|
||||
|
||||
/**
|
||||
* Scan wireformat RR to string in unknown RR format, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param pkt: packet for decompression, if NULL no decompression.
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_rr_unknown_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, uint8_t* pkt, size_t pktlen);
|
||||
|
||||
/**
|
||||
* Print to string the RR-information comment in default format,
|
||||
* with user buffers. Moves string along.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param rr: wireformat data.
|
||||
* @param rrlen: length of data buffer.
|
||||
* @param dname_off: offset in buffer behind owner dname, the compressed size
|
||||
* of the owner name.
|
||||
* @param rrtype: type of the RR, host format.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_rr_comment_print(char** str, size_t* str_len, uint8_t* rr,
|
||||
size_t rrlen, size_t dname_off, uint16_t rrtype);
|
||||
|
||||
/**
|
||||
* Scan wireformat packet header to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_header_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat rdata to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer. The length of the rdata in the
|
||||
* buffer. The rdatalen itself has already been scanned, the data
|
||||
* points to the rdata after the rdatalen.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param rrtype: RR type of Rdata, host format.
|
||||
* @param pkt: packet for decompression, if NULL no decompression.
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_rdata_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, uint16_t rrtype, uint8_t* pkt, size_t pktlen);
|
||||
|
||||
/**
|
||||
* Scan wireformat rdata to string in unknown format, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer, the length of the rdata in buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_rdata_unknown_scan(uint8_t** data, size_t* data_len,
|
||||
char** str, size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat domain name to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param pkt: packet for decompression, if NULL no decompression.
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_dname_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, uint8_t* pkt, size_t pktlen);
|
||||
|
||||
/**
|
||||
* Scan wireformat rr type to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_type_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat rr class to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_class_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat rr ttl to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_ttl_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
|
||||
/**
|
||||
* Print host format rr type to string. Moves string along, user buffers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param rrtype: host format rr type.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_type_print(char** str, size_t* str_len, uint16_t rrtype);
|
||||
|
||||
/**
|
||||
* Print host format rr class to string. Moves string along, user buffers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param rrclass: host format rr class.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_class_print(char** str, size_t* str_len, uint16_t rrclass);
|
||||
|
||||
/**
|
||||
* Print host format rcode to string. Moves string along, user buffers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param rcode: host format rcode number.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_rcode_print(char** str, size_t* str_len, int rcode);
|
||||
|
||||
/**
|
||||
* Print host format opcode to string. Moves string along, user buffers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param opcode: host format opcode number.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_opcode_print(char** str, size_t* str_len, int opcode);
|
||||
|
||||
/**
|
||||
* Print host format EDNS0 option to string. Moves string along, user buffers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param opcode: host format option number.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_option_code_print(char** str, size_t* str_len,
|
||||
uint16_t opcode);
|
||||
|
||||
/**
|
||||
* Convert RR to string presentation format, on one line. User buffer.
|
||||
* @param rr: wireformat RR data
|
||||
* @param rr_len: length of the rr wire data.
|
||||
* @param str: the string buffer to write to.
|
||||
* If you pass NULL as the str, the return value of the function is
|
||||
* the str_len you need for the entire packet. It does not include
|
||||
* the 0 byte at the end.
|
||||
* @param str_len: the size of the string buffer. If more is needed, it'll
|
||||
* silently truncate the output to fit in the buffer.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_rr_buf(uint8_t* rr, size_t rr_len, char* str,
|
||||
size_t str_len);
|
||||
|
||||
/**
|
||||
* 3597 printout of an RR in unknown rr format.
|
||||
* There are more format and comment options available for printout
|
||||
* with the function: TBD(TODO)
|
||||
* @param rr: wireformat RR data
|
||||
* @param rr_len: length of the rr wire data.
|
||||
* @param str: the string buffer to write to.
|
||||
* If you pass NULL as the str, the return value of the function is
|
||||
* the str_len you need for the entire rr. It does not include
|
||||
* the 0 byte at the end.
|
||||
* @param str_len: the size of the string buffer. If more is needed, it'll
|
||||
* silently truncate the output to fit in the buffer.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_rr_unknown_buf(uint8_t* rr, size_t rr_len, char* str,
|
||||
size_t str_len);
|
||||
|
||||
/**
|
||||
* This creates the comment to print after the RR. ; keytag=... , and other
|
||||
* basic comments for RRs.
|
||||
* There are more format and comment options available for printout
|
||||
* with the function: TBD(TODO)
|
||||
* @param rr: wireformat RR data
|
||||
* @param rr_len: length of the rr wire data.
|
||||
* @param dname_len: length of the dname in front of the RR.
|
||||
* @param str: the string buffer to write to.
|
||||
* If you pass NULL as the str, the return value of the function is
|
||||
* the str_len you need for the entire comment. It does not include
|
||||
* the 0 byte at the end.
|
||||
* @param str_len: the size of the string buffer. If more is needed, it'll
|
||||
* silently truncate the output to fit in the buffer.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_rr_comment_buf(uint8_t* rr, size_t rr_len, size_t dname_len,
|
||||
char* str, size_t str_len);
|
||||
|
||||
/**
|
||||
* Convert RDATA to string presentation format, on one line. User buffer.
|
||||
* @param rdata: wireformat rdata part of an RR.
|
||||
* @param rdata_len: length of the rr wire data.
|
||||
* @param str: the string buffer to write to.
|
||||
* If you pass NULL as the str, the return value of the function is
|
||||
* the str_len you need for the entire packet. It does not include
|
||||
* the 0 byte at the end.
|
||||
* @param str_len: the size of the string buffer. If more is needed, it'll
|
||||
* silently truncate the output to fit in the buffer.
|
||||
* @param rrtype: rr type of the data
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_rdata_buf(uint8_t* rdata, size_t rdata_len, char* str,
|
||||
size_t str_len, uint16_t rrtype);
|
||||
|
||||
/**
|
||||
* Convert wire RR type to a string, 'MX', 'TYPE12'. With user buffer.
|
||||
* @param rrtype: the RR type in host order.
|
||||
* @param str: the string to write to.
|
||||
* @param len: length of str.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_type_buf(uint16_t rrtype, char* str, size_t len);
|
||||
|
||||
/**
|
||||
* Convert wire RR class to a string, 'IN', 'CLASS12'. With user buffer.
|
||||
* @param rrclass: the RR class in host order.
|
||||
* @param str: the string to write to.
|
||||
* @param len: length of str.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_class_buf(uint16_t rrclass, char* str, size_t len);
|
||||
|
||||
/**
|
||||
* Convert wire RR rcode to a string, 'NOERROR', 'NXDOMAIN'. With user buffer.
|
||||
* @param rcode: rcode as integer in host order
|
||||
* @param str: the string to write to.
|
||||
* @param len: length of str.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_rcode_buf(int rcode, char* str, size_t len);
|
||||
|
||||
/**
|
||||
* Convert wire dname to a string, "example.com.". With user buffer.
|
||||
* @param dname: the dname in uncompressed wireformat.
|
||||
* @param dname_len: length of the dname.
|
||||
* @param str: the string to write to.
|
||||
* @param len: length of string.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger than str_len if output was truncated.
|
||||
*/
|
||||
int ldns_wire2str_dname_buf(uint8_t* dname, size_t dname_len, char* str,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* Scan wireformat rdf field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param rdftype: the type of the rdata field.
|
||||
* @param pkt: packet for decompression, if NULL no decompression.
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_rdf_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, enum ldns_enum_rdf_type rdftype, uint8_t* pkt,
|
||||
size_t pktlen);
|
||||
|
||||
/**
|
||||
* Scan wireformat int8 field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_int8_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat int16 field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_int16_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat int32 field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_int32_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat period field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_period_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat tsigtime field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_tsigtime_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat ip4 A field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_a_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat ip6 AAAA field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_aaaa_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat str field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_str_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat apl field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_apl_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat b32_ext field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_b32_ext_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat b64 field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_b64_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat hex field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_hex_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat nsec bitmap field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_nsec_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat nsec3_salt field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_nsec3_salt_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat cert_alg field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_cert_alg_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat alg field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_alg_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat type unknown field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_unknown_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat time field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_time_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat LOC field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_loc_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat WKS field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_wks_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat NSAP field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_nsap_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat ATMA field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_atma_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat IPSECKEY field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param pkt: packet for decompression, if NULL no decompression.
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_ipseckey_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, uint8_t* pkt, size_t pktlen);
|
||||
|
||||
/**
|
||||
* Scan wireformat int16_data field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_int16_data_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat nsec3_next_owner field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_nsec3_next_owner_scan(uint8_t** data, size_t* data_len,
|
||||
char** str, size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat ILNP64 field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_ilnp64_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat EUI48 field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_eui48_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat EUI64 field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_eui64_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat TAG field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_tag_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat long_str field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int ldns_wire2str_long_str_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Print EDNS LLQ option data to string. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_llq_print(char** str, size_t* str_len,
|
||||
uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Print EDNS UL option data to string. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_ul_print(char** str, size_t* str_len,
|
||||
uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Print EDNS NSID option data to string. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_nsid_print(char** str, size_t* str_len,
|
||||
uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Print EDNS DAU option data to string. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_dau_print(char** str, size_t* str_len,
|
||||
uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Print EDNS DHU option data to string. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_dhu_print(char** str, size_t* str_len,
|
||||
uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Print EDNS N3U option data to string. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_n3u_print(char** str, size_t* str_len,
|
||||
uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Print EDNS SUBNET option data to string. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_subnet_print(char** str, size_t* str_len,
|
||||
uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Print an EDNS option as OPT: VALUE. User buffers, moves string pointers.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param option_code: host format EDNS option code.
|
||||
* @param option_data: buffer with EDNS option code data.
|
||||
* @param option_len: length of the data for this option.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_option_print(char** str, size_t* str_len,
|
||||
uint16_t option_code, uint8_t* option_data, size_t option_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat EDNS OPT to string, with user buffers.
|
||||
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @param pkt: packet with header and other info (may be NULL)
|
||||
* @param pktlen: length of packet buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
*/
|
||||
int ldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len, uint8_t* pkt, size_t pktlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LDNS_WIRE2STR_H */
|
@ -49,6 +49,7 @@
|
||||
#include "services/cache/infra.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
int
|
||||
context_finalize(struct ub_ctx* ctx)
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "util/data/packed_rrset.h"
|
||||
struct libworker;
|
||||
struct tube;
|
||||
struct ldns_buffer;
|
||||
struct event_base;
|
||||
|
||||
/**
|
||||
@ -281,7 +282,7 @@ uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);
|
||||
* @return: an alloc, or NULL on mem error.
|
||||
*/
|
||||
uint8_t* context_serialize_answer(struct ctx_query* q, int err,
|
||||
ldns_buffer* pkt, uint32_t* len);
|
||||
struct ldns_buffer* pkt, uint32_t* len);
|
||||
|
||||
/**
|
||||
* Serialize a query cancellation. Serializes query async id
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "services/localzone.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include <signal.h>
|
||||
#endif
|
||||
@ -1173,18 +1174,10 @@ int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name)
|
||||
/* Add new RR data */
|
||||
int ub_ctx_data_add(struct ub_ctx* ctx, const char *data)
|
||||
{
|
||||
ldns_buffer* buf;
|
||||
int res = ub_ctx_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
buf = ldns_buffer_new(ctx->env->cfg->msg_buffer_size);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
if(!buf) return UB_NOMEM;
|
||||
|
||||
res = local_zones_add_RR(ctx->local_zones, data, buf);
|
||||
|
||||
ldns_buffer_free(buf);
|
||||
res = local_zones_add_RR(ctx->local_zones, data);
|
||||
return (!res) ? UB_NOMEM : UB_NOERROR;
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,6 @@
|
||||
* returns from the procedure when done.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/wire2host.h>
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
@ -70,6 +68,8 @@
|
||||
#include "util/tube.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/str2wire.h"
|
||||
|
||||
/** handle new query command for bg worker */
|
||||
static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len);
|
||||
@ -566,22 +566,12 @@ static int
|
||||
setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
|
||||
struct query_info* qinfo, struct edns_data* edns)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
qinfo->qtype = (uint16_t)q->res->qtype;
|
||||
qinfo->qclass = (uint16_t)q->res->qclass;
|
||||
rdf = ldns_dname_new_frm_str(q->res->qname);
|
||||
if(!rdf) {
|
||||
qinfo->qname = ldns_str2wire_dname(q->res->qname, &qinfo->qname_len);
|
||||
if(!qinfo->qname) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef UNBOUND_ALLOC_LITE
|
||||
qinfo->qname = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
|
||||
qinfo->qname_len = ldns_rdf_size(rdf);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
rdf = 0;
|
||||
#else
|
||||
qinfo->qname = ldns_rdf_data(rdf);
|
||||
qinfo->qname_len = ldns_rdf_size(rdf);
|
||||
#endif
|
||||
edns->edns_present = 1;
|
||||
edns->ext_rcode = 0;
|
||||
edns->edns_version = 0;
|
||||
@ -590,7 +580,6 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
|
||||
edns->udp_size = (uint16_t)ldns_buffer_capacity(
|
||||
w->back->udp_buff);
|
||||
else edns->udp_size = 65535;
|
||||
ldns_rdf_free(rdf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ struct comm_point;
|
||||
struct comm_reply;
|
||||
struct regional;
|
||||
struct tube;
|
||||
struct ldns_buffer;
|
||||
struct event_base;
|
||||
|
||||
/**
|
||||
@ -174,15 +175,15 @@ void libworker_handle_result_write(struct tube* tube, uint8_t* msg, size_t len,
|
||||
int err, void* arg);
|
||||
|
||||
/** mesh callback with fg results */
|
||||
void libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
void libworker_fg_done_cb(void* arg, int rcode, struct ldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
|
||||
/** mesh callback with bg results */
|
||||
void libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
void libworker_bg_done_cb(void* arg, int rcode, struct ldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
|
||||
/** mesh callback with event results */
|
||||
void libworker_event_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
void libworker_event_done_cb(void* arg, int rcode, struct ldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
|
||||
/**
|
||||
@ -194,7 +195,7 @@ void libworker_event_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
* On error, the res may contain a different status
|
||||
* (out of memory is not secure, not bogus).
|
||||
*/
|
||||
void libworker_enter_result(struct ub_result* res, ldns_buffer* buf,
|
||||
void libworker_enter_result(struct ub_result* res, struct ldns_buffer* buf,
|
||||
struct regional* temp, enum sec_status msg_security);
|
||||
|
||||
#endif /* LIBUNBOUND_WORKER_H */
|
||||
|
1
services/cache/dns.c
vendored
1
services/cache/dns.c
vendored
@ -50,6 +50,7 @@
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
/** store rrsets in the rrset cache.
|
||||
* @param env: module environment with caches.
|
||||
|
2
services/cache/infra.c
vendored
2
services/cache/infra.c
vendored
@ -39,7 +39,7 @@
|
||||
* This file contains the infrastructure cache.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/rr.h>
|
||||
#include "ldns/rrdef.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
|
1
services/cache/rrset.c
vendored
1
services/cache/rrset.c
vendored
@ -40,6 +40,7 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
@ -75,7 +76,7 @@ verbose_print_addr(struct addrinfo *addr)
|
||||
#endif /* INET6 */
|
||||
if(inet_ntop(addr->ai_family, sinaddr, buf,
|
||||
(socklen_t)sizeof(buf)) == 0) {
|
||||
strncpy(buf, "(null)", sizeof(buf));
|
||||
strlcpy(buf, "(null)", sizeof(buf));
|
||||
}
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
verbose(VERB_ALGO, "creating %s%s socket %s %d",
|
||||
@ -581,9 +582,9 @@ make_sock_port(int stype, const char* ifname, const char* port,
|
||||
*noip6 = 0;
|
||||
return -1;
|
||||
}
|
||||
strncpy(newif, ifname, sizeof(newif));
|
||||
strlcpy(newif, ifname, sizeof(newif));
|
||||
newif[s-ifname] = 0;
|
||||
strncpy(p, s+1, sizeof(p));
|
||||
strlcpy(p, s+1, sizeof(p));
|
||||
p[strlen(s+1)]=0;
|
||||
return make_sock(stype, newif, p, hints, v6only, noip6,
|
||||
rcv, snd);
|
||||
|
@ -46,6 +46,7 @@
|
||||
struct listen_list;
|
||||
struct config_file;
|
||||
struct addrinfo;
|
||||
struct ldns_buffer;
|
||||
|
||||
/**
|
||||
* Listening for queries structure.
|
||||
@ -57,7 +58,7 @@ struct listen_dnsport {
|
||||
|
||||
/** buffer shared by UDP connections, since there is only one
|
||||
datagram at any time. */
|
||||
ldns_buffer* udp_buff;
|
||||
struct ldns_buffer* udp_buff;
|
||||
|
||||
/** list of comm points used to get incoming events */
|
||||
struct listen_list* cps;
|
||||
|
@ -39,9 +39,9 @@
|
||||
* This file contains functions to enable local zone authority service.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/host2wire.h>
|
||||
#include "services/localzone.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/dname.h"
|
||||
@ -125,19 +125,10 @@ local_data_cmp(const void* d1, const void* d2)
|
||||
int
|
||||
parse_dname(const char* str, uint8_t** res, size_t* len, int* labs)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
*res = NULL;
|
||||
*len = 0;
|
||||
*res = ldns_str2wire_dname(str, len);
|
||||
*labs = 0;
|
||||
rdf = ldns_dname_new_frm_str(str);
|
||||
if(!rdf) {
|
||||
log_err("cannot parse name %s", str);
|
||||
return 0;
|
||||
}
|
||||
*res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!*res) {
|
||||
log_err("out of memory");
|
||||
log_err("cannot parse name %s", str);
|
||||
return 0;
|
||||
}
|
||||
*labs = dname_count_size_labels(*res, len);
|
||||
@ -225,39 +216,28 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
||||
/** return name and class and rdata of rr; parses string */
|
||||
static int
|
||||
get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
|
||||
uint16_t* dclass, time_t* ttl, ldns_buffer* rdata)
|
||||
uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len,
|
||||
uint8_t** rdata, size_t* rdata_len)
|
||||
{
|
||||
ldns_rr* rr = NULL;
|
||||
ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("error parsing local-data '%s': %s",
|
||||
str, ldns_get_errorstr_by_id(status));
|
||||
ldns_rr_free(rr);
|
||||
size_t dname_len = 0;
|
||||
int e = ldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
|
||||
NULL, 0, NULL, 0);
|
||||
if(e) {
|
||||
log_err("error parsing local-data at %d: '%s': %s",
|
||||
LDNS_WIREPARSE_OFFSET(e), str,
|
||||
ldns_get_errorstr_parse(e));
|
||||
return 0;
|
||||
}
|
||||
*nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)),
|
||||
ldns_rdf_size(ldns_rr_owner(rr)));
|
||||
*nm = memdup(rr, dname_len);
|
||||
if(!*nm) {
|
||||
log_err("out of memory");
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
*dclass = ldns_rr_get_class(rr);
|
||||
*type = ldns_rr_get_type(rr);
|
||||
*ttl = (time_t)ldns_rr_ttl(rr);
|
||||
ldns_buffer_clear(rdata);
|
||||
ldns_buffer_skip(rdata, 2);
|
||||
status = ldns_rr_rdata2buffer_wire(rdata, rr);
|
||||
ldns_rr_free(rr);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("error converting RR '%s' to wireformat: %s",
|
||||
str, ldns_get_errorstr_by_id(status));
|
||||
free(*nm);
|
||||
*nm = NULL;
|
||||
return 0;
|
||||
}
|
||||
ldns_buffer_flip(rdata);
|
||||
ldns_buffer_write_u16_at(rdata, 0, ldns_buffer_limit(rdata) - 2);
|
||||
*dclass = ldns_wirerr_get_class(rr, len, dname_len);
|
||||
*type = ldns_wirerr_get_type(rr, len, dname_len);
|
||||
*ttl = (time_t)ldns_wirerr_get_ttl(rr, len, dname_len);
|
||||
*rdata = ldns_wirerr_get_rdatawl(rr, len, dname_len);
|
||||
*rdata_len = ldns_wirerr_get_rdatalen(rr, len, dname_len)+2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -265,18 +245,18 @@ get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
|
||||
static int
|
||||
get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass)
|
||||
{
|
||||
ldns_rr* rr = NULL;
|
||||
ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("error parsing local-data '%s': %s",
|
||||
str, ldns_get_errorstr_by_id(status));
|
||||
ldns_rr_free(rr);
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t len = sizeof(rr), dname_len = 0;
|
||||
int s = ldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
|
||||
NULL, 0, NULL, 0);
|
||||
if(s != 0) {
|
||||
log_err("error parsing local-data at %d '%s': %s",
|
||||
LDNS_WIREPARSE_OFFSET(s), str,
|
||||
ldns_get_errorstr_parse(s));
|
||||
return 0;
|
||||
}
|
||||
*nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)),
|
||||
ldns_rdf_size(ldns_rr_owner(rr)));
|
||||
*dclass = ldns_rr_get_class(rr);
|
||||
ldns_rr_free(rr);
|
||||
*nm = memdup(rr, dname_len);
|
||||
*dclass = ldns_wirerr_get_class(rr, len, dname_len);
|
||||
if(!*nm) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
@ -304,13 +284,12 @@ local_data_find_type(struct local_data* data, uint16_t type)
|
||||
|
||||
/** check for RR duplicates */
|
||||
static int
|
||||
rr_is_duplicate(struct packed_rrset_data* pd, ldns_buffer* buf)
|
||||
rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<pd->count; i++) {
|
||||
if(ldns_buffer_limit(buf) == pd->rr_len[i] &&
|
||||
memcmp(ldns_buffer_begin(buf), pd->rr_data[i],
|
||||
ldns_buffer_limit(buf)) == 0)
|
||||
if(pd->rr_len[i] == rdata_len &&
|
||||
memcmp(pd->rr_data[i], rdata, rdata_len) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -356,7 +335,7 @@ new_local_rrset(struct regional* region, struct local_data* node,
|
||||
/** insert RR into RRset data structure; Wastes a couple of bytes */
|
||||
static int
|
||||
insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
ldns_buffer* buf, time_t ttl)
|
||||
uint8_t* rdata, size_t rdata_len, time_t ttl)
|
||||
{
|
||||
size_t* oldlen = pd->rr_len;
|
||||
time_t* oldttl = pd->rr_ttl;
|
||||
@ -379,10 +358,9 @@ insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
memcpy(pd->rr_data+1, olddata,
|
||||
sizeof(*pd->rr_data)*(pd->count-1));
|
||||
}
|
||||
pd->rr_len[0] = ldns_buffer_limit(buf);
|
||||
pd->rr_len[0] = rdata_len;
|
||||
pd->rr_ttl[0] = ttl;
|
||||
pd->rr_data[0] = regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len);
|
||||
if(!pd->rr_data[0]) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
@ -440,8 +418,7 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
|
||||
/** enter data RR into auth zone */
|
||||
static int
|
||||
lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
|
||||
const char* rrstr)
|
||||
lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
|
||||
{
|
||||
uint8_t* nm;
|
||||
size_t nmlen;
|
||||
@ -451,7 +428,11 @@ lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
|
||||
struct packed_rrset_data* pd;
|
||||
uint16_t rrtype = 0, rrclass = 0;
|
||||
time_t ttl = 0;
|
||||
if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, buf)) {
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
uint8_t* rdata;
|
||||
size_t rdata_len;
|
||||
if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr),
|
||||
&rdata, &rdata_len)) {
|
||||
log_err("bad local-data: %s", rrstr);
|
||||
return 0;
|
||||
}
|
||||
@ -487,16 +468,16 @@ lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
|
||||
log_assert(rrset && pd);
|
||||
|
||||
/* check for duplicate RR */
|
||||
if(rr_is_duplicate(pd, buf)) {
|
||||
if(rr_is_duplicate(pd, rdata, rdata_len)) {
|
||||
verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
|
||||
return 1;
|
||||
}
|
||||
return insert_rr(z->region, pd, buf, ttl);
|
||||
return insert_rr(z->region, pd, rdata, rdata_len, ttl);
|
||||
}
|
||||
|
||||
/** enter a data RR into auth data; a zone for it must exist */
|
||||
static int
|
||||
lz_enter_rr_str(struct local_zones* zones, const char* rr, ldns_buffer* buf)
|
||||
lz_enter_rr_str(struct local_zones* zones, const char* rr)
|
||||
{
|
||||
uint8_t* rr_name;
|
||||
uint16_t rr_class;
|
||||
@ -518,7 +499,7 @@ lz_enter_rr_str(struct local_zones* zones, const char* rr, ldns_buffer* buf)
|
||||
lock_rw_wrlock(&z->lock);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
free(rr_name);
|
||||
r = lz_enter_rr_into_zone(z, buf, rr);
|
||||
r = lz_enter_rr_into_zone(z, rr);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return r;
|
||||
}
|
||||
@ -582,7 +563,7 @@ lz_nodefault(struct config_file* cfg, const char* name)
|
||||
/** enter AS112 default zone */
|
||||
static int
|
||||
add_as112_default(struct local_zones* zones, struct config_file* cfg,
|
||||
ldns_buffer* buf, const char* name)
|
||||
const char* name)
|
||||
{
|
||||
struct local_zone* z;
|
||||
char str[1024]; /* known long enough */
|
||||
@ -592,12 +573,12 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg,
|
||||
return 0;
|
||||
snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. "
|
||||
"nobody.invalid. 1 3600 1200 604800 10800", name);
|
||||
if(!lz_enter_rr_into_zone(z, buf, str)) {
|
||||
if(!lz_enter_rr_into_zone(z, str)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name);
|
||||
if(!lz_enter_rr_into_zone(z, buf, str)) {
|
||||
if(!lz_enter_rr_into_zone(z, str)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
@ -607,8 +588,7 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg,
|
||||
|
||||
/** enter default zones */
|
||||
static int
|
||||
lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
ldns_buffer* buf)
|
||||
lz_enter_defaults(struct local_zones* zones, struct config_file* cfg)
|
||||
{
|
||||
struct local_zone* z;
|
||||
|
||||
@ -619,14 +599,14 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
!lz_nodefault(cfg, "localhost.")) {
|
||||
if(!(z=lz_enter_zone(zones, "localhost.", "static",
|
||||
LDNS_RR_CLASS_IN)) ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"localhost. 10800 IN NS localhost.") ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"localhost. 10800 IN SOA localhost. nobody.invalid. "
|
||||
"1 3600 1200 604800 10800") ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"localhost. 10800 IN A 127.0.0.1") ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"localhost. 10800 IN AAAA ::1")) {
|
||||
log_err("out of memory adding default zone");
|
||||
if(z) { lock_rw_unlock(&z->lock); }
|
||||
@ -639,12 +619,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
!lz_nodefault(cfg, "127.in-addr.arpa.")) {
|
||||
if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static",
|
||||
LDNS_RR_CLASS_IN)) ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"127.in-addr.arpa. 10800 IN NS localhost.") ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"127.in-addr.arpa. 10800 IN SOA localhost. "
|
||||
"nobody.invalid. 1 3600 1200 604800 10800") ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
if(z) { lock_rw_unlock(&z->lock); }
|
||||
@ -657,12 +637,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
!lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) {
|
||||
if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static",
|
||||
LDNS_RR_CLASS_IN)) ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. "
|
||||
"nobody.invalid. 1 3600 1200 604800 10800") ||
|
||||
!lz_enter_rr_into_zone(z, buf,
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
if(z) { lock_rw_unlock(&z->lock); }
|
||||
@ -670,37 +650,37 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
if ( !add_as112_default(zones, cfg, buf, "10.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "16.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "17.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "18.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "19.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "20.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "21.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "22.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "23.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "24.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "25.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "26.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "27.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "28.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "29.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "30.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "31.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "168.192.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "0.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "100.51.198.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "113.0.203.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "d.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "8.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "9.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "a.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "b.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
|
||||
if ( !add_as112_default(zones, cfg, "10.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "16.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "17.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "18.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "19.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "20.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "21.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "22.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "23.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "24.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "25.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "26.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "27.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "28.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "29.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "30.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "31.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "168.192.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "0.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "254.169.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "2.0.192.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "100.51.198.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "113.0.203.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "255.255.255.255.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "d.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "8.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "9.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "a.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "b.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
@ -825,12 +805,11 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
||||
|
||||
/** enter auth data */
|
||||
static int
|
||||
lz_enter_data(struct local_zones* zones, struct config_file* cfg,
|
||||
ldns_buffer* buf)
|
||||
lz_enter_data(struct local_zones* zones, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
for(p = cfg->local_data; p; p = p->next) {
|
||||
if(!lz_enter_rr_str(zones, p->str, buf))
|
||||
if(!lz_enter_rr_str(zones, p->str))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -851,35 +830,27 @@ lz_freeup_cfg(struct config_file* cfg)
|
||||
int
|
||||
local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
|
||||
{
|
||||
ldns_buffer* buf = ldns_buffer_new(65535);
|
||||
if(!buf) fatal_exit("cannot create temporary buffer");
|
||||
|
||||
/* create zones from zone statements. */
|
||||
if(!lz_enter_zones(zones, cfg)) {
|
||||
ldns_buffer_free(buf);
|
||||
return 0;
|
||||
}
|
||||
/* apply default zones+content (unless disabled, or overridden) */
|
||||
if(!lz_enter_defaults(zones, cfg, buf)) {
|
||||
ldns_buffer_free(buf);
|
||||
if(!lz_enter_defaults(zones, cfg)) {
|
||||
return 0;
|
||||
}
|
||||
/* create implicit transparent zone from data. */
|
||||
if(!lz_setup_implicit(zones, cfg)) {
|
||||
ldns_buffer_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setup parent ptrs for lookup during data entry */
|
||||
init_parents(zones);
|
||||
/* insert local data */
|
||||
if(!lz_enter_data(zones, cfg, buf)) {
|
||||
ldns_buffer_free(buf);
|
||||
if(!lz_enter_data(zones, cfg)) {
|
||||
return 0;
|
||||
}
|
||||
/* freeup memory from cfg struct. */
|
||||
lz_freeup_cfg(cfg);
|
||||
ldns_buffer_free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1255,7 +1226,7 @@ void local_zones_del_zone(struct local_zones* zones, struct local_zone* z)
|
||||
}
|
||||
|
||||
int
|
||||
local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
|
||||
local_zones_add_RR(struct local_zones* zones, const char* rr)
|
||||
{
|
||||
uint8_t* rr_name;
|
||||
uint16_t rr_class;
|
||||
@ -1281,7 +1252,7 @@ local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
r = lz_enter_rr_into_zone(z, buf, rr);
|
||||
r = lz_enter_rr_into_zone(z, rr);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return r;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ struct regional;
|
||||
struct config_file;
|
||||
struct edns_data;
|
||||
struct query_info;
|
||||
struct ldns_buffer;
|
||||
|
||||
/**
|
||||
* Local zone type
|
||||
@ -224,7 +225,7 @@ void local_zones_print(struct local_zones* zones);
|
||||
* value is true, but the buffer is cleared (empty).
|
||||
*/
|
||||
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
||||
struct edns_data* edns, ldns_buffer* buf, struct regional* temp);
|
||||
struct edns_data* edns, struct ldns_buffer* buf, struct regional* temp);
|
||||
|
||||
/**
|
||||
* Parse the string into localzone type.
|
||||
@ -286,11 +287,9 @@ void local_zones_del_zone(struct local_zones* zones, struct local_zone* zone);
|
||||
* name of the RR is created.
|
||||
* @param zones: the zones tree. Not locked by caller.
|
||||
* @param rr: string with on RR.
|
||||
* @param buf: buffer for scratch.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int local_zones_add_RR(struct local_zones* zones, const char* rr,
|
||||
ldns_buffer* buf);
|
||||
int local_zones_add_RR(struct local_zones* zones, const char* rr);
|
||||
|
||||
/**
|
||||
* Remove data from domain name in the tree.
|
||||
|
@ -43,7 +43,6 @@
|
||||
* send back to clients.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "services/mesh.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/cache/dns.h"
|
||||
@ -56,6 +55,7 @@
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
static void
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/module.h"
|
||||
#include "services/modstack.h"
|
||||
struct ldns_buffer;
|
||||
struct mesh_state;
|
||||
struct mesh_reply;
|
||||
struct mesh_cb;
|
||||
@ -125,7 +126,7 @@ struct mesh_area {
|
||||
|
||||
/** backup of query if other operations recurse and need the
|
||||
* network buffers */
|
||||
ldns_buffer* qbuf_bak;
|
||||
struct ldns_buffer* qbuf_bak;
|
||||
|
||||
/** double linked list of the run-to-completion query states.
|
||||
* These are query states with a reply */
|
||||
@ -219,7 +220,7 @@ struct mesh_reply {
|
||||
* Mesh result callback func.
|
||||
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
|
||||
*/
|
||||
typedef void (*mesh_cb_func_t)(void*, int, ldns_buffer*, enum sec_status,
|
||||
typedef void (*mesh_cb_func_t)(void*, int, struct ldns_buffer*, enum sec_status,
|
||||
char*);
|
||||
|
||||
/**
|
||||
@ -235,7 +236,7 @@ struct mesh_cb {
|
||||
/** flags of query, for reply flags */
|
||||
uint16_t qflags;
|
||||
/** buffer for reply */
|
||||
ldns_buffer* buf;
|
||||
struct ldns_buffer* buf;
|
||||
|
||||
/** callback routine for results. if rcode != 0 buf has message.
|
||||
* called as cb(cb_arg, rcode, buf, sec_state);
|
||||
@ -294,7 +295,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, ldns_buffer* buf,
|
||||
uint16_t qflags, struct edns_data* edns, struct ldns_buffer* buf,
|
||||
uint16_t qid, mesh_cb_func_t cb, void* cb_arg);
|
||||
|
||||
/**
|
||||
@ -473,7 +474,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
* @return: 0 on alloc error.
|
||||
*/
|
||||
int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns,
|
||||
ldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid,
|
||||
struct ldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid,
|
||||
uint16_t qflags);
|
||||
|
||||
/**
|
||||
@ -548,7 +549,7 @@ int mesh_state_ref_compare(const void* ap, const void* bp);
|
||||
* You can pass NULL if there is no buffer that must be backed up.
|
||||
* @return false if no space is available.
|
||||
*/
|
||||
int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf);
|
||||
int mesh_make_new_space(struct mesh_area* mesh, struct ldns_buffer* qbuf);
|
||||
|
||||
/**
|
||||
* Insert mesh state into a double linked list. Inserted at end.
|
||||
|
@ -45,7 +45,6 @@
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <ldns/wire2host.h>
|
||||
#include "services/outside_network.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/infra.h"
|
||||
@ -58,6 +57,7 @@
|
||||
#include "util/net_help.h"
|
||||
#include "util/random.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
@ -54,6 +54,7 @@ struct waiting_udp;
|
||||
struct infra_cache;
|
||||
struct port_comm;
|
||||
struct port_if;
|
||||
struct ldns_buffer;
|
||||
|
||||
/**
|
||||
* Send queries to outside servers and wait for answers from servers.
|
||||
@ -69,7 +70,7 @@ struct outside_network {
|
||||
|
||||
/** buffer shared by UDP connections, since there is only one
|
||||
datagram at any time. */
|
||||
ldns_buffer* udp_buff;
|
||||
struct ldns_buffer* udp_buff;
|
||||
/** serviced_callbacks malloc overhead when processing multiple
|
||||
* identical serviced queries to the same server. */
|
||||
size_t svcd_overhead;
|
||||
@ -411,7 +412,7 @@ void outside_network_quit_prepare(struct outside_network* outnet);
|
||||
* @return: NULL on error for malloc or socket. Else the pending query object.
|
||||
*/
|
||||
struct pending* pending_udp_query(struct outside_network* outnet,
|
||||
ldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
struct ldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg);
|
||||
|
||||
@ -431,7 +432,7 @@ struct pending* pending_udp_query(struct outside_network* outnet,
|
||||
* @return: false on error for malloc or socket. Else the pending TCP object.
|
||||
*/
|
||||
struct waiting_tcp* pending_tcp_query(struct outside_network* outnet,
|
||||
ldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
struct ldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg, int ssl_upstream);
|
||||
|
||||
@ -476,7 +477,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
|
||||
int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, comm_point_callback_t* callback,
|
||||
void* callback_arg, ldns_buffer* buff);
|
||||
void* callback_arg, struct ldns_buffer* buff);
|
||||
|
||||
/**
|
||||
* Remove service query callback.
|
||||
|
@ -116,7 +116,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "libunbound/unbound.h"
|
||||
#include <ldns/rr.h>
|
||||
#include "ldns/rrdef.h"
|
||||
#include <expat.h>
|
||||
#ifndef HAVE_EXPAT_H
|
||||
#error "need libexpat to parse root-anchors.xml file."
|
||||
@ -669,6 +669,15 @@ count_unused(struct ip_list* p)
|
||||
return num;
|
||||
}
|
||||
|
||||
static int get_random(void)
|
||||
{
|
||||
int r;
|
||||
if (RAND_bytes((unsigned char*)&r, (int)sizeof(r)) == 1) {
|
||||
return r;
|
||||
}
|
||||
return (int)random();
|
||||
}
|
||||
|
||||
/** pick random unused element from IP list */
|
||||
static struct ip_list*
|
||||
pick_random_ip(struct ip_list* list)
|
||||
@ -678,7 +687,7 @@ pick_random_ip(struct ip_list* list)
|
||||
int sel;
|
||||
if(num == 0) return NULL;
|
||||
/* not perfect, but random enough */
|
||||
sel = (int)ldns_get_random() % num;
|
||||
sel = get_random() % num;
|
||||
/* skip over unused elements that we did not select */
|
||||
while(sel > 0 && p) {
|
||||
if(!p->used) sel--;
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "validator/validator.h"
|
||||
#include "services/localzone.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
@ -343,9 +344,9 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
if(fname[0] != '/') {
|
||||
if(getcwd(buf, sizeof(buf)) == NULL)
|
||||
fatal_exit("getcwd: %s", strerror(errno));
|
||||
strncat(buf, "/", sizeof(buf)-strlen(buf)-1);
|
||||
strlcat(buf, "/", sizeof(buf));
|
||||
}
|
||||
strncat(buf, fname, sizeof(buf)-strlen(buf)-1);
|
||||
strlcat(buf, fname, sizeof(buf));
|
||||
if(strncmp(buf, cfg->chrootdir, strlen(cfg->chrootdir)) != 0)
|
||||
fatal_exit("config file %s is not inside chroot %s",
|
||||
buf, cfg->chrootdir);
|
||||
|
@ -60,7 +60,8 @@
|
||||
#define unbound_lite_wrapstr(s) s
|
||||
#endif
|
||||
#include "libunbound/unbound.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/wire2str.h"
|
||||
#ifdef HAVE_NSS
|
||||
/* nss3 */
|
||||
#include "nss.h"
|
||||
@ -215,61 +216,36 @@ secure_str(struct ub_result* result)
|
||||
static void
|
||||
pretty_type(char* s, size_t len, int t)
|
||||
{
|
||||
char* d = ldns_rr_type2str(t);
|
||||
char d[16];
|
||||
ldns_wire2str_type_buf((uint16_t)t, d, sizeof(d));
|
||||
snprintf(s, len, "%s", d);
|
||||
free(d);
|
||||
}
|
||||
|
||||
/** nice string for class */
|
||||
static void
|
||||
pretty_class(char* s, size_t len, int c)
|
||||
{
|
||||
char* d = ldns_rr_class2str(c);
|
||||
char d[16];
|
||||
ldns_wire2str_class_buf((uint16_t)c, d, sizeof(d));
|
||||
snprintf(s, len, "%s", d);
|
||||
free(d);
|
||||
}
|
||||
|
||||
/** nice string for rcode */
|
||||
static void
|
||||
pretty_rcode(char* s, size_t len, int r)
|
||||
{
|
||||
ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes, r);
|
||||
if(rcode) {
|
||||
snprintf(s, len, "%s", rcode->name);
|
||||
} else {
|
||||
snprintf(s, len, "RCODE%d", r);
|
||||
}
|
||||
char d[16];
|
||||
ldns_wire2str_rcode_buf(r, d, sizeof(d));
|
||||
snprintf(s, len, "%s", d);
|
||||
}
|
||||
|
||||
/** convert and print rdata */
|
||||
static void
|
||||
print_rd(int t, char* data, size_t len)
|
||||
{
|
||||
size_t i, pos = 0;
|
||||
uint8_t* rd = (uint8_t*)malloc(len+2);
|
||||
ldns_rr* rr = ldns_rr_new();
|
||||
ldns_status status;
|
||||
if(!rd || !rr) {
|
||||
fprintf(stderr, "out of memory");
|
||||
exit(1);
|
||||
}
|
||||
ldns_rr_set_type(rr, t);
|
||||
ldns_write_uint16(rd, len);
|
||||
memmove(rd+2, data, len);
|
||||
ldns_rr_set_owner(rr, NULL);
|
||||
status = ldns_wire2rdf(rr, rd, len+2, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
free(rd);
|
||||
ldns_rr_free(rr);
|
||||
printf("error_printing_data");
|
||||
return;
|
||||
}
|
||||
for(i=0; i<ldns_rr_rd_count(rr); i++) {
|
||||
printf(" ");
|
||||
ldns_rdf_print(stdout, ldns_rr_rdf(rr, i));
|
||||
}
|
||||
ldns_rr_free(rr);
|
||||
free(rd);
|
||||
char s[65535];
|
||||
ldns_wire2str_rdata_buf((uint8_t*)data, len, s, sizeof(s), (uint16_t)t);
|
||||
printf(" %s", s);
|
||||
}
|
||||
|
||||
/** pretty line of RR data for results */
|
||||
@ -344,24 +320,14 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname)
|
||||
else if(t == LDNS_RR_TYPE_MX)
|
||||
printf(" has no mail handler record");
|
||||
else if(t == LDNS_RR_TYPE_ANY) {
|
||||
ldns_pkt* p = NULL;
|
||||
if(ldns_wire2pkt(&p, result->answer_packet,
|
||||
(size_t)result->answer_len)==LDNS_STATUS_OK){
|
||||
if(ldns_rr_list_rr_count(
|
||||
ldns_pkt_answer(p)) == 0)
|
||||
printf(" has no records\n");
|
||||
else {
|
||||
printf(" ANY:\n");
|
||||
ldns_rr_list_print(stdout,
|
||||
ldns_pkt_answer(p));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "could not parse "
|
||||
"reply packet to ANY query\n");
|
||||
char* s = ldns_wire2str_pkt(
|
||||
result->answer_packet,
|
||||
(size_t)result->answer_len);
|
||||
if(!s) {
|
||||
fprintf(stderr, "alloc failure\n");
|
||||
exit(1);
|
||||
}
|
||||
ldns_pkt_free(p);
|
||||
|
||||
printf("%s\n", s);
|
||||
} else printf(" has no %s record", tstr);
|
||||
printf(" %s\n", secstatus);
|
||||
}
|
||||
|
@ -166,21 +166,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
||||
}
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
struct ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
struct ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
struct ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "libunbound/context.h"
|
||||
#include "util/locks.h"
|
||||
#include "util/log.h"
|
||||
#include "ldns/rrdef.h"
|
||||
#ifdef UNBOUND_ALLOC_LITE
|
||||
#undef malloc
|
||||
#undef calloc
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <sys/time.h>
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include <signal.h>
|
||||
|
||||
/** number of reads per select for delayer */
|
||||
@ -889,12 +890,12 @@ proxy_list_clear(struct proxy* p)
|
||||
if(inet_ntop(AF_INET6,
|
||||
&((struct sockaddr_in6*)&p->addr)->sin6_addr,
|
||||
from, (socklen_t)sizeof(from)) == 0)
|
||||
strncpy(from, "err", sizeof(from));
|
||||
strlcpy(from, "err", sizeof(from));
|
||||
} else {
|
||||
if(inet_ntop(AF_INET,
|
||||
&((struct sockaddr_in*)&p->addr)->sin_addr,
|
||||
from, (socklen_t)sizeof(from)) == 0)
|
||||
strncpy(from, "err", sizeof(from));
|
||||
strlcpy(from, "err", sizeof(from));
|
||||
}
|
||||
printf("client[%d]: last %s@%d of %d : %u in, %u out, "
|
||||
"%u returned\n", i++, from, port, (int)p->numreuse+1,
|
||||
|
@ -57,9 +57,12 @@
|
||||
#include "services/outside_network.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "testcode/replay.h"
|
||||
#include "testcode/ldns-testpkts.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "util/log.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/wire2str.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include <signal.h>
|
||||
struct worker;
|
||||
struct daemon_remote;
|
||||
@ -108,11 +111,11 @@ fake_event_cleanup(void)
|
||||
|
||||
/** helper function that logs a ldns_pkt packet to logfile */
|
||||
static void
|
||||
log_pkt(const char* desc, ldns_pkt* pkt)
|
||||
log_pkt(const char* desc, uint8_t* pkt, size_t len)
|
||||
{
|
||||
char* str = ldns_pkt2str(pkt);
|
||||
char* str = ldns_wire2str_pkt(pkt, len);
|
||||
if(!str)
|
||||
log_info("%s: (failed)", desc);
|
||||
fatal_exit("%s: (failed out of memory wire2str_pkt)", desc);
|
||||
else {
|
||||
log_info("%s%s", desc, str);
|
||||
free(str);
|
||||
@ -150,7 +153,7 @@ delete_fake_pending(struct fake_pending* pend)
|
||||
return;
|
||||
free(pend->zone);
|
||||
ldns_buffer_free(pend->buffer);
|
||||
ldns_pkt_free(pend->pkt);
|
||||
free(pend->pkt);
|
||||
free(pend);
|
||||
}
|
||||
|
||||
@ -164,7 +167,7 @@ delete_replay_answer(struct replay_answer* a)
|
||||
ldns_buffer_free(a->repinfo.c->buffer);
|
||||
free(a->repinfo.c);
|
||||
}
|
||||
ldns_pkt_free(a->pkt);
|
||||
free(a->pkt);
|
||||
free(a);
|
||||
}
|
||||
|
||||
@ -186,7 +189,8 @@ pending_matches_current(struct replay_runtime* runtime,
|
||||
sockaddr_cmp(&p->addr, p->addrlen, &runtime->now->addr,
|
||||
runtime->now->addrlen) != 0)
|
||||
continue;
|
||||
if((e=find_match(runtime->now->match, p->pkt, p->transport))) {
|
||||
if((e=find_match(runtime->now->match, p->pkt, p->pkt_len,
|
||||
p->transport))) {
|
||||
*entry = e;
|
||||
*pend = p;
|
||||
return 1;
|
||||
@ -212,13 +216,16 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
|
||||
if(p->start_step <= timenow && timenow <= p->end_step &&
|
||||
(p->addrlen == 0 || sockaddr_cmp(&p->addr, p->addrlen,
|
||||
&pend->addr, pend->addrlen) == 0) &&
|
||||
(*entry = find_match(p->match, pend->pkt, pend->transport))) {
|
||||
(*entry = find_match(p->match, pend->pkt, pend->pkt_len,
|
||||
pend->transport))) {
|
||||
log_info("matched query time %d in range [%d, %d] "
|
||||
"with entry line %d", timenow,
|
||||
p->start_step, p->end_step, (*entry)->lineno);
|
||||
if(p->addrlen != 0)
|
||||
log_addr(0, "matched ip", &p->addr, p->addrlen);
|
||||
log_pkt("matched pkt: ", (*entry)->reply_list->reply);
|
||||
log_pkt("matched pkt: ",
|
||||
(*entry)->reply_list->reply_pkt,
|
||||
(*entry)->reply_list->reply_len);
|
||||
return 1;
|
||||
}
|
||||
p = p->next_range;
|
||||
@ -275,31 +282,26 @@ pending_list_delete(struct replay_runtime* runtime, struct fake_pending* pend)
|
||||
* Fill buffer with reply from the entry.
|
||||
*/
|
||||
static void
|
||||
fill_buffer_with_reply(ldns_buffer* buffer, struct entry* entry, ldns_pkt* q)
|
||||
fill_buffer_with_reply(ldns_buffer* buffer, struct entry* entry, uint8_t* q,
|
||||
size_t qlen)
|
||||
{
|
||||
ldns_status status;
|
||||
ldns_pkt* answer_pkt = NULL;
|
||||
uint8_t* c;
|
||||
size_t clen;
|
||||
log_assert(entry && entry->reply_list);
|
||||
ldns_buffer_clear(buffer);
|
||||
if(entry->reply_list->reply_from_hex) {
|
||||
status = ldns_buffer2pkt_wire(&answer_pkt,
|
||||
entry->reply_list->reply_from_hex);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("testbound: hex packet unparsable, used asis.");
|
||||
ldns_buffer_write(buffer,
|
||||
ldns_buffer_begin(entry->reply_list->reply_from_hex),
|
||||
ldns_buffer_limit(entry->reply_list->reply_from_hex));
|
||||
}
|
||||
c = ldns_buffer_begin(entry->reply_list->reply_from_hex);
|
||||
clen = ldns_buffer_limit(entry->reply_list->reply_from_hex);
|
||||
if(!c) fatal_exit("out of memory");
|
||||
} else {
|
||||
answer_pkt = ldns_pkt_clone(entry->reply_list->reply);
|
||||
c = entry->reply_list->reply_pkt;
|
||||
clen = entry->reply_list->reply_len;
|
||||
}
|
||||
if(answer_pkt) {
|
||||
if(q) adjust_packet(entry, answer_pkt, q);
|
||||
status = ldns_pkt2buffer_wire(buffer, answer_pkt);
|
||||
if(status != LDNS_STATUS_OK)
|
||||
fatal_exit("ldns: cannot pkt2buffer_wire parsed pkt");
|
||||
if(c) {
|
||||
if(q) adjust_packet(entry, &c, &clen, q, qlen);
|
||||
ldns_buffer_write(buffer, c, clen);
|
||||
if(q) free(c);
|
||||
}
|
||||
ldns_pkt_free(answer_pkt);
|
||||
ldns_buffer_flip(buffer);
|
||||
}
|
||||
|
||||
@ -324,7 +326,7 @@ answer_callback_from_entry(struct replay_runtime* runtime,
|
||||
c.type = comm_udp;
|
||||
if(pend->transport == transport_tcp)
|
||||
c.type = comm_tcp;
|
||||
fill_buffer_with_reply(c.buffer, entry, pend->pkt);
|
||||
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len);
|
||||
repinfo.c = &c;
|
||||
repinfo.addrlen = pend->addrlen;
|
||||
memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
|
||||
@ -351,7 +353,8 @@ answer_check_it(struct replay_runtime* runtime)
|
||||
if((runtime->now->addrlen == 0 || sockaddr_cmp(
|
||||
&runtime->now->addr, runtime->now->addrlen,
|
||||
&ans->repinfo.addr, ans->repinfo.addrlen) == 0) &&
|
||||
find_match(runtime->now->match, ans->pkt, tr)) {
|
||||
find_match(runtime->now->match, ans->pkt,
|
||||
ans->pkt_len, tr)) {
|
||||
log_info("testbound matched event entry from line %d",
|
||||
runtime->now->match->lineno);
|
||||
log_info("testbound: do STEP %d %s",
|
||||
@ -394,9 +397,10 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
|
||||
if(todo->match->match_transport == transport_tcp)
|
||||
repinfo.c->type = comm_tcp;
|
||||
else repinfo.c->type = comm_udp;
|
||||
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL);
|
||||
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0);
|
||||
log_info("testbound: incoming QUERY");
|
||||
log_pkt("query pkt", todo->match->reply_list->reply);
|
||||
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
|
||||
todo->match->reply_list->reply_len);
|
||||
/* call the callback for incoming queries */
|
||||
if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
|
||||
NETEVENT_NOERROR, &repinfo)) {
|
||||
@ -424,13 +428,13 @@ fake_pending_callback(struct replay_runtime* runtime,
|
||||
if(!p) fatal_exit("No pending queries.");
|
||||
cb_arg = p->cb_arg;
|
||||
cb = p->callback;
|
||||
log_assert(todo->qname == NULL); /* or find that one */
|
||||
c.buffer = ldns_buffer_new(runtime->bufsize);
|
||||
c.type = comm_udp;
|
||||
if(p->transport == transport_tcp)
|
||||
c.type = comm_tcp;
|
||||
if(todo->evt_type == repevt_back_reply && todo->match) {
|
||||
fill_buffer_with_reply(c.buffer, todo->match, p->pkt);
|
||||
fill_buffer_with_reply(c.buffer, todo->match, p->pkt,
|
||||
p->pkt_len);
|
||||
}
|
||||
repinfo.c = &c;
|
||||
repinfo.addrlen = p->addrlen;
|
||||
@ -552,16 +556,17 @@ do_infra_rtt(struct replay_runtime* runtime)
|
||||
{
|
||||
struct replay_moment* now = runtime->now;
|
||||
int rto;
|
||||
ldns_rdf* dp = ldns_dname_new_frm_str(now->variable);
|
||||
size_t dplen = 0;
|
||||
uint8_t* dp = ldns_str2wire_dname(now->variable, &dplen);
|
||||
if(!dp) fatal_exit("cannot parse %s", now->variable);
|
||||
rto = infra_rtt_update(runtime->infra, &now->addr,
|
||||
now->addrlen, ldns_rdf_data(dp), ldns_rdf_size(dp),
|
||||
LDNS_RR_TYPE_A, atoi(now->string), -1, runtime->now_secs);
|
||||
rto = infra_rtt_update(runtime->infra, &now->addr, now->addrlen,
|
||||
dp, dplen, LDNS_RR_TYPE_A, atoi(now->string),
|
||||
-1, runtime->now_secs);
|
||||
log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen);
|
||||
log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable,
|
||||
atoi(now->string), rto);
|
||||
if(rto == 0) fatal_exit("infra_rtt_update failed");
|
||||
ldns_rdf_deep_free(dp);
|
||||
free(dp);
|
||||
}
|
||||
|
||||
/** perform exponential backoff on the timout */
|
||||
@ -712,7 +717,7 @@ run_scenario(struct replay_runtime* runtime)
|
||||
struct fake_pending* p;
|
||||
log_err("testbound: there are still messages pending.");
|
||||
for(p = runtime->pending_list; p; p=p->next) {
|
||||
log_pkt("pending msg", p->pkt);
|
||||
log_pkt("pending msg", p->pkt, p->pkt_len);
|
||||
log_addr(0, "pending to", &p->addr, p->addrlen);
|
||||
}
|
||||
fatal_exit("testbound: there are still messages pending.");
|
||||
@ -856,7 +861,6 @@ comm_point_send_reply(struct comm_reply* repinfo)
|
||||
{
|
||||
struct replay_answer* ans = (struct replay_answer*)calloc(1,
|
||||
sizeof(struct replay_answer));
|
||||
ldns_status status;
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)repinfo->c->ev;
|
||||
log_info("testbound: comm_point_send_reply fake");
|
||||
/* dump it into the todo list */
|
||||
@ -869,13 +873,11 @@ comm_point_send_reply(struct comm_reply* repinfo)
|
||||
runtime->answer_last = ans;
|
||||
|
||||
/* try to parse packet */
|
||||
status = ldns_buffer2pkt_wire(&ans->pkt, ans->repinfo.c->buffer);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("ldns error parsing packet: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
fatal_exit("Sending unparseable DNS replies to clients!");
|
||||
}
|
||||
log_pkt("reply pkt: ", ans->pkt);
|
||||
ans->pkt = memdup(ldns_buffer_begin(ans->repinfo.c->buffer),
|
||||
ldns_buffer_limit(ans->repinfo.c->buffer));
|
||||
ans->pkt_len = ldns_buffer_limit(ans->repinfo.c->buffer);
|
||||
if(!ans->pkt) fatal_exit("out of memory");
|
||||
log_pkt("reply pkt: ", ans->pkt, ans->pkt_len);
|
||||
}
|
||||
|
||||
void
|
||||
@ -938,7 +940,6 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
ldns_status status;
|
||||
log_assert(pend);
|
||||
pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet));
|
||||
log_assert(pend->buffer);
|
||||
@ -955,20 +956,18 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
pend->zone = NULL;
|
||||
pend->serviced = 0;
|
||||
pend->runtime = runtime;
|
||||
status = ldns_buffer2pkt_wire(&pend->pkt, packet);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("ldns error parsing udp output packet: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
fatal_exit("Sending unparseable DNS packets to servers!");
|
||||
}
|
||||
log_pkt("pending udp pkt: ", pend->pkt);
|
||||
pend->pkt_len = ldns_buffer_limit(packet);
|
||||
pend->pkt = memdup(ldns_buffer_begin(packet), pend->pkt_len);
|
||||
if(!pend->pkt) fatal_exit("out of memory");
|
||||
log_pkt("pending udp pkt: ", pend->pkt, pend->pkt_len);
|
||||
|
||||
/* see if it matches the current moment */
|
||||
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
|
||||
(runtime->now->addrlen == 0 || sockaddr_cmp(
|
||||
&runtime->now->addr, runtime->now->addrlen,
|
||||
&pend->addr, pend->addrlen) == 0) &&
|
||||
find_match(runtime->now->match, pend->pkt, pend->transport)) {
|
||||
find_match(runtime->now->match, pend->pkt, pend->pkt_len,
|
||||
pend->transport)) {
|
||||
log_info("testbound: matched pending to event. "
|
||||
"advance time between events.");
|
||||
log_info("testbound: do STEP %d %s", runtime->now->time_step,
|
||||
@ -992,7 +991,6 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
ldns_status status;
|
||||
log_assert(pend);
|
||||
pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet));
|
||||
log_assert(pend->buffer);
|
||||
@ -1009,20 +1007,18 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
pend->zone = NULL;
|
||||
pend->runtime = runtime;
|
||||
pend->serviced = 0;
|
||||
status = ldns_buffer2pkt_wire(&pend->pkt, packet);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("ldns error parsing tcp output packet: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
fatal_exit("Sending unparseable DNS packets to servers!");
|
||||
}
|
||||
log_pkt("pending tcp pkt: ", pend->pkt);
|
||||
pend->pkt_len = ldns_buffer_limit(packet);
|
||||
pend->pkt = memdup(ldns_buffer_begin(packet), pend->pkt_len);
|
||||
if(!pend->pkt) fatal_exit("out of memory");
|
||||
log_pkt("pending tcp pkt: ", pend->pkt, pend->pkt_len);
|
||||
|
||||
/* see if it matches the current moment */
|
||||
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
|
||||
(runtime->now->addrlen == 0 || sockaddr_cmp(
|
||||
&runtime->now->addr, runtime->now->addrlen,
|
||||
&pend->addr, pend->addrlen) == 0) &&
|
||||
find_match(runtime->now->match, pend->pkt, pend->transport)) {
|
||||
find_match(runtime->now->match, pend->pkt, pend->pkt_len,
|
||||
pend->transport)) {
|
||||
log_info("testbound: matched pending to event. "
|
||||
"advance time between events.");
|
||||
log_info("testbound: do STEP %d %s", runtime->now->time_step,
|
||||
@ -1049,7 +1045,6 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
char z[256];
|
||||
ldns_status status;
|
||||
log_assert(pend);
|
||||
log_nametypeclass(VERB_OPS, "pending serviced query",
|
||||
qname, qtype, qclass);
|
||||
@ -1096,20 +1091,18 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
pend->pkt = NULL;
|
||||
pend->runtime = runtime;
|
||||
pend->serviced = 1;
|
||||
status = ldns_buffer2pkt_wire(&pend->pkt, pend->buffer);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("ldns error parsing serviced output packet: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
fatal_exit("internal error");
|
||||
}
|
||||
/*log_pkt("pending serviced query: ", pend->pkt);*/
|
||||
pend->pkt_len = ldns_buffer_limit(pend->buffer);
|
||||
pend->pkt = memdup(ldns_buffer_begin(pend->buffer), pend->pkt_len);
|
||||
if(!pend->pkt) fatal_exit("out of memory");
|
||||
/*log_pkt("pending serviced query: ", pend->pkt, pend->pkt_len);*/
|
||||
|
||||
/* see if it matches the current moment */
|
||||
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
|
||||
(runtime->now->addrlen == 0 || sockaddr_cmp(
|
||||
&runtime->now->addr, runtime->now->addrlen,
|
||||
&pend->addr, pend->addrlen) == 0) &&
|
||||
find_match(runtime->now->match, pend->pkt, pend->transport)) {
|
||||
find_match(runtime->now->match, pend->pkt, pend->pkt_len,
|
||||
pend->transport)) {
|
||||
log_info("testbound: matched pending to event. "
|
||||
"advance time between events.");
|
||||
log_info("testbound: do STEP %d %s", runtime->now->time_step,
|
||||
@ -1138,7 +1131,7 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
|
||||
prev->next = p->next;
|
||||
else runtime->pending_list = p->next;
|
||||
ldns_buffer_free(p->buffer);
|
||||
ldns_pkt_free(p->pkt);
|
||||
free(p->pkt);
|
||||
free(p->zone);
|
||||
free(p);
|
||||
return;
|
||||
|
@ -1,857 +0,0 @@
|
||||
/*
|
||||
* testcode/harvest.c - debug program to get relevant data to a set of queries.
|
||||
*
|
||||
* Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This program downloads relevant DNS data to a set of queries.
|
||||
* This means that the queries are asked to root, TLD, SLD servers and
|
||||
* the results stored per zone.
|
||||
* The following data is pertinent:
|
||||
*
|
||||
* At each label:
|
||||
* SOA
|
||||
* NS
|
||||
* DNSKEY
|
||||
* DS
|
||||
* For the whole query:
|
||||
* the result.
|
||||
* For NS-records:
|
||||
* their label data
|
||||
* and the A and AAAA records for it.
|
||||
* (as if the name, with A and AAAA query type is in the list,
|
||||
* referred to as recursion depth+1)
|
||||
* Any NSEC, NSEC3, SOA records or additional data found in answers.
|
||||
*
|
||||
* All of this is data that would be encountered during an iterative lookup
|
||||
* for the queries in the list. It is saved to enable a replay of iterative
|
||||
* lookups for performance testing.
|
||||
*
|
||||
* A number of assumptions are made.
|
||||
* 1) configuration is correct.
|
||||
* The parent has the same NS records as the child.
|
||||
* All nameservers carry the same data.
|
||||
* 2) EDNS/nonEDNS responses and other behaviour is ignored.
|
||||
* Only the data is saved.
|
||||
* This creates a snapshot that represents the data as this resolver saw it.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <ldns/ldns.h>
|
||||
#include <signal.h>
|
||||
#include "libunbound/unbound.h"
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef UNBOUND_ALLOC_LITE
|
||||
#undef malloc
|
||||
#undef calloc
|
||||
#undef realloc
|
||||
#undef free
|
||||
#undef strdup
|
||||
#define unbound_lite_wrapstr(s) s
|
||||
#endif
|
||||
struct todo_item;
|
||||
struct labdata;
|
||||
|
||||
/** this represents the data that has been collected
|
||||
* as well as a todo list and some settings */
|
||||
struct harvest_data {
|
||||
/** the unbound context */
|
||||
struct ub_ctx* ctx;
|
||||
|
||||
/** a tree per label; thus this first one is one root entry,
|
||||
* that has a tree of TLD labels. Those have trees of SLD labels. */
|
||||
struct labdata* root;
|
||||
/** the original query list */
|
||||
struct todo_item* orig_list;
|
||||
/** the query list todo */
|
||||
struct todo_item* todo_list;
|
||||
/** last item in todo list */
|
||||
struct todo_item* todo_last;
|
||||
/** number of todo items */
|
||||
int numtodo;
|
||||
|
||||
/** where to store the results */
|
||||
char* resultdir;
|
||||
/** maximum recursion depth */
|
||||
int maxdepth;
|
||||
/** current recursion depth */
|
||||
int curdepth;
|
||||
|
||||
/** max depth of labels */
|
||||
int maxlabels;
|
||||
/** number of RRs stored */
|
||||
int num_rrs;
|
||||
/** number of zones written */
|
||||
int num_zones;
|
||||
};
|
||||
|
||||
/**
|
||||
* Todo item
|
||||
*/
|
||||
struct todo_item {
|
||||
/** the next item */
|
||||
struct todo_item* next;
|
||||
|
||||
/** query as rdf */
|
||||
ldns_rdf* qname;
|
||||
/** the query type */
|
||||
int qtype;
|
||||
/** query class */
|
||||
int qclass;
|
||||
|
||||
/** recursion depth of todo item (orig list is 0) */
|
||||
int depth;
|
||||
/** the label associated with the query */
|
||||
struct labdata* lab;
|
||||
};
|
||||
|
||||
/**
|
||||
* Every label has a sest of sublabels, that have sets of sublabels ...
|
||||
* Per label is stored also a set of data items, and todo information
|
||||
*/
|
||||
struct labdata {
|
||||
/** node in ldns rbtree */
|
||||
ldns_rbnode_t node;
|
||||
/** the name of this label */
|
||||
ldns_rdf* label;
|
||||
/** full name of point in domain tree */
|
||||
ldns_rdf* name;
|
||||
|
||||
/** parent in label tree (NULL for root) */
|
||||
struct labdata* parent;
|
||||
/** tree of sublabels (if any) */
|
||||
ldns_rbtree_t* sublabels;
|
||||
|
||||
/** list of RRs for this label */
|
||||
ldns_rr_list* rrlist;
|
||||
/** have queries for this label been queued */
|
||||
int done;
|
||||
};
|
||||
|
||||
/** usage information for harvest */
|
||||
static void usage(char* nm)
|
||||
{
|
||||
printf("usage: %s [options]\n", nm);
|
||||
printf("-f fnm query list to read from file\n");
|
||||
printf(" every line has format: qname qclass qtype\n");
|
||||
printf("-v verbose (-v -v even more)\n");
|
||||
printf("-C cfg config file with resolver options\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** verbosity for harvest */
|
||||
static int hverb = 0;
|
||||
|
||||
/** exit with error */
|
||||
static void error_exit(const char* str)
|
||||
{
|
||||
printf("error: %s\n", str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** read a query file */
|
||||
static void
|
||||
qlist_read_file(struct harvest_data* data, char* fname)
|
||||
{
|
||||
char buf[1024];
|
||||
char nm[1024], cl[1024], tp[1024];
|
||||
int r;
|
||||
int num = 0;
|
||||
FILE* in = fopen(fname, "r");
|
||||
struct todo_item* t;
|
||||
if(!in) {
|
||||
perror(fname);
|
||||
error_exit("could not open file");
|
||||
}
|
||||
while(fgets(buf, (int)sizeof(buf), in)) {
|
||||
if(buf[0] == 0) continue;
|
||||
if(buf[0] == '\n') continue;
|
||||
/* allow some comments */
|
||||
if(buf[0] == ';') continue;
|
||||
if(buf[0] == '#') continue;
|
||||
nm[0] = 0; cl[0] = 0; tp[0] = 0;
|
||||
r = sscanf(buf, " %1023s %1023s %1023s", nm, cl, tp);
|
||||
if(r == 0) continue;
|
||||
t = (struct todo_item*)calloc(1, sizeof(*t));
|
||||
if(!t) error_exit("out of memory");
|
||||
t->qname = ldns_dname_new_frm_str(nm);
|
||||
if(!t->qname) {
|
||||
printf("parse error: %s\n", nm);
|
||||
error_exit("bad qname");
|
||||
}
|
||||
t->depth = 0;
|
||||
t->qtype = LDNS_RR_TYPE_A;
|
||||
t->qclass = LDNS_RR_CLASS_IN;
|
||||
if(r >= 2) {
|
||||
if(strcmp(cl, "IN") == 0 || strcmp(cl, "CH") == 0)
|
||||
t->qclass = ldns_get_rr_class_by_name(cl);
|
||||
else t->qtype = ldns_get_rr_type_by_name(cl);
|
||||
}
|
||||
if(r >= 3) {
|
||||
if(strcmp(tp, "IN") == 0 || strcmp(tp, "CH") == 0)
|
||||
t->qclass = ldns_get_rr_class_by_name(tp);
|
||||
else t->qtype = ldns_get_rr_type_by_name(tp);
|
||||
}
|
||||
num++;
|
||||
|
||||
t->next = data->orig_list;
|
||||
data->orig_list = t;
|
||||
}
|
||||
printf("read %s: %d queries\n", fname, num);
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
/** compare two labels */
|
||||
static int
|
||||
lab_cmp(const void *x, const void *y)
|
||||
{
|
||||
return ldns_dname_compare((const ldns_rdf*)x, (const ldns_rdf*)y);
|
||||
}
|
||||
|
||||
/** create label entry */
|
||||
static struct labdata*
|
||||
lab_create(const char* name)
|
||||
{
|
||||
struct labdata* lab = (struct labdata*)calloc(1, sizeof(*lab));
|
||||
if(!lab) error_exit("out of memory");
|
||||
lab->label = ldns_dname_new_frm_str(name);
|
||||
if(!lab->label) error_exit("out of memory");
|
||||
lab->name = ldns_dname_new_frm_str(name);
|
||||
if(!lab->name) error_exit("out of memory");
|
||||
lab->node.key = lab->label;
|
||||
lab->node.data = lab;
|
||||
lab->sublabels = ldns_rbtree_create(lab_cmp);
|
||||
if(!lab->sublabels) error_exit("out of memory");
|
||||
lab->rrlist = ldns_rr_list_new();
|
||||
if(!lab->rrlist) error_exit("out of memory");
|
||||
|
||||
return lab;
|
||||
}
|
||||
|
||||
/** for this name, lookup the label, create if does not exist */
|
||||
static struct labdata*
|
||||
find_create_lab(struct harvest_data* data, ldns_rdf* name)
|
||||
{
|
||||
struct labdata* lab = data->root;
|
||||
struct labdata* nextlab;
|
||||
ldns_rdf* next;
|
||||
uint8_t numlab = ldns_dname_label_count(name);
|
||||
if((int)numlab > data->maxlabels)
|
||||
data->maxlabels = (int)numlab;
|
||||
while(numlab--) {
|
||||
next = ldns_dname_label(name, numlab);
|
||||
if(!next) error_exit("ldns_dname_label");
|
||||
|
||||
nextlab = (struct labdata*)
|
||||
ldns_rbtree_search(lab->sublabels, next);
|
||||
if(!nextlab) {
|
||||
/* create it */
|
||||
nextlab = (struct labdata*)calloc(1, sizeof(*lab));
|
||||
if(!nextlab) error_exit("out of memory");
|
||||
nextlab->label = ldns_rdf_clone(next);
|
||||
if(!nextlab->label) error_exit("out of memory");
|
||||
nextlab->node.key = nextlab->label;
|
||||
nextlab->node.data = nextlab;
|
||||
nextlab->sublabels = ldns_rbtree_create(lab_cmp);
|
||||
if(!nextlab->sublabels) error_exit("out of memory");
|
||||
nextlab->parent = lab;
|
||||
nextlab->name = ldns_rdf_clone(next);
|
||||
if(!nextlab->name) error_exit("out of memory");
|
||||
if(ldns_dname_cat(nextlab->name, lab->name)
|
||||
!= LDNS_STATUS_OK) error_exit("outofmem");
|
||||
nextlab->rrlist = ldns_rr_list_new();
|
||||
if(!nextlab->rrlist) error_exit("out of memory");
|
||||
(void)ldns_rbtree_insert(lab->sublabels,
|
||||
&nextlab->node);
|
||||
if(hverb) {
|
||||
printf("new label: ");
|
||||
ldns_rdf_print(stdout, nextlab->name);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
lab = nextlab;
|
||||
ldns_rdf_deep_free(next);
|
||||
}
|
||||
return lab;
|
||||
}
|
||||
|
||||
/** for given query, create todo items, and labels if needed */
|
||||
static void
|
||||
new_todo_item(struct harvest_data* data, ldns_rdf* qname, int qtype,
|
||||
int qclass, int depth)
|
||||
{
|
||||
struct labdata* lab = find_create_lab(data, qname);
|
||||
struct todo_item* it;
|
||||
if(!lab) error_exit("out of memory creating new label");
|
||||
it = (struct todo_item*)calloc(1, sizeof(*it));
|
||||
it->qname = ldns_rdf_clone(qname);
|
||||
it->qtype = qtype;
|
||||
it->qclass = qclass;
|
||||
it->depth = depth;
|
||||
it->lab = lab;
|
||||
it->next = NULL;
|
||||
if(data->todo_last)
|
||||
data->todo_last->next = it;
|
||||
else data->todo_list = it;
|
||||
data->todo_last = it;
|
||||
data->numtodo ++;
|
||||
if(hverb >= 2) {
|
||||
printf("new todo: ");
|
||||
ldns_rdf_print(stdout, it->qname);
|
||||
if(ldns_rr_descript((uint16_t)it->qtype) &&
|
||||
ldns_rr_descript((uint16_t)it->qtype)->_name)
|
||||
printf(" %s", ldns_rr_descript((uint16_t)
|
||||
it->qtype)->_name);
|
||||
if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) &&
|
||||
ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name)
|
||||
printf(" %s", ldns_lookup_by_id(ldns_rr_classes,
|
||||
it->qclass)->name);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** add infra todo items for this query */
|
||||
static void
|
||||
new_todo_infra(struct harvest_data* data, struct labdata* startlab, int depth)
|
||||
{
|
||||
struct labdata* lab;
|
||||
for(lab = startlab; lab; lab = lab->parent) {
|
||||
if(lab->done)
|
||||
return;
|
||||
new_todo_item(data, lab->name, LDNS_RR_TYPE_NS,
|
||||
LDNS_RR_CLASS_IN, depth);
|
||||
new_todo_item(data, lab->name, LDNS_RR_TYPE_SOA,
|
||||
LDNS_RR_CLASS_IN, depth);
|
||||
new_todo_item(data, lab->name, LDNS_RR_TYPE_DNSKEY,
|
||||
LDNS_RR_CLASS_IN, depth);
|
||||
new_todo_item(data, lab->name, LDNS_RR_TYPE_DS,
|
||||
LDNS_RR_CLASS_IN, depth);
|
||||
new_todo_item(data, lab->name, LDNS_RR_TYPE_A,
|
||||
LDNS_RR_CLASS_IN, depth);
|
||||
new_todo_item(data, lab->name, LDNS_RR_TYPE_AAAA,
|
||||
LDNS_RR_CLASS_IN, depth);
|
||||
lab->done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** make todo items for initial data */
|
||||
static void
|
||||
make_todo(struct harvest_data* data)
|
||||
{
|
||||
struct todo_item* it;
|
||||
for(it=data->orig_list; it; it = it->next) {
|
||||
/* create todo item for this query itself */
|
||||
new_todo_item(data, it->qname, it->qtype, it->qclass, 0);
|
||||
/* create todo items for infra queries to support it */
|
||||
new_todo_infra(data, data->todo_list->lab,
|
||||
data->todo_list->depth);
|
||||
}
|
||||
}
|
||||
|
||||
/** store RR and make new work items for it if needed */
|
||||
static void
|
||||
process_rr(struct harvest_data* data, ldns_rr* rr, int depth)
|
||||
{
|
||||
/* must free or store rr */
|
||||
struct labdata* lab = find_create_lab(data, ldns_rr_owner(rr));
|
||||
if(!lab) error_exit("cannot find/create label");
|
||||
/* generate extra queries */
|
||||
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
|
||||
new_todo_infra(data, find_create_lab(data,
|
||||
ldns_rr_ns_nsdname(rr)), depth+1);
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_MX) {
|
||||
new_todo_infra(data, find_create_lab(data,
|
||||
ldns_rr_mx_exchange(rr)), depth+1);
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
|
||||
new_todo_infra(data, find_create_lab(data,
|
||||
ldns_rr_rdf(rr, 0)), depth+1);
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_CNAME) {
|
||||
int t = ldns_rr_get_type(rr);
|
||||
if(t!=LDNS_RR_TYPE_A && t!=LDNS_RR_TYPE_AAAA &&
|
||||
t!=LDNS_RR_TYPE_SOA && t!=LDNS_RR_TYPE_NS &&
|
||||
t!=LDNS_RR_TYPE_DS && t!=LDNS_RR_TYPE_DNSKEY)
|
||||
new_todo_item(data, ldns_rr_rdf(rr, 0), t,
|
||||
ldns_rr_get_class(rr), depth+1);
|
||||
/* can get caught in CNAME loop, but depth will
|
||||
* catch that; unbound cache helps too(servfails on
|
||||
* a cname loop) */
|
||||
new_todo_infra(data, find_create_lab(data,
|
||||
ldns_rr_rdf(rr, 0)), depth+1);
|
||||
}
|
||||
/* store it */
|
||||
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC) {
|
||||
/* find correct zone to store NSEC in (for delegation zones) */
|
||||
if(ldns_dname_compare(ldns_rr_rdf(rr, 0), ldns_rr_owner(rr))
|
||||
== 0) {
|
||||
/* store at the single name = apex */
|
||||
} else if(!ldns_dname_is_subdomain(ldns_rr_rdf(rr, 0),
|
||||
ldns_rr_owner(rr)) && lab->parent) {
|
||||
/* if owner NSEC subdomain-of-owner then
|
||||
* store at owner (owner is apex or empty nonterminal).
|
||||
* Otherwise at owner parent. */
|
||||
lab = lab->parent;
|
||||
}
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) {
|
||||
/* store DSes in parent zone */
|
||||
if(lab->parent)
|
||||
lab = lab->parent;
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3) {
|
||||
/* store NSEC3s one label up at zone apex */
|
||||
if(lab->parent)
|
||||
lab = lab->parent;
|
||||
}
|
||||
/* we assume NS set is equal across parent-child border. */
|
||||
|
||||
if(!ldns_rr_list_contains_rr(lab->rrlist, rr)) {
|
||||
if(hverb >= 2) {
|
||||
printf("store RR ");
|
||||
ldns_rr_print(stdout, rr);
|
||||
printf("\n");
|
||||
}
|
||||
if(!ldns_rr_list_push_rr(lab->rrlist, rr))
|
||||
error_exit("outofmem ldns_rr_list_push_rr");
|
||||
data->num_rrs++;
|
||||
} else {
|
||||
if(hverb >= 2) {
|
||||
printf("duplicate RR ");
|
||||
ldns_rr_print(stdout, rr);
|
||||
printf("\n");
|
||||
}
|
||||
ldns_rr_free(rr);
|
||||
}
|
||||
}
|
||||
|
||||
/** store RRs and make new work items if needed */
|
||||
static void
|
||||
process_pkt(struct harvest_data* data, ldns_pkt* pkt, int depth)
|
||||
{
|
||||
size_t i;
|
||||
ldns_rr_list* list;
|
||||
list = ldns_pkt_get_section_clone(pkt, LDNS_SECTION_ANY_NOQUESTION);
|
||||
if(!list) error_exit("outofmemory");
|
||||
for(i=0; i<ldns_rr_list_rr_count(list); i++) {
|
||||
process_rr(data, ldns_rr_list_rr(list, i), depth);
|
||||
}
|
||||
ldns_rr_list_free(list);
|
||||
}
|
||||
|
||||
/** process a todo item */
|
||||
static void
|
||||
process(struct harvest_data* data, struct todo_item* it)
|
||||
{
|
||||
int r;
|
||||
char* nm;
|
||||
struct ub_result* result = NULL;
|
||||
ldns_pkt* pkt = NULL;
|
||||
ldns_status s;
|
||||
if(hverb) {
|
||||
printf("process: ");
|
||||
ldns_rdf_print(stdout, it->qname);
|
||||
if(ldns_rr_descript((uint16_t)it->qtype) &&
|
||||
ldns_rr_descript((uint16_t)it->qtype)->_name)
|
||||
printf(" %s", ldns_rr_descript((uint16_t)
|
||||
it->qtype)->_name);
|
||||
if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) &&
|
||||
ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name)
|
||||
printf(" %s", ldns_lookup_by_id(ldns_rr_classes,
|
||||
it->qclass)->name);
|
||||
printf("\n");
|
||||
}
|
||||
/* do lookup */
|
||||
nm = ldns_rdf2str(it->qname);
|
||||
if(!nm) error_exit("ldns_rdf2str");
|
||||
r = ub_resolve(data->ctx, nm, it->qtype, it->qclass, &result);
|
||||
if(r != 0) {
|
||||
printf("ub_resolve(%s, %d, %d): %s\n", nm, it->qtype,
|
||||
it->qclass, ub_strerror(r));
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
if(result->rcode == LDNS_RCODE_SERVFAIL) {
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
/* even if result is a negative, try to store resulting SOA/NSEC */
|
||||
|
||||
/* create ldns pkt */
|
||||
s = ldns_wire2pkt(&pkt, result->answer_packet,
|
||||
(size_t)result->answer_len);
|
||||
if(s != LDNS_STATUS_OK) {
|
||||
printf("ldns_wire2pkt failed! %s %d %d %s %d\n", nm,
|
||||
it->qtype, it->qclass, ldns_get_errorstr_by_id(s),
|
||||
result->answer_len);
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
if(hverb >= 2) {
|
||||
printf("answer: ");
|
||||
ldns_pkt_print(stdout, pkt);
|
||||
printf("\n");
|
||||
}
|
||||
/* process results */
|
||||
process_pkt(data, pkt, it->depth);
|
||||
|
||||
ldns_pkt_free(pkt);
|
||||
free(nm);
|
||||
ub_resolve_free(result);
|
||||
}
|
||||
|
||||
/** perform main harvesting */
|
||||
static void
|
||||
harvest_main(struct harvest_data* data)
|
||||
{
|
||||
struct todo_item* it;
|
||||
int numdone = 0;
|
||||
/* register todo queries for all original queries */
|
||||
make_todo(data);
|
||||
printf("depth 0: done %d todo %d\n", 0, data->numtodo);
|
||||
/* pick up a todo item and process it */
|
||||
while(data->todo_list) {
|
||||
numdone++;
|
||||
it = data->todo_list;
|
||||
data->todo_list = it->next;
|
||||
if(!data->todo_list) data->todo_last = NULL;
|
||||
if(numdone%1000==0 || it->depth > data->curdepth) {
|
||||
data->curdepth = it->depth;
|
||||
printf("depth %d: done %d todo %d, %d rrs\n",
|
||||
it->depth, numdone, data->numtodo,
|
||||
data->num_rrs);
|
||||
}
|
||||
if(it->depth >= data->maxdepth) {
|
||||
printf("obtained %d rrs to a max of %d labels.\n",
|
||||
data->num_rrs, data->maxlabels);
|
||||
return;
|
||||
}
|
||||
data->numtodo--;
|
||||
process(data, it);
|
||||
usleep(1000000/100);
|
||||
}
|
||||
}
|
||||
|
||||
/** create directory if it does not exist */
|
||||
static void
|
||||
hv_mkdir(char* dir)
|
||||
{
|
||||
#ifdef MKDIR_HAS_ONE_ARG
|
||||
if(mkdir(dir) == -1) {
|
||||
#else
|
||||
if(mkdir(dir, 0755) == -1) {
|
||||
#endif
|
||||
if(errno == EEXIST)
|
||||
return;
|
||||
perror(dir);
|
||||
error_exit("mkdir failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** see if rrlist contains a SOA record */
|
||||
static ldns_rr*
|
||||
has_SOA(ldns_rr_list* list)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<ldns_rr_list_rr_count(list); i++) {
|
||||
if(ldns_rr_get_type(ldns_rr_list_rr(list, i))
|
||||
== LDNS_RR_TYPE_SOA)
|
||||
return ldns_rr_list_rr(list, i);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** write moredata for a zone*/
|
||||
static void
|
||||
write_moredata(struct harvest_data* data, struct labdata* zone,
|
||||
FILE *f, struct labdata* thislab, ldns_rr* nslist)
|
||||
{
|
||||
struct labdata* lab;
|
||||
size_t i;
|
||||
ldns_rr* ns;
|
||||
LDNS_RBTREE_FOR(lab, struct labdata*, thislab->sublabels) {
|
||||
if(has_SOA(lab->rrlist)) {
|
||||
/* copy only NS glue */
|
||||
for(i=0; i<ldns_rr_list_rr_count(lab->rrlist); i++) {
|
||||
ns = ldns_rr_list_rr(lab->rrlist, i);
|
||||
if(ldns_rr_get_type(ns) == LDNS_RR_TYPE_NS) {
|
||||
ldns_rr_print(f, ns);
|
||||
if(ldns_dname_is_subdomain(
|
||||
ldns_rr_ns_nsdname(ns),
|
||||
lab->name)) {
|
||||
ldns_rr_push_rdf(nslist,
|
||||
ldns_rdf_clone(
|
||||
ldns_rr_ns_nsdname(ns)));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* copy all, recurse */
|
||||
for(i=0; i<ldns_rr_list_rr_count(lab->rrlist); i++) {
|
||||
ldns_rr_print(f,
|
||||
ldns_rr_list_rr(lab->rrlist, i));
|
||||
}
|
||||
write_moredata(data, zone, f, lab, nslist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** find and write glue into zone file */
|
||||
static void
|
||||
write_glue(struct harvest_data* data, struct labdata* thislab, FILE* f,
|
||||
ldns_rdf* name, int dep)
|
||||
{
|
||||
size_t i;
|
||||
struct labdata* lab;
|
||||
ldns_rr* rr;
|
||||
if(ldns_dname_compare(name, thislab->name) == 0) {
|
||||
/* this is it! Did we go outside the zone? */
|
||||
if(dep == 0)
|
||||
return;
|
||||
/* find A and AAAA */
|
||||
for(i=0; i<ldns_rr_list_rr_count(thislab->rrlist); i++) {
|
||||
rr = ldns_rr_list_rr(thislab->rrlist, i);
|
||||
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A ||
|
||||
ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
|
||||
ldns_rr_print(f, rr);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* recurse deeper */
|
||||
LDNS_RBTREE_FOR(lab, struct labdata*, thislab->sublabels) {
|
||||
if(has_SOA(lab->rrlist)) {
|
||||
write_glue(data, lab, f, name, dep+1);
|
||||
} else {
|
||||
write_glue(data, lab, f, name, dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** write zonefile for zone at this apex */
|
||||
static void
|
||||
write_zonefile(struct harvest_data* data, int dep, FILE* zlist,
|
||||
struct labdata* apex, ldns_rr* soa)
|
||||
{
|
||||
FILE *f;
|
||||
char fname[1024];
|
||||
char* zname = ldns_rdf2str(apex->name);
|
||||
time_t tm = time(NULL);
|
||||
size_t i;
|
||||
ldns_rr* nslist;
|
||||
if(!zname) error_exit("out of mem ldns_rdf2str");
|
||||
if(strcmp(zname, ".") == 0)
|
||||
snprintf(fname, sizeof(fname), "l%d/root.zone", dep);
|
||||
else snprintf(fname, sizeof(fname), "l%d/%szone", dep, zname);
|
||||
|
||||
fprintf(zlist, "zone: name: \"%s\" %s%szonefile: \"%s\"\n",
|
||||
zname,
|
||||
strlen(zname)/8<1?"\t":"",
|
||||
strlen(zname)/8<2?"\t":"",
|
||||
fname);
|
||||
|
||||
if(hverb) printf("writing %s\n", fname);
|
||||
f = fopen(fname, "w");
|
||||
if(!f) {
|
||||
perror(fname);
|
||||
error_exit("cannot open zone file");
|
||||
}
|
||||
fprintf(f, "; %s - generated by harvest program.\n", fname);
|
||||
fprintf(f, "; zone name %s - this is a partial snapshot of "
|
||||
"data relevant to the query list.\n", zname);
|
||||
fprintf(f, "; created %u - date %s\n", (unsigned)tm, ctime(&tm));
|
||||
ldns_rr_print(f, soa);
|
||||
fprintf(f, "\n");
|
||||
for(i=0; i<ldns_rr_list_rr_count(apex->rrlist); i++) {
|
||||
if(ldns_rr_get_type(ldns_rr_list_rr(apex->rrlist, i))
|
||||
== LDNS_RR_TYPE_SOA) continue;
|
||||
ldns_rr_print(f, ldns_rr_list_rr(apex->rrlist, i));
|
||||
}
|
||||
/* search for more data - subdomains inside the zone, NS glue */
|
||||
nslist = ldns_rr_new();
|
||||
if(!nslist) error_exit("out of memory");
|
||||
fprintf(f, "; end of apex, more data follows\n");
|
||||
write_moredata(data, apex, f, apex, nslist);
|
||||
|
||||
/* add NS from apex that need glue too */
|
||||
for(i=0; i<ldns_rr_list_rr_count(apex->rrlist); i++) {
|
||||
if(ldns_rr_get_type(ldns_rr_list_rr(apex->rrlist, i)) !=
|
||||
LDNS_RR_TYPE_NS)
|
||||
continue;
|
||||
/* these are only added again if in a subzone */
|
||||
if(ldns_dname_is_subdomain(ldns_rr_ns_nsdname(
|
||||
ldns_rr_list_rr(apex->rrlist, i)), apex->name)) {
|
||||
ldns_rr_push_rdf(nslist, ldns_rdf_clone(
|
||||
ldns_rr_ns_nsdname(ldns_rr_list_rr(
|
||||
apex->rrlist, i))));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(f, "; glue data follows\n");
|
||||
/* lookup and add glue (if not already in zone) */
|
||||
for(i=0; i<ldns_rr_rd_count(nslist); i++) {
|
||||
write_glue(data, apex, f, ldns_rr_rdf(nslist, i), 0);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
ldns_rr_free(nslist);
|
||||
free(zname);
|
||||
}
|
||||
|
||||
/** create zones at depth d in label tree */
|
||||
static void
|
||||
create_zones(struct harvest_data* data, int dep, FILE* zlist,
|
||||
struct labdata* labnow, int depnow)
|
||||
{
|
||||
struct labdata* s;
|
||||
ldns_rr* soa;
|
||||
if(depnow == dep) {
|
||||
/* see if this is a zone start - a SOA */
|
||||
if((soa=has_SOA(labnow->rrlist))) {
|
||||
write_zonefile(data, dep, zlist, labnow, soa);
|
||||
data->num_zones++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* recurse */
|
||||
LDNS_RBTREE_FOR(s, struct labdata*, labnow->sublabels) {
|
||||
create_zones(data, dep, zlist, s, depnow+1);
|
||||
}
|
||||
}
|
||||
|
||||
/** sort rrlists */
|
||||
static void
|
||||
harvest_sort(struct labdata* lab)
|
||||
{
|
||||
struct labdata* s;
|
||||
/* prettier output if sorted here */
|
||||
ldns_rr_list_sort(lab->rrlist);
|
||||
/* and recurse */
|
||||
LDNS_RBTREE_FOR(s, struct labdata*, lab->sublabels) {
|
||||
harvest_sort(s);
|
||||
}
|
||||
}
|
||||
|
||||
/** output harvested results */
|
||||
static void
|
||||
harvest_output(struct harvest_data* data)
|
||||
{
|
||||
int d;
|
||||
char buf[20];
|
||||
FILE* zlist;
|
||||
int lastzones;
|
||||
hv_mkdir(data->resultdir);
|
||||
if(chdir(data->resultdir) == -1) {
|
||||
perror(data->resultdir);
|
||||
error_exit("cannot chdir");
|
||||
}
|
||||
harvest_sort(data->root);
|
||||
/* create zones */
|
||||
for(d = 0; d<data->maxlabels; d++) {
|
||||
lastzones = data->num_zones;
|
||||
printf("creating zones %d\n", d);
|
||||
snprintf(buf, sizeof(buf), "l%d", d);
|
||||
hv_mkdir(buf);
|
||||
snprintf(buf, sizeof(buf), "l%d.zones", d);
|
||||
zlist = fopen(buf, "w");
|
||||
if(!zlist) {
|
||||
perror(buf);
|
||||
error_exit("cannot write zonelist file");
|
||||
}
|
||||
fprintf(zlist, "# partial zones at depth %d\n", d);
|
||||
create_zones(data, d, zlist, data->root, 0);
|
||||
fclose(zlist);
|
||||
printf("creating zones %d - %d zones written\n", d,
|
||||
data->num_zones - lastzones);
|
||||
}
|
||||
}
|
||||
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern int optind;
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern char* optarg;
|
||||
|
||||
/** main program for harvest */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
struct harvest_data data;
|
||||
char* nm = argv[0];
|
||||
int c;
|
||||
|
||||
/* defaults */
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.ctx = ub_ctx_create();
|
||||
data.resultdir = strdup("harvested_zones");
|
||||
if(!data.resultdir) error_exit("out of memory");
|
||||
data.maxdepth = 2;
|
||||
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "hf:vC:")) != -1) {
|
||||
switch(c) {
|
||||
case 'C':
|
||||
if(ub_ctx_config(data.ctx, optarg) != 0)
|
||||
error_exit("config read failed");
|
||||
break;
|
||||
case 'f':
|
||||
qlist_read_file(&data, optarg);
|
||||
break;
|
||||
case 'v':
|
||||
hverb++;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
usage(nm);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if(argc != 0)
|
||||
usage(nm);
|
||||
if(data.orig_list == NULL)
|
||||
error_exit("No queries to make, use -f (help with -h).");
|
||||
data.root = lab_create(".");
|
||||
if(!data.root) error_exit("out of memory");
|
||||
|
||||
/* harvest the data */
|
||||
harvest_main(&data);
|
||||
harvest_output(&data);
|
||||
|
||||
/* no cleanup except the context (to close open sockets) */
|
||||
ub_ctx_delete(data.ctx);
|
||||
return 0;
|
||||
}
|
@ -1,898 +0,0 @@
|
||||
/*
|
||||
* ldns-testpkts. Data file parse for test packets, and query matching.
|
||||
*
|
||||
* Data storage for specially crafted replies for testing purposes.
|
||||
*
|
||||
* (c) NLnet Labs, 2005, 2006, 2007, 2008
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* This is a debugging aid. It is not efficient, especially
|
||||
* with a long config file, but it can give any reply to any query.
|
||||
* This can help the developer pre-script replies for queries.
|
||||
*
|
||||
* You can specify a packet RR by RR with header flags to return.
|
||||
*
|
||||
* Missing features:
|
||||
* - matching content different from reply content.
|
||||
* - find way to adjust mangled packets?
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
struct sockaddr_storage;
|
||||
#include <ldns/ldns.h>
|
||||
#include <errno.h>
|
||||
#include "ldns-testpkts.h"
|
||||
|
||||
/** max line length */
|
||||
#define MAX_LINE 10240
|
||||
/** string to show in warnings and errors */
|
||||
static const char* prog_name = "ldns-testpkts";
|
||||
|
||||
#ifndef UTIL_LOG_H
|
||||
/** verbosity definition for compat */
|
||||
enum verbosity_value { NO_VERBOSE=0 };
|
||||
#endif
|
||||
/** logging routine, provided by caller */
|
||||
void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3);
|
||||
|
||||
/** print error and exit */
|
||||
static void error(const char* msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
fprintf(stderr, "%s error: ", prog_name);
|
||||
vfprintf(stderr, msg, args);
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
va_end(args);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/** return if string is empty or comment */
|
||||
static bool isendline(char c)
|
||||
{
|
||||
if(c == ';' || c == '#'
|
||||
|| c == '\n' || c == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** true if the string starts with the keyword given. Moves the str ahead.
|
||||
* @param str: before keyword, afterwards after keyword and spaces.
|
||||
* @param keyword: the keyword to match
|
||||
* @return: true if keyword present. False otherwise, and str unchanged.
|
||||
*/
|
||||
static bool str_keyword(char** str, const char* keyword)
|
||||
{
|
||||
size_t len = strlen(keyword);
|
||||
assert(str && keyword);
|
||||
if(strncmp(*str, keyword, len) != 0)
|
||||
return false;
|
||||
*str += len;
|
||||
while(isspace((int)**str))
|
||||
(*str)++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Add reply packet to entry */
|
||||
static struct reply_packet*
|
||||
entry_add_reply(struct entry* entry)
|
||||
{
|
||||
struct reply_packet* pkt = (struct reply_packet*)malloc(
|
||||
sizeof(struct reply_packet));
|
||||
struct reply_packet ** p = &entry->reply_list;
|
||||
pkt->next = NULL;
|
||||
pkt->packet_sleep = 0;
|
||||
pkt->reply = ldns_pkt_new();
|
||||
pkt->reply_from_hex = NULL;
|
||||
/* link at end */
|
||||
while(*p)
|
||||
p = &((*p)->next);
|
||||
*p = pkt;
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/** parse MATCH line */
|
||||
static void matchline(char* line, struct entry* e)
|
||||
{
|
||||
char* parse = line;
|
||||
while(*parse) {
|
||||
if(isendline(*parse))
|
||||
return;
|
||||
if(str_keyword(&parse, "opcode")) {
|
||||
e->match_opcode = true;
|
||||
} else if(str_keyword(&parse, "qtype")) {
|
||||
e->match_qtype = true;
|
||||
} else if(str_keyword(&parse, "qname")) {
|
||||
e->match_qname = true;
|
||||
} else if(str_keyword(&parse, "subdomain")) {
|
||||
e->match_subdomain = true;
|
||||
} else if(str_keyword(&parse, "all")) {
|
||||
e->match_all = true;
|
||||
} else if(str_keyword(&parse, "ttl")) {
|
||||
e->match_ttl = true;
|
||||
} else if(str_keyword(&parse, "DO")) {
|
||||
e->match_do = true;
|
||||
} else if(str_keyword(&parse, "noedns")) {
|
||||
e->match_noedns = true;
|
||||
} else if(str_keyword(&parse, "UDP")) {
|
||||
e->match_transport = transport_udp;
|
||||
} else if(str_keyword(&parse, "TCP")) {
|
||||
e->match_transport = transport_tcp;
|
||||
} else if(str_keyword(&parse, "serial")) {
|
||||
e->match_serial = true;
|
||||
if(*parse != '=' && *parse != ':')
|
||||
error("expected = or : in MATCH: %s", line);
|
||||
parse++;
|
||||
e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((int)*parse))
|
||||
parse++;
|
||||
} else {
|
||||
error("could not parse MATCH: '%s'", parse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** parse REPLY line */
|
||||
static void replyline(char* line, ldns_pkt *reply)
|
||||
{
|
||||
char* parse = line;
|
||||
while(*parse) {
|
||||
if(isendline(*parse))
|
||||
return;
|
||||
/* opcodes */
|
||||
if(str_keyword(&parse, "QUERY")) {
|
||||
ldns_pkt_set_opcode(reply, LDNS_PACKET_QUERY);
|
||||
} else if(str_keyword(&parse, "IQUERY")) {
|
||||
ldns_pkt_set_opcode(reply, LDNS_PACKET_IQUERY);
|
||||
} else if(str_keyword(&parse, "STATUS")) {
|
||||
ldns_pkt_set_opcode(reply, LDNS_PACKET_STATUS);
|
||||
} else if(str_keyword(&parse, "NOTIFY")) {
|
||||
ldns_pkt_set_opcode(reply, LDNS_PACKET_NOTIFY);
|
||||
} else if(str_keyword(&parse, "UPDATE")) {
|
||||
ldns_pkt_set_opcode(reply, LDNS_PACKET_UPDATE);
|
||||
/* rcodes */
|
||||
} else if(str_keyword(&parse, "NOERROR")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOERROR);
|
||||
} else if(str_keyword(&parse, "FORMERR")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_FORMERR);
|
||||
} else if(str_keyword(&parse, "SERVFAIL")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_SERVFAIL);
|
||||
} else if(str_keyword(&parse, "NXDOMAIN")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_NXDOMAIN);
|
||||
} else if(str_keyword(&parse, "NOTIMPL")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTIMPL);
|
||||
} else if(str_keyword(&parse, "REFUSED")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_REFUSED);
|
||||
} else if(str_keyword(&parse, "YXDOMAIN")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_YXDOMAIN);
|
||||
} else if(str_keyword(&parse, "YXRRSET")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_YXRRSET);
|
||||
} else if(str_keyword(&parse, "NXRRSET")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_NXRRSET);
|
||||
} else if(str_keyword(&parse, "NOTAUTH")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTAUTH);
|
||||
} else if(str_keyword(&parse, "NOTZONE")) {
|
||||
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTZONE);
|
||||
/* flags */
|
||||
} else if(str_keyword(&parse, "QR")) {
|
||||
ldns_pkt_set_qr(reply, true);
|
||||
} else if(str_keyword(&parse, "AA")) {
|
||||
ldns_pkt_set_aa(reply, true);
|
||||
} else if(str_keyword(&parse, "TC")) {
|
||||
ldns_pkt_set_tc(reply, true);
|
||||
} else if(str_keyword(&parse, "RD")) {
|
||||
ldns_pkt_set_rd(reply, true);
|
||||
} else if(str_keyword(&parse, "CD")) {
|
||||
ldns_pkt_set_cd(reply, true);
|
||||
} else if(str_keyword(&parse, "RA")) {
|
||||
ldns_pkt_set_ra(reply, true);
|
||||
} else if(str_keyword(&parse, "AD")) {
|
||||
ldns_pkt_set_ad(reply, true);
|
||||
} else if(str_keyword(&parse, "DO")) {
|
||||
ldns_pkt_set_edns_udp_size(reply, 4096);
|
||||
ldns_pkt_set_edns_do(reply, true);
|
||||
} else {
|
||||
error("could not parse REPLY: '%s'", parse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** parse ADJUST line */
|
||||
static void adjustline(char* line, struct entry* e,
|
||||
struct reply_packet* pkt)
|
||||
{
|
||||
char* parse = line;
|
||||
while(*parse) {
|
||||
if(isendline(*parse))
|
||||
return;
|
||||
if(str_keyword(&parse, "copy_id")) {
|
||||
e->copy_id = true;
|
||||
} else if(str_keyword(&parse, "copy_query")) {
|
||||
e->copy_query = true;
|
||||
} else if(str_keyword(&parse, "sleep=")) {
|
||||
e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((int)*parse))
|
||||
parse++;
|
||||
} else if(str_keyword(&parse, "packet_sleep=")) {
|
||||
pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((int)*parse))
|
||||
parse++;
|
||||
} else {
|
||||
error("could not parse ADJUST: '%s'", parse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** create new entry */
|
||||
static struct entry* new_entry()
|
||||
{
|
||||
struct entry* e = LDNS_MALLOC(struct entry);
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->match_opcode = false;
|
||||
e->match_qtype = false;
|
||||
e->match_qname = false;
|
||||
e->match_subdomain = false;
|
||||
e->match_all = false;
|
||||
e->match_ttl = false;
|
||||
e->match_do = false;
|
||||
e->match_noedns = false;
|
||||
e->match_serial = false;
|
||||
e->ixfr_soa_serial = 0;
|
||||
e->match_transport = transport_any;
|
||||
e->reply_list = NULL;
|
||||
e->copy_id = false;
|
||||
e->copy_query = false;
|
||||
e->sleeptime = 0;
|
||||
e->next = NULL;
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a hex string to binary data
|
||||
* @param hexstr: string of hex.
|
||||
* @param len: is the length of the string
|
||||
* @param buf: is the buffer to store the result in
|
||||
* @param offset: is the starting position in the result buffer
|
||||
* @param buf_len: is the length of buf.
|
||||
* @return This function returns the length of the result
|
||||
*/
|
||||
static size_t
|
||||
hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len)
|
||||
{
|
||||
char c;
|
||||
int i;
|
||||
uint8_t int8 = 0;
|
||||
int sec = 0;
|
||||
size_t bufpos = 0;
|
||||
|
||||
if (len % 2 != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
c = hexstr[i];
|
||||
|
||||
/* case insensitive, skip spaces */
|
||||
if (c != ' ') {
|
||||
if (c >= '0' && c <= '9') {
|
||||
int8 += c & 0x0f;
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
int8 += (c & 0x0f) + 9;
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
int8 += (c & 0x0f) + 9;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sec == 0) {
|
||||
int8 = int8 << 4;
|
||||
sec = 1;
|
||||
} else {
|
||||
if (bufpos + offset + 1 <= buf_len) {
|
||||
buf[bufpos+offset] = int8;
|
||||
int8 = 0;
|
||||
sec = 0;
|
||||
bufpos++;
|
||||
} else {
|
||||
fprintf(stderr, "Buffer too small in hexstr2bin");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bufpos;
|
||||
}
|
||||
|
||||
/** convert hex buffer to binary buffer */
|
||||
static ldns_buffer *
|
||||
data_buffer2wire(ldns_buffer *data_buffer)
|
||||
{
|
||||
ldns_buffer *wire_buffer = NULL;
|
||||
int c;
|
||||
|
||||
/* stat hack
|
||||
* 0 = normal
|
||||
* 1 = comment (skip to end of line)
|
||||
* 2 = unprintable character found, read binary data directly
|
||||
*/
|
||||
size_t data_buf_pos = 0;
|
||||
int state = 0;
|
||||
uint8_t *hexbuf;
|
||||
int hexbufpos = 0;
|
||||
size_t wirelen;
|
||||
uint8_t *data_wire = (uint8_t *) ldns_buffer_begin(data_buffer);
|
||||
uint8_t *wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
|
||||
|
||||
hexbuf = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
|
||||
for (data_buf_pos = 0; data_buf_pos < ldns_buffer_position(data_buffer); data_buf_pos++) {
|
||||
c = (int) data_wire[data_buf_pos];
|
||||
|
||||
if (state < 2 && !isascii(c)) {
|
||||
/*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/
|
||||
state = 2;
|
||||
}
|
||||
switch (state) {
|
||||
case 0:
|
||||
if ( (c >= '0' && c <= '9') ||
|
||||
(c >= 'a' && c <= 'f') ||
|
||||
(c >= 'A' && c <= 'F') )
|
||||
{
|
||||
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
|
||||
error("buffer overflow");
|
||||
LDNS_FREE(hexbuf);
|
||||
return 0;
|
||||
|
||||
}
|
||||
hexbuf[hexbufpos] = (uint8_t) c;
|
||||
hexbufpos++;
|
||||
} else if (c == ';') {
|
||||
state = 1;
|
||||
} else if (c == ' ' || c == '\t' || c == '\n') {
|
||||
/* skip whitespace */
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (c == '\n' || c == EOF) {
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
|
||||
error("buffer overflow");
|
||||
LDNS_FREE(hexbuf);
|
||||
return 0;
|
||||
}
|
||||
hexbuf[hexbufpos] = (uint8_t) c;
|
||||
hexbufpos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
|
||||
/*verbose("packet size reached\n");*/
|
||||
}
|
||||
|
||||
/* lenient mode: length must be multiple of 2 */
|
||||
if (hexbufpos % 2 != 0) {
|
||||
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
|
||||
error("buffer overflow");
|
||||
LDNS_FREE(hexbuf);
|
||||
return 0;
|
||||
}
|
||||
hexbuf[hexbufpos] = (uint8_t) '0';
|
||||
hexbufpos++;
|
||||
}
|
||||
|
||||
if (state < 2) {
|
||||
wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0, LDNS_MAX_PACKETLEN);
|
||||
wire_buffer = ldns_buffer_new(wirelen);
|
||||
ldns_buffer_new_frm_data(wire_buffer, wire, wirelen);
|
||||
} else {
|
||||
error("Incomplete hex data, not at byte boundary\n");
|
||||
}
|
||||
LDNS_FREE(wire);
|
||||
LDNS_FREE(hexbuf);
|
||||
return wire_buffer;
|
||||
}
|
||||
|
||||
/** parse ORIGIN */
|
||||
static void
|
||||
get_origin(const char* name, int lineno, ldns_rdf** origin, char* parse)
|
||||
{
|
||||
/* snip off rest of the text so as to make the parse work in ldns */
|
||||
char* end;
|
||||
char store;
|
||||
ldns_status status;
|
||||
|
||||
ldns_rdf_free(*origin);
|
||||
*origin = NULL;
|
||||
|
||||
end=parse;
|
||||
while(!isspace((int)*end) && !isendline(*end))
|
||||
end++;
|
||||
store = *end;
|
||||
*end = 0;
|
||||
verbose(3, "parsing '%s'\n", parse);
|
||||
status = ldns_str2rdf_dname(origin, parse);
|
||||
*end = store;
|
||||
if (status != LDNS_STATUS_OK)
|
||||
error("%s line %d:\n\t%s: %s", name, lineno,
|
||||
ldns_get_errorstr_by_id(status), parse);
|
||||
}
|
||||
|
||||
/* Reads one entry from file. Returns entry or NULL on error. */
|
||||
struct entry*
|
||||
read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl,
|
||||
ldns_rdf** origin, ldns_rdf** prev_rr, int skip_whitespace)
|
||||
{
|
||||
struct entry* current = NULL;
|
||||
char line[MAX_LINE];
|
||||
char* parse;
|
||||
ldns_pkt_section add_section = LDNS_SECTION_QUESTION;
|
||||
struct reply_packet *cur_reply = NULL;
|
||||
bool reading_hex = false;
|
||||
ldns_buffer* hex_data_buffer = NULL;
|
||||
|
||||
while(fgets(line, (int)sizeof(line), in) != NULL) {
|
||||
line[MAX_LINE-1] = 0;
|
||||
parse = line;
|
||||
(*lineno) ++;
|
||||
|
||||
while(isspace((int)*parse))
|
||||
parse++;
|
||||
/* test for keywords */
|
||||
if(isendline(*parse))
|
||||
continue; /* skip comment and empty lines */
|
||||
if(str_keyword(&parse, "ENTRY_BEGIN")) {
|
||||
if(current) {
|
||||
error("%s line %d: previous entry does not ENTRY_END",
|
||||
name, *lineno);
|
||||
}
|
||||
current = new_entry();
|
||||
current->lineno = *lineno;
|
||||
cur_reply = entry_add_reply(current);
|
||||
continue;
|
||||
} else if(str_keyword(&parse, "$ORIGIN")) {
|
||||
get_origin(name, *lineno, origin, parse);
|
||||
continue;
|
||||
} else if(str_keyword(&parse, "$TTL")) {
|
||||
*default_ttl = (uint32_t)atoi(parse);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* working inside an entry */
|
||||
if(!current) {
|
||||
error("%s line %d: expected ENTRY_BEGIN but got %s",
|
||||
name, *lineno, line);
|
||||
}
|
||||
if(str_keyword(&parse, "MATCH")) {
|
||||
matchline(parse, current);
|
||||
} else if(str_keyword(&parse, "REPLY")) {
|
||||
replyline(parse, cur_reply->reply);
|
||||
} else if(str_keyword(&parse, "ADJUST")) {
|
||||
adjustline(parse, current, cur_reply);
|
||||
} else if(str_keyword(&parse, "EXTRA_PACKET")) {
|
||||
cur_reply = entry_add_reply(current);
|
||||
} else if(str_keyword(&parse, "SECTION")) {
|
||||
if(str_keyword(&parse, "QUESTION"))
|
||||
add_section = LDNS_SECTION_QUESTION;
|
||||
else if(str_keyword(&parse, "ANSWER"))
|
||||
add_section = LDNS_SECTION_ANSWER;
|
||||
else if(str_keyword(&parse, "AUTHORITY"))
|
||||
add_section = LDNS_SECTION_AUTHORITY;
|
||||
else if(str_keyword(&parse, "ADDITIONAL"))
|
||||
add_section = LDNS_SECTION_ADDITIONAL;
|
||||
else error("%s line %d: bad section %s", name, *lineno, parse);
|
||||
} else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) {
|
||||
hex_data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
|
||||
reading_hex = true;
|
||||
} else if(str_keyword(&parse, "HEX_ANSWER_END")) {
|
||||
if (!reading_hex) {
|
||||
error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, *lineno);
|
||||
}
|
||||
reading_hex = false;
|
||||
cur_reply->reply_from_hex = data_buffer2wire(hex_data_buffer);
|
||||
ldns_buffer_free(hex_data_buffer);
|
||||
hex_data_buffer = NULL;
|
||||
} else if(str_keyword(&parse, "ENTRY_END")) {
|
||||
if (hex_data_buffer)
|
||||
ldns_buffer_free(hex_data_buffer);
|
||||
return current;
|
||||
} else if(reading_hex) {
|
||||
ldns_buffer_printf(hex_data_buffer, line);
|
||||
} else {
|
||||
/* it must be a RR, parse and add to packet. */
|
||||
ldns_rr* n = NULL;
|
||||
ldns_status status;
|
||||
char* rrstr = line;
|
||||
if (skip_whitespace)
|
||||
rrstr = parse;
|
||||
if(add_section == LDNS_SECTION_QUESTION)
|
||||
status = ldns_rr_new_question_frm_str(
|
||||
&n, rrstr, *origin, prev_rr);
|
||||
else status = ldns_rr_new_frm_str(&n, rrstr,
|
||||
*default_ttl, *origin, prev_rr);
|
||||
if(status != LDNS_STATUS_OK)
|
||||
error("%s line %d:\n\t%s: %s", name, *lineno,
|
||||
ldns_get_errorstr_by_id(status), rrstr);
|
||||
ldns_pkt_push_rr(cur_reply->reply, add_section, n);
|
||||
}
|
||||
|
||||
}
|
||||
if (reading_hex) {
|
||||
error("%s: End of file reached while still reading hex, "
|
||||
"missing HEX_ANSWER_END\n", name);
|
||||
}
|
||||
if(current) {
|
||||
error("%s: End of file reached while reading entry. "
|
||||
"missing ENTRY_END\n", name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reads the canned reply file and returns a list of structs */
|
||||
struct entry*
|
||||
read_datafile(const char* name, int skip_whitespace)
|
||||
{
|
||||
struct entry* list = NULL;
|
||||
struct entry* last = NULL;
|
||||
struct entry* current = NULL;
|
||||
FILE *in;
|
||||
int lineno = 0;
|
||||
uint32_t default_ttl = 0;
|
||||
ldns_rdf* origin = NULL;
|
||||
ldns_rdf* prev_rr = NULL;
|
||||
int entry_num = 0;
|
||||
|
||||
if((in=fopen(name, "r")) == NULL) {
|
||||
error("could not open file %s: %s", name, strerror(errno));
|
||||
}
|
||||
|
||||
while((current = read_entry(in, name, &lineno, &default_ttl,
|
||||
&origin, &prev_rr, skip_whitespace)))
|
||||
{
|
||||
if(last)
|
||||
last->next = current;
|
||||
else list = current;
|
||||
last = current;
|
||||
entry_num ++;
|
||||
}
|
||||
verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
|
||||
|
||||
fclose(in);
|
||||
ldns_rdf_deep_free(origin);
|
||||
ldns_rdf_deep_free(prev_rr);
|
||||
return list;
|
||||
}
|
||||
|
||||
/** get qtype from rr */
|
||||
static ldns_rr_type get_qtype(ldns_pkt* p)
|
||||
{
|
||||
if(!ldns_rr_list_rr(ldns_pkt_question(p), 0))
|
||||
return 0;
|
||||
return ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_question(p), 0));
|
||||
}
|
||||
|
||||
/** returns owner from rr */
|
||||
static ldns_rdf* get_owner(ldns_pkt* p)
|
||||
{
|
||||
if(!ldns_rr_list_rr(ldns_pkt_question(p), 0))
|
||||
return NULL;
|
||||
return ldns_rr_owner(ldns_rr_list_rr(ldns_pkt_question(p), 0));
|
||||
}
|
||||
|
||||
/** get authority section SOA serial value */
|
||||
static uint32_t get_serial(ldns_pkt* p)
|
||||
{
|
||||
ldns_rr *rr = ldns_rr_list_rr(ldns_pkt_authority(p), 0);
|
||||
ldns_rdf *rdf;
|
||||
uint32_t val;
|
||||
if(!rr) return 0;
|
||||
rdf = ldns_rr_rdf(rr, 2);
|
||||
if(!rdf) return 0;
|
||||
val = ldns_rdf2native_int32(rdf);
|
||||
verbose(3, "found serial %u in msg. ", (int)val);
|
||||
return val;
|
||||
}
|
||||
|
||||
/** match two rr lists */
|
||||
static int
|
||||
match_list(ldns_rr_list* q, ldns_rr_list *p, bool mttl)
|
||||
{
|
||||
size_t i;
|
||||
if(ldns_rr_list_rr_count(q) != ldns_rr_list_rr_count(p))
|
||||
return 0;
|
||||
for(i=0; i<ldns_rr_list_rr_count(q); i++)
|
||||
{
|
||||
if(ldns_rr_compare(ldns_rr_list_rr(q, i),
|
||||
ldns_rr_list_rr(p, i)) != 0) {
|
||||
verbose(3, "rr %d different", (int)i);
|
||||
return 0;
|
||||
}
|
||||
if(mttl && ldns_rr_ttl(ldns_rr_list_rr(q, i)) !=
|
||||
ldns_rr_ttl(ldns_rr_list_rr(p, i))) {
|
||||
verbose(3, "rr %d ttl different", (int)i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** compare two booleans */
|
||||
static int
|
||||
cmp_bool(int x, int y)
|
||||
{
|
||||
if(!x && !y) return 0;
|
||||
if(x && y) return 0;
|
||||
if(!x) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** match all of the packet */
|
||||
static int
|
||||
match_all(ldns_pkt* q, ldns_pkt* p, bool mttl)
|
||||
{
|
||||
if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p))
|
||||
{ verbose(3, "allmatch: opcode different"); return 0;}
|
||||
if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p))
|
||||
{ verbose(3, "allmatch: rcode different"); return 0;}
|
||||
if(ldns_pkt_id(q) != ldns_pkt_id(p))
|
||||
{ verbose(3, "allmatch: id different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0)
|
||||
{ verbose(3, "allmatch: qr different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0)
|
||||
{ verbose(3, "allmatch: aa different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0)
|
||||
{ verbose(3, "allmatch: tc different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0)
|
||||
{ verbose(3, "allmatch: rd different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0)
|
||||
{ verbose(3, "allmatch: cd different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0)
|
||||
{ verbose(3, "allmatch: ra different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0)
|
||||
{ verbose(3, "allmatch: ad different"); return 0;}
|
||||
if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p))
|
||||
{ verbose(3, "allmatch: qdcount different"); return 0;}
|
||||
if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p))
|
||||
{ verbose(3, "allmatch: ancount different"); return 0;}
|
||||
if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p))
|
||||
{ verbose(3, "allmatch: nscount different"); return 0;}
|
||||
if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p))
|
||||
{ verbose(3, "allmatch: arcount different"); return 0;}
|
||||
if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p), 0))
|
||||
{ verbose(3, "allmatch: qd section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p), mttl))
|
||||
{ verbose(3, "allmatch: an section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p), mttl))
|
||||
{ verbose(3, "allmatch: ar section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p), mttl))
|
||||
{ verbose(3, "allmatch: ns section different"); return 0;}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* finds entry in list, or returns NULL */
|
||||
struct entry*
|
||||
find_match(struct entry* entries, ldns_pkt* query_pkt,
|
||||
enum transport_type transport)
|
||||
{
|
||||
struct entry* p = entries;
|
||||
ldns_pkt* reply = NULL;
|
||||
for(p=entries; p; p=p->next) {
|
||||
verbose(3, "comparepkt: ");
|
||||
reply = p->reply_list->reply;
|
||||
if(p->match_opcode && ldns_pkt_get_opcode(query_pkt) !=
|
||||
ldns_pkt_get_opcode(reply)) {
|
||||
verbose(3, "bad opcode\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_qtype && get_qtype(query_pkt) != get_qtype(reply)) {
|
||||
verbose(3, "bad qtype\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_qname) {
|
||||
if(!get_owner(query_pkt) || !get_owner(reply) ||
|
||||
ldns_dname_compare(
|
||||
get_owner(query_pkt), get_owner(reply)) != 0) {
|
||||
verbose(3, "bad qname\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(p->match_subdomain) {
|
||||
if(!get_owner(query_pkt) || !get_owner(reply) ||
|
||||
(ldns_dname_compare(get_owner(query_pkt),
|
||||
get_owner(reply)) != 0 &&
|
||||
!ldns_dname_is_subdomain(
|
||||
get_owner(query_pkt), get_owner(reply))))
|
||||
{
|
||||
verbose(3, "bad subdomain\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(p->match_serial && get_serial(query_pkt) != p->ixfr_soa_serial) {
|
||||
verbose(3, "bad serial\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_do && !ldns_pkt_edns_do(query_pkt)) {
|
||||
verbose(3, "no DO bit set\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_noedns && ldns_pkt_edns(query_pkt)) {
|
||||
verbose(3, "bad; EDNS OPT present\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_transport != transport_any && p->match_transport != transport) {
|
||||
verbose(3, "bad transport\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_all && !match_all(query_pkt, reply, p->match_ttl)) {
|
||||
verbose(3, "bad allmatch\n");
|
||||
continue;
|
||||
}
|
||||
verbose(3, "match!\n");
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
adjust_packet(struct entry* match, ldns_pkt* answer_pkt, ldns_pkt* query_pkt)
|
||||
{
|
||||
/* copy & adjust packet */
|
||||
if(match->copy_id)
|
||||
ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt));
|
||||
if(match->copy_query) {
|
||||
ldns_rr_list* list = ldns_pkt_get_section_clone(query_pkt,
|
||||
LDNS_SECTION_QUESTION);
|
||||
ldns_rr_list_deep_free(ldns_pkt_question(answer_pkt));
|
||||
ldns_pkt_set_question(answer_pkt, list);
|
||||
}
|
||||
if(match->sleeptime > 0) {
|
||||
verbose(3, "sleeping for %d seconds\n", match->sleeptime);
|
||||
#ifdef HAVE_SLEEP
|
||||
sleep(match->sleeptime);
|
||||
#else
|
||||
Sleep(match->sleeptime * 1000);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses data buffer to a query, finds the correct answer
|
||||
* and calls the given function for every packet to send.
|
||||
*/
|
||||
void
|
||||
handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
|
||||
enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*),
|
||||
void* userdata, FILE* verbose_out)
|
||||
{
|
||||
ldns_status status;
|
||||
ldns_pkt *query_pkt = NULL;
|
||||
ldns_pkt *answer_pkt = NULL;
|
||||
struct reply_packet *p;
|
||||
ldns_rr *query_rr = NULL;
|
||||
uint8_t *outbuf = NULL;
|
||||
size_t answer_size = 0;
|
||||
struct entry* entry = NULL;
|
||||
ldns_rdf *stop_command = ldns_dname_new_frm_str("server.stop.");
|
||||
|
||||
status = ldns_wire2pkt(&query_pkt, inbuf, (size_t)inlen);
|
||||
if (status != LDNS_STATUS_OK) {
|
||||
verbose(1, "Got bad packet: %s\n", ldns_get_errorstr_by_id(status));
|
||||
ldns_rdf_free(stop_command);
|
||||
return;
|
||||
}
|
||||
|
||||
query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0);
|
||||
verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count), (int)ldns_pkt_id(query_pkt),
|
||||
(transport==transport_tcp)?"TCP":"UDP", (int)inlen);
|
||||
if(verbose_out) ldns_rr_print(verbose_out, query_rr);
|
||||
if(verbose_out) ldns_pkt_print(verbose_out, query_pkt);
|
||||
|
||||
if (ldns_rr_get_type(query_rr) == LDNS_RR_TYPE_TXT &&
|
||||
ldns_rr_get_class(query_rr) == LDNS_RR_CLASS_CH &&
|
||||
ldns_dname_compare(ldns_rr_owner(query_rr), stop_command) == 0) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* fill up answer packet */
|
||||
entry = find_match(entries, query_pkt, transport);
|
||||
if(!entry || !entry->reply_list) {
|
||||
verbose(1, "no answer packet for this query, no reply.\n");
|
||||
ldns_pkt_free(query_pkt);
|
||||
ldns_rdf_free(stop_command);
|
||||
return;
|
||||
}
|
||||
for(p = entry->reply_list; p; p = p->next)
|
||||
{
|
||||
verbose(3, "Answer pkt:\n");
|
||||
if (p->reply_from_hex) {
|
||||
/* try to parse the hex packet, if it can be
|
||||
* parsed, we can use adjust rules. if not,
|
||||
* send packet literally */
|
||||
status = ldns_buffer2pkt_wire(&answer_pkt, p->reply_from_hex);
|
||||
if (status == LDNS_STATUS_OK) {
|
||||
adjust_packet(entry, answer_pkt, query_pkt);
|
||||
if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
|
||||
status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
|
||||
verbose(2, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
|
||||
if (status != LDNS_STATUS_OK) {
|
||||
verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
|
||||
ldns_pkt_free(query_pkt);
|
||||
ldns_rdf_free(stop_command);
|
||||
return;
|
||||
}
|
||||
ldns_pkt_free(answer_pkt);
|
||||
answer_pkt = NULL;
|
||||
} else {
|
||||
verbose(3, "Could not parse hex data (%s), sending hex data directly.\n", ldns_get_errorstr_by_id(status));
|
||||
/* still try to adjust ID */
|
||||
answer_size = ldns_buffer_capacity(p->reply_from_hex);
|
||||
outbuf = LDNS_XMALLOC(uint8_t, answer_size);
|
||||
memcpy(outbuf, ldns_buffer_begin(p->reply_from_hex), answer_size);
|
||||
if(entry->copy_id) {
|
||||
ldns_write_uint16(outbuf,
|
||||
ldns_pkt_id(query_pkt));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
answer_pkt = ldns_pkt_clone(p->reply);
|
||||
adjust_packet(entry, answer_pkt, query_pkt);
|
||||
if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
|
||||
status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
|
||||
verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
|
||||
if (status != LDNS_STATUS_OK) {
|
||||
verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
|
||||
ldns_pkt_free(query_pkt);
|
||||
ldns_rdf_free(stop_command);
|
||||
return;
|
||||
}
|
||||
ldns_pkt_free(answer_pkt);
|
||||
answer_pkt = NULL;
|
||||
}
|
||||
if(p->packet_sleep) {
|
||||
verbose(3, "sleeping for next packet %d secs\n",
|
||||
p->packet_sleep);
|
||||
#ifdef HAVE_SLEEP
|
||||
sleep(p->packet_sleep);
|
||||
#else
|
||||
Sleep(p->packet_sleep * 1000);
|
||||
#endif
|
||||
verbose(3, "wakeup for next packet "
|
||||
"(slept %d secs)\n", p->packet_sleep);
|
||||
}
|
||||
sendfunc(outbuf, answer_size, userdata);
|
||||
LDNS_FREE(outbuf);
|
||||
outbuf = NULL;
|
||||
answer_size = 0;
|
||||
}
|
||||
ldns_pkt_free(query_pkt);
|
||||
ldns_rdf_free(stop_command);
|
||||
}
|
||||
|
||||
/** delete the list of reply packets */
|
||||
void delete_replylist(struct reply_packet* replist)
|
||||
{
|
||||
struct reply_packet *p=replist, *np;
|
||||
while(p) {
|
||||
np = p->next;
|
||||
ldns_pkt_free(p->reply);
|
||||
ldns_buffer_free(p->reply_from_hex);
|
||||
free(p);
|
||||
p=np;
|
||||
}
|
||||
}
|
||||
|
||||
void delete_entry(struct entry* list)
|
||||
{
|
||||
struct entry *p=list, *np;
|
||||
while(p) {
|
||||
np = p->next;
|
||||
delete_replylist(p->reply_list);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
}
|
@ -43,7 +43,6 @@
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <ldns/ldns.h>
|
||||
#include <signal.h>
|
||||
#include "util/log.h"
|
||||
#include "util/locks.h"
|
||||
@ -51,6 +50,10 @@
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/wire2str.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
/** usage information for perf */
|
||||
static void usage(char* nm)
|
||||
@ -434,11 +437,10 @@ perfendstats(struct perfinfo* info)
|
||||
for(i=0; i<(int)(sizeof(info->by_rcode)/sizeof(size_t)); i++)
|
||||
{
|
||||
if(info->by_rcode[i] > 0) {
|
||||
char rc[16];
|
||||
ldns_wire2str_rcode_buf(i, rc, sizeof(rc));
|
||||
printf("%d(%5s): %u replies\n",
|
||||
i, ldns_lookup_by_id(ldns_rcodes, i)?
|
||||
ldns_lookup_by_id(ldns_rcodes,
|
||||
i)->name:"??",
|
||||
(unsigned)info->by_rcode[i]);
|
||||
i, rc, (unsigned)info->by_rcode[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -465,7 +467,6 @@ qlist_parse_line(ldns_buffer* buf, char* p)
|
||||
int r;
|
||||
int rec = 1, edns = 0;
|
||||
struct query_info qinfo;
|
||||
ldns_rdf* rdf;
|
||||
nm[0] = 0; cl[0] = 0; tp[0] = 0; fl[0] = 0;
|
||||
r = sscanf(p, " %1023s %1023s %1023s %1023s", nm, cl, tp, fl);
|
||||
if(r != 3 && r != 4)
|
||||
@ -483,11 +484,9 @@ qlist_parse_line(ldns_buffer* buf, char* p)
|
||||
else if(fl[0] == 'E') edns = 1;
|
||||
if((fl[0] == '+' || fl[0] == '-') && fl[1] == 'E')
|
||||
edns = 1;
|
||||
rdf = ldns_dname_new_frm_str(nm);
|
||||
if(!rdf)
|
||||
qinfo.qname = ldns_str2wire_dname(nm, &qinfo.qname_len);
|
||||
if(!qinfo.qname)
|
||||
return 0;
|
||||
qinfo.qname = ldns_rdf_data(rdf);
|
||||
qinfo.qname_len = ldns_rdf_size(rdf);
|
||||
qinfo_query_encode(buf, &qinfo);
|
||||
ldns_buffer_write_u16_at(buf, 0, 0); /* zero ID */
|
||||
if(rec) LDNS_RD_SET(ldns_buffer_begin(buf));
|
||||
@ -500,7 +499,7 @@ qlist_parse_line(ldns_buffer* buf, char* p)
|
||||
ed.bits = EDNS_DO;
|
||||
attach_edns_record(buf, &ed);
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
free(qinfo.qname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,13 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/log.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "testcode/readhex.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/parseutil.h"
|
||||
|
||||
/** usage information for pktview */
|
||||
static void usage(char* argv[])
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include <ctype.h>
|
||||
#include "testcode/readhex.h"
|
||||
#include "util/log.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/parseutil.h"
|
||||
|
||||
/** skip whitespace */
|
||||
static void
|
||||
|
@ -40,13 +40,13 @@
|
||||
|
||||
#ifndef TESTCODE_READHEX_H
|
||||
#define TESTCODE_READHEX_H
|
||||
#include <ldns/buffer.h>
|
||||
struct ldns_buffer;
|
||||
|
||||
/**
|
||||
* Helper to convert hex string to packet buffer.
|
||||
* @param pkt: buffer to put result in.
|
||||
* @param hex: string of hex data. Spaces and ';...' comments are skipped.
|
||||
*/
|
||||
void hex_to_buf(ldns_buffer* pkt, const char* hex);
|
||||
void hex_to_buf(struct ldns_buffer* pkt, const char* hex);
|
||||
|
||||
#endif /* TESTCODE_READHEX_H */
|
||||
|
@ -42,12 +42,15 @@
|
||||
#include "config.h"
|
||||
/* for strtod prototype */
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
#include "testcode/replay.h"
|
||||
#include "testcode/ldns-testpkts.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "testcode/fake_event.h"
|
||||
#include "ldns/str2wire.h"
|
||||
|
||||
/** max length of lines in file */
|
||||
#define MAX_LINE_LEN 10240
|
||||
@ -138,16 +141,15 @@ strip_end_white(char* p)
|
||||
* @param remain: Rest of line (after RANGE keyword).
|
||||
* @param in: file to read from.
|
||||
* @param name: name to print in errors.
|
||||
* @param lineno: incremented as lines are read.
|
||||
* @param pstate: read state structure with
|
||||
* with lineno : incremented as lines are read.
|
||||
* ttl, origin, prev for readentry.
|
||||
* @param line: line buffer.
|
||||
* @param ttl: for readentry
|
||||
* @param or: for readentry
|
||||
* @param prev: for readentry
|
||||
* @return: range object to add to list, or NULL on error.
|
||||
*/
|
||||
static struct replay_range*
|
||||
replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
char* line, uint32_t* ttl, ldns_rdf** or, ldns_rdf** prev)
|
||||
replay_range_read(char* remain, FILE* in, const char* name,
|
||||
struct ldns_file_parse_state* pstate, char* line)
|
||||
{
|
||||
struct replay_range* rng = (struct replay_range*)malloc(
|
||||
sizeof(struct replay_range));
|
||||
@ -166,7 +168,7 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
/* read entries */
|
||||
pos = ftello(in);
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
(*lineno)++;
|
||||
pstate->lineno++;
|
||||
parse = line;
|
||||
while(isspace((int)*parse))
|
||||
parse++;
|
||||
@ -180,7 +182,7 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
strip_end_white(parse);
|
||||
if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen)) {
|
||||
log_err("Line %d: could not read ADDRESS: %s",
|
||||
*lineno, parse);
|
||||
pstate->lineno, parse);
|
||||
free(rng);
|
||||
return NULL;
|
||||
}
|
||||
@ -191,11 +193,11 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
return rng;
|
||||
}
|
||||
/* set position before line; read entry */
|
||||
(*lineno)--;
|
||||
pstate->lineno--;
|
||||
fseeko(in, pos, SEEK_SET);
|
||||
entry = read_entry(in, name, lineno, ttl, or, prev, 1);
|
||||
entry = read_entry(in, name, pstate, 1);
|
||||
if(!entry)
|
||||
fatal_exit("%d: bad entry", *lineno);
|
||||
fatal_exit("%d: bad entry", pstate->lineno);
|
||||
entry->next = NULL;
|
||||
if(last)
|
||||
last->next = entry;
|
||||
@ -258,15 +260,13 @@ read_assign_step(char* remain, struct replay_moment* mom)
|
||||
* @param remain: Rest of line (after STEP keyword).
|
||||
* @param in: file to read from.
|
||||
* @param name: name to print in errors.
|
||||
* @param lineno: incremented as lines are read.
|
||||
* @param ttl: for readentry
|
||||
* @param or: for readentry
|
||||
* @param prev: for readentry
|
||||
* @param pstate: with lineno, ttl, origin, prev for parse state.
|
||||
* lineno is incremented.
|
||||
* @return: range object to add to list, or NULL on error.
|
||||
*/
|
||||
static struct replay_moment*
|
||||
replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
uint32_t* ttl, ldns_rdf** or, ldns_rdf** prev)
|
||||
replay_moment_read(char* remain, FILE* in, const char* name,
|
||||
struct ldns_file_parse_state* pstate)
|
||||
{
|
||||
struct replay_moment* mom = (struct replay_moment*)malloc(
|
||||
sizeof(struct replay_moment));
|
||||
@ -276,7 +276,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
return NULL;
|
||||
memset(mom, 0, sizeof(*mom));
|
||||
if(sscanf(remain, " %d%n", &mom->time_step, &skip) != 1) {
|
||||
log_err("%d: cannot read number: %s", *lineno, remain);
|
||||
log_err("%d: cannot read number: %s", pstate->lineno, remain);
|
||||
free(mom);
|
||||
return NULL;
|
||||
}
|
||||
@ -322,7 +322,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
remain[strlen(remain)-1] = 0;
|
||||
mom->autotrust_id = strdup(remain);
|
||||
if(!mom->autotrust_id) fatal_exit("out of memory");
|
||||
read_file_content(in, lineno, mom);
|
||||
read_file_content(in, &pstate->lineno, mom);
|
||||
} else if(parse_keyword(&remain, "ERROR")) {
|
||||
mom->evt_type = repevt_error;
|
||||
} else if(parse_keyword(&remain, "TRAFFIC")) {
|
||||
@ -357,7 +357,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
if(!mom->string) fatal_exit("out of memory");
|
||||
if(!mom->variable) fatal_exit("out of memory");
|
||||
} else {
|
||||
log_err("%d: unknown event type %s", *lineno, remain);
|
||||
log_err("%d: unknown event type %s", pstate->lineno, remain);
|
||||
free(mom);
|
||||
return NULL;
|
||||
}
|
||||
@ -370,7 +370,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
remain[strlen(remain)-1] = 0;
|
||||
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
|
||||
log_err("line %d: could not parse ADDRESS: %s",
|
||||
*lineno, remain);
|
||||
pstate->lineno, remain);
|
||||
free(mom);
|
||||
return NULL;
|
||||
}
|
||||
@ -381,7 +381,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
sec = strtod(remain, &remain);
|
||||
if(sec == 0. && errno != 0) {
|
||||
log_err("line %d: could not parse ELAPSE: %s (%s)",
|
||||
*lineno, remain, strerror(errno));
|
||||
pstate->lineno, remain, strerror(errno));
|
||||
free(mom);
|
||||
return NULL;
|
||||
}
|
||||
@ -393,7 +393,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
}
|
||||
|
||||
if(readentry) {
|
||||
mom->match = read_entry(in, name, lineno, ttl, or, prev, 1);
|
||||
mom->match = read_entry(in, name, pstate, 1);
|
||||
if(!mom->match) {
|
||||
free(mom);
|
||||
return NULL;
|
||||
@ -432,13 +432,15 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
|
||||
char line[MAX_LINE_LEN];
|
||||
char *parse;
|
||||
struct replay_scenario* scen = NULL;
|
||||
uint32_t ttl = 3600;
|
||||
ldns_rdf* or = NULL;
|
||||
ldns_rdf* prev = NULL;
|
||||
struct ldns_file_parse_state pstate;
|
||||
line[MAX_LINE_LEN-1]=0;
|
||||
memset(&pstate, 0, sizeof(pstate));
|
||||
pstate.default_ttl = 3600;
|
||||
pstate.lineno = *lineno;
|
||||
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
parse=line;
|
||||
pstate.lineno++;
|
||||
(*lineno)++;
|
||||
while(isspace((int)*parse))
|
||||
parse++;
|
||||
@ -456,16 +458,18 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
|
||||
fatal_exit("%d: expected SCENARIO", *lineno);
|
||||
if(parse_keyword(&parse, "RANGE_BEGIN")) {
|
||||
struct replay_range* newr = replay_range_read(parse,
|
||||
in, name, lineno, line, &ttl, &or, &prev);
|
||||
in, name, &pstate, line);
|
||||
if(!newr)
|
||||
fatal_exit("%d: bad range", *lineno);
|
||||
fatal_exit("%d: bad range", pstate.lineno);
|
||||
*lineno = pstate.lineno;
|
||||
newr->next_range = scen->range_list;
|
||||
scen->range_list = newr;
|
||||
} else if(parse_keyword(&parse, "STEP")) {
|
||||
struct replay_moment* mom = replay_moment_read(parse,
|
||||
in, name, lineno, &ttl, &or, &prev);
|
||||
in, name, &pstate);
|
||||
if(!mom)
|
||||
fatal_exit("%d: bad moment", *lineno);
|
||||
fatal_exit("%d: bad moment", pstate.lineno);
|
||||
*lineno = pstate.lineno;
|
||||
if(scen->mom_last &&
|
||||
scen->mom_last->time_step >= mom->time_step)
|
||||
fatal_exit("%d: time goes backwards", *lineno);
|
||||
@ -481,13 +485,9 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
|
||||
p = p->mom_next;
|
||||
}
|
||||
log_info("Scenario has %d steps", num);
|
||||
ldns_rdf_deep_free(or);
|
||||
ldns_rdf_deep_free(prev);
|
||||
return scen;
|
||||
}
|
||||
}
|
||||
ldns_rdf_deep_free(or);
|
||||
ldns_rdf_deep_free(prev);
|
||||
replay_scenario_delete(scen);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@
|
||||
#ifndef TESTCODE_REPLAY_H
|
||||
#define TESTCODE_REPLAY_H
|
||||
#include "util/netevent.h"
|
||||
#include "testcode/ldns-testpkts.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "util/rbtree.h"
|
||||
struct replay_answer;
|
||||
struct replay_moment;
|
||||
@ -138,6 +138,7 @@ struct fake_pending;
|
||||
struct fake_timer;
|
||||
struct replay_var;
|
||||
struct infra_cache;
|
||||
struct ldns_buffer;
|
||||
|
||||
/**
|
||||
* A replay scenario.
|
||||
@ -217,12 +218,6 @@ struct replay_moment {
|
||||
/** length of addr, if 0, then any address will do */
|
||||
socklen_t addrlen;
|
||||
|
||||
/** what pending query should timeout or is answered. or
|
||||
* NULL for last sent query.
|
||||
* Unused at this time.
|
||||
*/
|
||||
ldns_rr* qname;
|
||||
|
||||
/** macro name, for assign. */
|
||||
char* variable;
|
||||
/** string argument, for assign. */
|
||||
@ -318,7 +313,7 @@ struct replay_runtime {
|
||||
*/
|
||||
struct fake_pending {
|
||||
/** what is important only that we remember the query, copied here. */
|
||||
ldns_buffer* buffer;
|
||||
struct ldns_buffer* buffer;
|
||||
/** and to what address this is sent to. */
|
||||
struct sockaddr_storage addr;
|
||||
/** len of addr */
|
||||
@ -339,7 +334,8 @@ struct fake_pending {
|
||||
/** next in pending list */
|
||||
struct fake_pending* next;
|
||||
/** the buffer parsed into a ldns_pkt */
|
||||
ldns_pkt* pkt;
|
||||
uint8_t* pkt;
|
||||
size_t pkt_len;
|
||||
/** by what transport was the query sent out */
|
||||
enum transport_type transport;
|
||||
/** if this is a serviced query */
|
||||
@ -357,7 +353,8 @@ struct replay_answer {
|
||||
/** reply information */
|
||||
struct comm_reply repinfo;
|
||||
/** the answer preparsed as ldns pkt */
|
||||
ldns_pkt* pkt;
|
||||
uint8_t* pkt;
|
||||
size_t pkt_len;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,9 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define DNSKEY_BIT_ZSK 0x0100
|
||||
|
||||
/**
|
||||
* Key settings
|
||||
@ -74,12 +74,47 @@ usage()
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static time_t
|
||||
convert_timeval(const char* str)
|
||||
{
|
||||
time_t t;
|
||||
struct tm tm;
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
if(strlen(str) < 14)
|
||||
return 0;
|
||||
if(sscanf(str, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon,
|
||||
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6)
|
||||
return 0;
|
||||
tm.tm_year -= 1900;
|
||||
tm.tm_mon--;
|
||||
/* Check values */
|
||||
if (tm.tm_year < 70) return 0;
|
||||
if (tm.tm_mon < 0 || tm.tm_mon > 11) return 0;
|
||||
if (tm.tm_mday < 1 || tm.tm_mday > 31) return 0;
|
||||
if (tm.tm_hour < 0 || tm.tm_hour > 23) return 0;
|
||||
if (tm.tm_min < 0 || tm.tm_min > 59) return 0;
|
||||
if (tm.tm_sec < 0 || tm.tm_sec > 59) return 0;
|
||||
/* call ldns conversion function */
|
||||
t = ldns_mktime_from_utc(&tm);
|
||||
return t;
|
||||
}
|
||||
|
||||
static void fatal_exit(const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
printf("fatal exit: ");
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** read expi ince keytag owner from cmdline */
|
||||
static void
|
||||
parse_cmdline(char *argv[], struct keysets* s)
|
||||
{
|
||||
s->expi = cfg_convert_timeval(argv[1]);
|
||||
s->incep = cfg_convert_timeval(argv[2]);
|
||||
s->expi = convert_timeval(argv[1]);
|
||||
s->incep = convert_timeval(argv[2]);
|
||||
s->keytag = (uint16_t)atoi(argv[3]);
|
||||
s->owner = argv[4];
|
||||
s->flags = DNSKEY_BIT_ZSK; /* to enforce signing */
|
||||
@ -118,7 +153,7 @@ read_keys(int num, char* names[], struct keysets* set)
|
||||
ldns_key_set_flags(k, set->flags);
|
||||
ldns_key_set_keytag(k, set->keytag);
|
||||
b = ldns_key_list_push_key(keys, k);
|
||||
log_assert(b);
|
||||
assert(b);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
@ -151,7 +186,7 @@ read_rrs(FILE* in)
|
||||
fatal_exit("parse error in line %d: %s", line_nr,
|
||||
ldns_get_errorstr_by_id(s));
|
||||
b = ldns_rr_list_push_rr(list, rr);
|
||||
log_assert(b);
|
||||
assert(b);
|
||||
}
|
||||
printf("read %d lines\n", line_nr);
|
||||
|
||||
@ -185,7 +220,7 @@ process_keys(int argc, char* argv[])
|
||||
ldns_rr_list* rrs;
|
||||
ldns_key_list* keys;
|
||||
struct keysets settings;
|
||||
log_assert(argc == 6);
|
||||
assert(argc == 6);
|
||||
|
||||
parse_cmdline(argv, &settings);
|
||||
keys = read_keys(1, argv+5, &settings);
|
||||
@ -208,7 +243,7 @@ process_nsec3(int argc, char* argv[])
|
||||
if(status != LDNS_STATUS_OK)
|
||||
fatal_exit("Could not parse salt %s: %s", argv[5],
|
||||
ldns_get_errorstr_by_id(status));
|
||||
log_assert(argc == 6);
|
||||
assert(argc == 6);
|
||||
while(fgets(line, (int)sizeof(line), stdin)) {
|
||||
if(strlen(line) > 0)
|
||||
line[strlen(line)-1] = 0; /* remove trailing newline */
|
||||
@ -237,7 +272,6 @@ process_nsec3(int argc, char* argv[])
|
||||
/** main program */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
log_init(NULL, 0, NULL);
|
||||
if(argc != 6) {
|
||||
usage();
|
||||
}
|
||||
|
@ -43,7 +43,6 @@
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <ldns/ldns.h>
|
||||
#include <signal.h>
|
||||
#include "util/locks.h"
|
||||
#include "util/log.h"
|
||||
@ -52,6 +51,11 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include "ldns/wire2str.h"
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifndef PF_INET6
|
||||
@ -112,18 +116,13 @@ write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id,
|
||||
const char* strname, const char* strtype, const char* strclass)
|
||||
{
|
||||
struct query_info qinfo;
|
||||
ldns_rdf* rdf;
|
||||
uint16_t len;
|
||||
/* qname */
|
||||
rdf = ldns_dname_new_frm_str(strname);
|
||||
if(!rdf) {
|
||||
qinfo.qname = ldns_str2wire_dname(strname, &qinfo.qname_len);
|
||||
if(!qinfo.qname) {
|
||||
printf("cannot parse query name: '%s'\n", strname);
|
||||
exit(1);
|
||||
}
|
||||
qinfo.qname = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
|
||||
if(!qinfo.qname) fatal_exit("out of memory");
|
||||
(void)dname_count_size_labels(qinfo.qname, &qinfo.qname_len);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
|
||||
/* qtype and qclass */
|
||||
qinfo.qtype = ldns_get_rr_type_by_name(strtype);
|
||||
@ -192,9 +191,8 @@ write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id,
|
||||
static void
|
||||
recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf)
|
||||
{
|
||||
char* pktstr;
|
||||
uint16_t len;
|
||||
ldns_pkt* pkt;
|
||||
ldns_status status;
|
||||
if(!udp) {
|
||||
if(ssl) {
|
||||
if(SSL_read(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
|
||||
@ -256,15 +254,18 @@ recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf)
|
||||
printf("\nnext received packet\n");
|
||||
log_buf(0, "data", buf);
|
||||
|
||||
status = ldns_wire2pkt(&pkt, ldns_buffer_begin(buf), len);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
printf("could not parse incoming packet: %s\n",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
log_buf(0, "data was", buf);
|
||||
exit(1);
|
||||
pktstr = ldns_wire2str_pkt(ldns_buffer_begin(buf), len);
|
||||
printf("%s", pktstr);
|
||||
free(pktstr);
|
||||
}
|
||||
|
||||
static int get_random(void)
|
||||
{
|
||||
int r;
|
||||
if (RAND_bytes((unsigned char*)&r, (int)sizeof(r)) == 1) {
|
||||
return r;
|
||||
}
|
||||
ldns_pkt_print(stdout, pkt);
|
||||
ldns_pkt_free(pkt);
|
||||
return (int)random();
|
||||
}
|
||||
|
||||
/** send the TCP queries and print answers */
|
||||
@ -305,7 +306,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
|
||||
}
|
||||
for(i=0; i<num; i+=3) {
|
||||
printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
|
||||
write_q(fd, udp, ssl, buf, ldns_get_random(), qs[i],
|
||||
write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
|
||||
qs[i+1], qs[i+2]);
|
||||
/* print at least one result */
|
||||
if(!noanswer)
|
||||
|
@ -39,11 +39,13 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "testcode/ldns-testpkts.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "testcode/replay.h"
|
||||
#include "testcode/fake_event.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "util/config_file.h"
|
||||
#include "ldns/keyraw.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/** signal that this is a testbound compile */
|
||||
#define unbound_testbound 1
|
||||
|
1427
testcode/testpkts.c
Normal file
1427
testcode/testpkts.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ldns-testpkts. Data file parse for test packets, and query matching.
|
||||
* testpkts. Data file parse for test packets, and query matching.
|
||||
*
|
||||
* Data storage for specially crafted replies for testing purposes.
|
||||
*
|
||||
@ -7,8 +7,10 @@
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
#ifndef LDNS_TESTPKTS_H
|
||||
#define LDNS_TESTPKTS_H
|
||||
#ifndef TESTPKTS_H
|
||||
#define TESTPKTS_H
|
||||
struct ldns_buffer;
|
||||
struct ldns_file_parse_state;
|
||||
|
||||
/**
|
||||
* \file
|
||||
@ -131,8 +133,6 @@ ENTRY_END
|
||||
void verbose(int level, char* format, ...); output function.
|
||||
*/
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
/** Type of transport, since some entries match based on UDP or TCP of query */
|
||||
enum transport_type {transport_any = 0, transport_udp, transport_tcp };
|
||||
|
||||
@ -141,9 +141,11 @@ struct reply_packet {
|
||||
/** next in list of reply packets, for TCP multiple pkts on wire */
|
||||
struct reply_packet* next;
|
||||
/** the reply pkt */
|
||||
ldns_pkt* reply;
|
||||
uint8_t* reply_pkt;
|
||||
/** length of reply pkt */
|
||||
size_t reply_len;
|
||||
/** or reply pkt in hex if not parsable */
|
||||
ldns_buffer* reply_from_hex;
|
||||
struct ldns_buffer* reply_from_hex;
|
||||
/** seconds to sleep before giving packet */
|
||||
unsigned int packet_sleep;
|
||||
};
|
||||
@ -154,23 +156,23 @@ struct entry {
|
||||
/* match */
|
||||
/* How to match an incoming query with this canned reply */
|
||||
/** match query opcode with answer opcode */
|
||||
bool match_opcode;
|
||||
uint8_t match_opcode;
|
||||
/** match qtype with answer qtype */
|
||||
bool match_qtype;
|
||||
uint8_t match_qtype;
|
||||
/** match qname with answer qname */
|
||||
bool match_qname;
|
||||
uint8_t match_qname;
|
||||
/** match qname as subdomain of answer qname */
|
||||
bool match_subdomain;
|
||||
uint8_t match_subdomain;
|
||||
/** match SOA serial number, from auth section */
|
||||
bool match_serial;
|
||||
uint8_t match_serial;
|
||||
/** match all of the packet */
|
||||
bool match_all;
|
||||
uint8_t match_all;
|
||||
/** match ttls in the packet */
|
||||
bool match_ttl;
|
||||
uint8_t match_ttl;
|
||||
/** match DO bit */
|
||||
bool match_do;
|
||||
uint8_t match_do;
|
||||
/** match absence of EDNS OPT record in query */
|
||||
bool match_noedns;
|
||||
uint8_t match_noedns;
|
||||
/** match query serial with this value. */
|
||||
uint32_t ixfr_soa_serial;
|
||||
/** match on UDP/TCP */
|
||||
@ -181,9 +183,9 @@ struct entry {
|
||||
|
||||
/** how to adjust the reply packet */
|
||||
/** copy over the ID from the query into the answer */
|
||||
bool copy_id;
|
||||
uint8_t copy_id;
|
||||
/** copy the query nametypeclass from query into the answer */
|
||||
bool copy_query;
|
||||
uint8_t copy_query;
|
||||
/** in seconds */
|
||||
unsigned int sleeptime;
|
||||
|
||||
@ -211,32 +213,39 @@ void delete_entry(struct entry* list);
|
||||
* Read one entry from the data file.
|
||||
* @param in: file to read from. Filepos must be at the start of a new line.
|
||||
* @param name: name of the file for prettier errors.
|
||||
* @param lineno: line number in file, incremented as lines are read.
|
||||
* for prettier errors.
|
||||
* @param default_ttl: on first call set to default TTL for entries,
|
||||
* later it stores the $TTL value last seen. Try 3600 first call.
|
||||
* @param origin: domain name for origin appending. Can be &NULL on first call.
|
||||
* later it stores the $ORIGIN value last seen. Often &NULL or the zone
|
||||
* name on first call.
|
||||
* @param prev_rr: previous rr name for correcter parsing. &NULL on first call.
|
||||
* @param pstate: file parse state with lineno, default_ttl,
|
||||
* oirigin and prev_rr name.
|
||||
* @param skip_whitespace: skip leftside whitespace.
|
||||
* @return: The entry read (malloced) or NULL if no entry could be read.
|
||||
*/
|
||||
struct entry* read_entry(FILE* in, const char* name, int *lineno,
|
||||
uint32_t* default_ttl, ldns_rdf** origin, ldns_rdf** prev_rr,
|
||||
int skip_whitespace);
|
||||
struct entry* read_entry(FILE* in, const char* name,
|
||||
struct ldns_file_parse_state* pstate, int skip_whitespace);
|
||||
|
||||
/**
|
||||
* finds entry in list, or returns NULL.
|
||||
*/
|
||||
struct entry* find_match(struct entry* entries, ldns_pkt* query_pkt,
|
||||
enum transport_type transport);
|
||||
struct entry* find_match(struct entry* entries, uint8_t* query_pkt,
|
||||
size_t query_pkt_len, enum transport_type transport);
|
||||
|
||||
/**
|
||||
* copy & adjust packet
|
||||
* match two packets, all must match
|
||||
* @param q: packet 1
|
||||
* @param qlen: length of q.
|
||||
* @param p: packet 2
|
||||
* @param plen: length of p.
|
||||
* @param mttl: if true, ttls must match, if false, ttls do not need to match
|
||||
* @param noloc: if true, rrs may be reordered in their packet-section.
|
||||
* rrs are then matches without location of the rr being important.
|
||||
* @return true if matched.
|
||||
*/
|
||||
void adjust_packet(struct entry* match, ldns_pkt* answer_pkt,
|
||||
ldns_pkt* query_pkt);
|
||||
int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
int noloc);
|
||||
|
||||
/**
|
||||
* copy & adjust packet, mallocs a copy.
|
||||
*/
|
||||
void adjust_packet(struct entry* match, uint8_t** answer_pkt,
|
||||
size_t* answer_pkt_len, uint8_t* query_pkt, size_t query_pkt_len);
|
||||
|
||||
/**
|
||||
* Parses data buffer to a query, finds the correct answer
|
||||
@ -256,4 +265,4 @@ void handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries,
|
||||
void (*sendfunc)(uint8_t*, size_t, void*), void* userdata,
|
||||
FILE* verbose_out);
|
||||
|
||||
#endif /* LDNS_TESTPKTS_H */
|
||||
#endif /* TESTPKTS_H */
|
@ -39,11 +39,12 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ldns/rr.h>
|
||||
#include "util/log.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "validator/val_anchor.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/rrdef.h"
|
||||
|
||||
/** test empty set */
|
||||
static void
|
||||
|
@ -39,25 +39,24 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/host2wire.h>
|
||||
#include "util/log.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/str2wire.h"
|
||||
|
||||
/** put dname into buffer */
|
||||
static ldns_buffer*
|
||||
dname_to_buf(ldns_buffer* b, const char* str)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
ldns_status status;
|
||||
int e;
|
||||
size_t len = ldns_buffer_capacity(b);
|
||||
ldns_buffer_clear(b);
|
||||
rdf = ldns_dname_new_frm_str(str);
|
||||
status = ldns_dname2buffer_wire(b, rdf);
|
||||
if(status != LDNS_STATUS_OK)
|
||||
e = ldns_str2wire_dname_buf(str, ldns_buffer_begin(b), &len);
|
||||
if(e != 0)
|
||||
fatal_exit("%s ldns: %s", __func__,
|
||||
ldns_get_errorstr_by_id(status));
|
||||
ldns_rdf_deep_free(rdf);
|
||||
ldns_get_errorstr_parse(e));
|
||||
ldns_buffer_set_position(b, len);
|
||||
ldns_buffer_flip(b);
|
||||
return b;
|
||||
}
|
||||
|
@ -61,7 +61,8 @@
|
||||
#include "nss.h"
|
||||
#endif
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
#include "ldns/rrdef.h"
|
||||
#include "ldns/keyraw.h"
|
||||
#include "util/log.h"
|
||||
#include "testcode/unitmain.h"
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include <sys/time.h>
|
||||
#include "util/log.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "util/data/msgparse.h"
|
||||
@ -50,6 +50,10 @@
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "testcode/readhex.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include "ldns/wire2str.h"
|
||||
|
||||
/** verbose message parse unit test */
|
||||
static int vbmp = 0;
|
||||
@ -62,122 +66,10 @@ static int check_rrsigs = 0;
|
||||
/** do not check buffer sameness */
|
||||
static int check_nosameness = 0;
|
||||
|
||||
/** match two rr lists */
|
||||
static int
|
||||
match_list(ldns_rr_list* q, ldns_rr_list *p)
|
||||
{
|
||||
size_t i;
|
||||
if(ldns_rr_list_rr_count(q) != ldns_rr_list_rr_count(p)) {
|
||||
verbose(3, "rrlistcount different %d %d",
|
||||
(int)ldns_rr_list_rr_count(q),
|
||||
(int)ldns_rr_list_rr_count(p));
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<ldns_rr_list_rr_count(q); i++)
|
||||
{
|
||||
if(matches_nolocation) {
|
||||
if(!ldns_rr_list_contains_rr(p, ldns_rr_list_rr(q, i)))
|
||||
{
|
||||
verbose(3, "rr %u not found", (unsigned)i);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(ldns_rr_compare(ldns_rr_list_rr(q, i),
|
||||
ldns_rr_list_rr(p, i)) != 0) {
|
||||
verbose(3, "rr %u different", (unsigned)i);
|
||||
return 0;
|
||||
}
|
||||
/* and check the ttl */
|
||||
if(ldns_rr_ttl(ldns_rr_list_rr(q, i)) !=
|
||||
ldns_rr_ttl(ldns_rr_list_rr(p, i))) {
|
||||
verbose(3, "rr %u ttl different", (unsigned)i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** match edns sections */
|
||||
static int
|
||||
match_edns(ldns_pkt* q, ldns_pkt* p)
|
||||
{
|
||||
if(ldns_pkt_edns_udp_size(q) != ldns_pkt_edns_udp_size(p))
|
||||
return 0;
|
||||
if(ldns_pkt_edns_extended_rcode(q) != ldns_pkt_edns_extended_rcode(p))
|
||||
return 0;
|
||||
if(ldns_pkt_edns_version(q) != ldns_pkt_edns_version(p))
|
||||
return 0;
|
||||
if(ldns_pkt_edns_do(q) != ldns_pkt_edns_do(p))
|
||||
return 0;
|
||||
if(ldns_pkt_edns_z(q) != ldns_pkt_edns_z(p))
|
||||
return 0;
|
||||
if(ldns_rdf_compare(ldns_pkt_edns_data(q), ldns_pkt_edns_data(p)) != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** compare two booleans */
|
||||
static int
|
||||
cmp_bool(int x, int y)
|
||||
{
|
||||
if(!x && !y) return 0;
|
||||
if(x && y) return 0;
|
||||
if(!x) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** match all of the packet */
|
||||
static int
|
||||
match_all(ldns_pkt* q, ldns_pkt* p)
|
||||
{
|
||||
if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p))
|
||||
{ verbose(3, "allmatch: opcode different"); return 0;}
|
||||
if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p))
|
||||
{ verbose(3, "allmatch: rcode different"); return 0;}
|
||||
if(ldns_pkt_id(q) != ldns_pkt_id(p))
|
||||
{ verbose(3, "allmatch: id different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0)
|
||||
{ verbose(3, "allmatch: qr different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0)
|
||||
{ verbose(3, "allmatch: aa different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0)
|
||||
{ verbose(3, "allmatch: tc different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0)
|
||||
{ verbose(3, "allmatch: rd different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0)
|
||||
{ verbose(3, "allmatch: cd different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0)
|
||||
{ verbose(3, "allmatch: ra different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0)
|
||||
{ verbose(3, "allmatch: ad different"); return 0;}
|
||||
if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p))
|
||||
{ verbose(3, "allmatch: qdcount different"); return 0;}
|
||||
if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p))
|
||||
{ verbose(3, "allmatch: ancount different"); return 0;}
|
||||
if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p))
|
||||
{ verbose(3, "allmatch: nscount different"); return 0;}
|
||||
if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p))
|
||||
{ verbose(3, "allmatch: arcount different"); return 0;}
|
||||
if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p)))
|
||||
{ verbose(3, "allmatch: qd section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p)))
|
||||
{ verbose(3, "allmatch: an section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p)))
|
||||
{ verbose(3, "allmatch: ns section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p)))
|
||||
{ verbose(3, "allmatch: ar section different"); return 0;}
|
||||
if(!match_edns(q, p))
|
||||
{ verbose(3, "edns different."); return 0;}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if buffers contain the same packet */
|
||||
static int
|
||||
test_buffers(ldns_buffer* pkt, ldns_buffer* out)
|
||||
{
|
||||
ldns_pkt* p1=0, *p2=0;
|
||||
ldns_status s1, s2;
|
||||
/* check binary same */
|
||||
if(ldns_buffer_limit(pkt) == ldns_buffer_limit(out) &&
|
||||
memcmp(ldns_buffer_begin(pkt), ldns_buffer_begin(out),
|
||||
@ -210,32 +102,42 @@ test_buffers(ldns_buffer* pkt, ldns_buffer* out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if it 'means the same' */
|
||||
s1 = ldns_buffer2pkt_wire(&p1, pkt);
|
||||
s2 = ldns_buffer2pkt_wire(&p2, out);
|
||||
if(vbmp) {
|
||||
char* s1, *s2;
|
||||
log_buf(0, "orig in hex", pkt);
|
||||
log_buf(0, "unbound out in hex", out);
|
||||
printf("\npacket from unbound (%d):\n",
|
||||
(int)ldns_buffer_limit(out));
|
||||
ldns_pkt_print(stdout, p2);
|
||||
s1 = ldns_wire2str_pkt(ldns_buffer_begin(out),
|
||||
ldns_buffer_limit(out));
|
||||
printf("%s\n", s1?s1:"null");
|
||||
free(s1);
|
||||
|
||||
printf("\npacket original (%d):\n",
|
||||
(int)ldns_buffer_limit(pkt));
|
||||
ldns_pkt_print(stdout, p1);
|
||||
s2 = ldns_wire2str_pkt(ldns_buffer_begin(pkt),
|
||||
ldns_buffer_limit(pkt));
|
||||
printf("%s\n", s2?s2:"null");
|
||||
free(s2);
|
||||
printf("\n");
|
||||
}
|
||||
if(s1 != s2) {
|
||||
/* oops! */
|
||||
printf("input ldns parse: %s, output ldns parse: %s.\n",
|
||||
ldns_get_errorstr_by_id(s1),
|
||||
ldns_get_errorstr_by_id(s2));
|
||||
unit_assert(0);
|
||||
/* if it had two EDNS sections, skip comparison */
|
||||
if(1) {
|
||||
char* s = ldns_wire2str_pkt(ldns_buffer_begin(pkt),
|
||||
ldns_buffer_limit(pkt));
|
||||
char* e1 = strstr(s, "; EDNS:");
|
||||
if(e1 && strstr(e1+4, "; EDNS:")) {
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
/* compare packets */
|
||||
unit_assert(match_all(p1, p2));
|
||||
ldns_pkt_free(p1);
|
||||
ldns_pkt_free(p2);
|
||||
unit_assert(match_all(ldns_buffer_begin(pkt), ldns_buffer_limit(pkt),
|
||||
ldns_buffer_begin(out), ldns_buffer_limit(out), 1,
|
||||
matches_nolocation));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -243,16 +145,20 @@ test_buffers(ldns_buffer* pkt, ldns_buffer* out)
|
||||
static void
|
||||
checkformerr(ldns_buffer* pkt)
|
||||
{
|
||||
ldns_pkt* p;
|
||||
ldns_status status = ldns_buffer2pkt_wire(&p, pkt);
|
||||
if(vbmp) printf("formerr, ldns parse is: %s\n",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
if(status == LDNS_STATUS_OK) {
|
||||
int status = 0;
|
||||
char* s = ldns_wire2str_pkt(ldns_buffer_begin(pkt),
|
||||
ldns_buffer_limit(pkt));
|
||||
if(!s) fatal_exit("out of memory");
|
||||
if(strstr(s, "Error")) status = 1;
|
||||
if(strstr(s, "error")) status = 1;
|
||||
if(status == 0) {
|
||||
printf("Formerr, but ldns gives packet:\n");
|
||||
ldns_pkt_print(stdout, p);
|
||||
printf("%s\n", s);
|
||||
free(s);
|
||||
exit(1);
|
||||
}
|
||||
unit_assert(status != LDNS_STATUS_OK);
|
||||
free(s);
|
||||
unit_assert(status != 0);
|
||||
}
|
||||
|
||||
/** performance test message encoding */
|
||||
@ -311,8 +217,9 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
|
||||
flags = ntohs(flags);
|
||||
ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
|
||||
if(ret != 0) {
|
||||
if(vbmp) printf("parse code %d: %s\n", ret,
|
||||
ldns_lookup_by_id(ldns_rcodes, ret)->name);
|
||||
char rbuf[16];
|
||||
ldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
|
||||
if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
|
||||
if(ret == LDNS_RCODE_FORMERR)
|
||||
checkformerr(pkt);
|
||||
unit_assert(ret != LDNS_RCODE_SERVFAIL);
|
||||
@ -325,37 +232,44 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
|
||||
regional_destroy(region);
|
||||
}
|
||||
|
||||
/** print packed rrset */
|
||||
static void
|
||||
print_rrset(struct ub_packed_rrset_key* rrset)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
||||
entry.data;
|
||||
char buf[65535];
|
||||
size_t i;
|
||||
for(i=0; i<d->count+d->rrsig_count; i++) {
|
||||
if(!packed_rr_to_string(rrset, i, 0, buf, sizeof(buf)))
|
||||
printf("failedtoconvert %d\n", (int)i);
|
||||
else
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/** debug print a packet that failed */
|
||||
static void
|
||||
print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep)
|
||||
{
|
||||
size_t i;
|
||||
ldns_rr_list* l;
|
||||
ldns_buffer* buf = ldns_buffer_new(65536);
|
||||
log_query_info(0, "failed query", qinfo);
|
||||
printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets);
|
||||
for(i=0; i<rep->an_numrrsets; i++) {
|
||||
l = packed_rrset_to_rr_list(rep->rrsets[i], buf);
|
||||
printf("; rrset %d\n", (int)i);
|
||||
ldns_rr_list_print(stdout, l);
|
||||
ldns_rr_list_deep_free(l);
|
||||
print_rrset(rep->rrsets[i]);
|
||||
}
|
||||
printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets);
|
||||
for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) {
|
||||
l = packed_rrset_to_rr_list(rep->rrsets[i], buf);
|
||||
printf("; rrset %d\n", (int)i);
|
||||
ldns_rr_list_print(stdout, l);
|
||||
ldns_rr_list_deep_free(l);
|
||||
print_rrset(rep->rrsets[i]);
|
||||
}
|
||||
printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets);
|
||||
for(i=rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) {
|
||||
l = packed_rrset_to_rr_list(rep->rrsets[i], buf);
|
||||
printf("; rrset %d\n", (int)i);
|
||||
ldns_rr_list_print(stdout, l);
|
||||
ldns_rr_list_deep_free(l);
|
||||
print_rrset(rep->rrsets[i]);
|
||||
}
|
||||
printf(";; packet end\n");
|
||||
ldns_buffer_free(buf);
|
||||
}
|
||||
|
||||
/** check that there is no data element that matches the RRSIG */
|
||||
@ -417,8 +331,9 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
|
||||
flags = ntohs(flags);
|
||||
ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
|
||||
if(ret != 0) {
|
||||
if(vbmp) printf("parse code %d: %s\n", ret,
|
||||
ldns_lookup_by_id(ldns_rcodes, ret)->name);
|
||||
char rbuf[16];
|
||||
ldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
|
||||
if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
|
||||
if(ret == LDNS_RCODE_FORMERR) {
|
||||
unit_assert(!check_formerr_gone);
|
||||
checkformerr(pkt);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "util/data/dname.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "validator/val_neg.h"
|
||||
#include "ldns/rrdef.h"
|
||||
|
||||
/** verbose unit test for negative cache */
|
||||
static int negverbose = 0;
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "validator/val_nsec.h"
|
||||
#include "validator/val_nsec3.h"
|
||||
#include "validator/validator.h"
|
||||
#include "testcode/ldns-testpkts.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/dname.h"
|
||||
@ -56,6 +56,10 @@
|
||||
#include "util/net_help.h"
|
||||
#include "util/module.h"
|
||||
#include "util/config_file.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "ldns/keyraw.h"
|
||||
#include "ldns/str2wire.h"
|
||||
#include "ldns/wire2str.h"
|
||||
|
||||
/** verbose signature test */
|
||||
static int vsig = 0;
|
||||
@ -68,20 +72,10 @@ entry_to_buf(struct entry* e, ldns_buffer* pkt)
|
||||
if(e->reply_list->reply_from_hex) {
|
||||
ldns_buffer_copy(pkt, e->reply_list->reply_from_hex);
|
||||
} else {
|
||||
ldns_status status;
|
||||
size_t answer_size;
|
||||
uint8_t* ans = NULL;
|
||||
status = ldns_pkt2wire(&ans, e->reply_list->reply,
|
||||
&answer_size);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("could not create reply: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
fatal_exit("error in test");
|
||||
}
|
||||
ldns_buffer_clear(pkt);
|
||||
ldns_buffer_write(pkt, ans, answer_size);
|
||||
ldns_buffer_write(pkt, e->reply_list->reply_pkt,
|
||||
e->reply_list->reply_len);
|
||||
ldns_buffer_flip(pkt);
|
||||
free(ans);
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,8 +96,9 @@ entry_to_repinfo(struct entry* e, struct alloc_cache* alloc,
|
||||
ret = reply_info_parse(pkt, alloc, qi, rep, region, &edns);
|
||||
lock_quick_unlock(&alloc->lock);
|
||||
if(ret != 0) {
|
||||
printf("parse code %d: %s\n", ret,
|
||||
ldns_lookup_by_id(ldns_rcodes, ret)->name);
|
||||
char rcode[16];
|
||||
ldns_wire2str_rcode_buf(ret, rcode, sizeof(rcode));
|
||||
printf("parse code %d: %s\n", ret, rcode);
|
||||
unit_assert(ret != 0);
|
||||
}
|
||||
}
|
||||
@ -216,9 +211,10 @@ verifytest_entry(struct entry* e, struct alloc_cache* alloc,
|
||||
|
||||
regional_free_all(region);
|
||||
if(vsig) {
|
||||
printf("verifying pkt:\n");
|
||||
ldns_pkt_print(stdout, e->reply_list->reply);
|
||||
printf("\n");
|
||||
char* s = ldns_wire2str_pkt(e->reply_list->reply_pkt,
|
||||
e->reply_list->reply_len);
|
||||
printf("verifying pkt:\n%s\n", s?s:"outofmemory");
|
||||
free(s);
|
||||
}
|
||||
entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
|
||||
|
||||
@ -254,9 +250,10 @@ dstest_entry(struct entry* e, struct alloc_cache* alloc,
|
||||
|
||||
regional_free_all(region);
|
||||
if(vsig) {
|
||||
printf("verifying DS-DNSKEY match:\n");
|
||||
ldns_pkt_print(stdout, e->reply_list->reply);
|
||||
printf("\n");
|
||||
char* s = ldns_wire2str_pkt(e->reply_list->reply_pkt,
|
||||
e->reply_list->reply_len);
|
||||
printf("verifying DS-DNSKEY match:\n%s\n", s?s:"outofmemory");
|
||||
free(s);
|
||||
}
|
||||
entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
|
||||
ds = find_rrset_type(rep, LDNS_RR_TYPE_DS);
|
||||
@ -427,9 +424,10 @@ nsec3_hash_test_entry(struct entry* e, rbtree_t* ct,
|
||||
uint8_t* qname;
|
||||
|
||||
if(vsig) {
|
||||
printf("verifying NSEC3 hash:\n");
|
||||
ldns_pkt_print(stdout, e->reply_list->reply);
|
||||
printf("\n");
|
||||
char* s = ldns_wire2str_pkt(e->reply_list->reply_pkt,
|
||||
e->reply_list->reply_len);
|
||||
printf("verifying NSEC3 hash:\n%s\n", s?s:"outofmemory");
|
||||
free(s);
|
||||
}
|
||||
entry_to_repinfo(e, alloc, region, buf, &qinfo, &rep);
|
||||
nsec3 = find_rrset_type(rep, LDNS_RR_TYPE_NSEC3);
|
||||
|
2
testdata/autotrust_init.rpl
vendored
2
testdata/autotrust_init.rpl
vendored
@ -129,7 +129,7 @@ ENTRY_END
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_init_ds.rpl
vendored
2
testdata/autotrust_init_ds.rpl
vendored
@ -128,7 +128,7 @@ ENTRY_END
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_init_fail.rpl
vendored
2
testdata/autotrust_init_fail.rpl
vendored
@ -149,7 +149,7 @@ ENTRY_END
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_init_failsig.rpl
vendored
2
testdata/autotrust_init_failsig.rpl
vendored
@ -136,7 +136,7 @@ ENTRY_END
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_init_sigs.rpl
vendored
2
testdata/autotrust_init_sigs.rpl
vendored
@ -131,7 +131,7 @@ ENTRY_END
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_init_zsk.rpl
vendored
2
testdata/autotrust_init_zsk.rpl
vendored
@ -128,7 +128,7 @@ ENTRY_END
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_probefail.rpl
vendored
2
testdata/autotrust_probefail.rpl
vendored
@ -154,7 +154,7 @@ ENTRY_END
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_probefailsig.rpl
vendored
2
testdata/autotrust_probefailsig.rpl
vendored
@ -154,7 +154,7 @@ ENTRY_END
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_revtp.rpl
vendored
2
testdata/autotrust_revtp.rpl
vendored
@ -138,7 +138,7 @@ ENTRY_END
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_revtp_read.rpl
vendored
2
testdata/autotrust_revtp_read.rpl
vendored
@ -99,7 +99,7 @@ ENTRY_END
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_revtp_use.rpl
vendored
2
testdata/autotrust_revtp_use.rpl
vendored
@ -120,7 +120,7 @@ ENTRY_END
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
2
testdata/autotrust_valid_use.rpl
vendored
2
testdata/autotrust_valid_use.rpl
vendored
@ -299,7 +299,7 @@ ENTRY_END
|
||||
STEP 43 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
4
testdata/black_data.rpl
vendored
4
testdata/black_data.rpl
vendored
@ -265,7 +265,7 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -292,7 +292,7 @@ ENTRY_END
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD CD RA NOERROR
|
||||
REPLY QR RD CD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
ns.blabla.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
|
4
testdata/black_dnskey.rpl
vendored
4
testdata/black_dnskey.rpl
vendored
@ -475,7 +475,7 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -495,7 +495,7 @@ ENTRY_END
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD CD RA NOERROR
|
||||
REPLY QR RD CD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
ns.blabla.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
|
4
testdata/black_ds.rpl
vendored
4
testdata/black_ds.rpl
vendored
@ -385,7 +385,7 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -405,7 +405,7 @@ ENTRY_END
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD CD RA NOERROR
|
||||
REPLY QR RD CD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
ns.blabla.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
|
6
testdata/black_ds_entry.rpl
vendored
6
testdata/black_ds_entry.rpl
vendored
@ -577,7 +577,7 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -594,7 +594,7 @@ ENTRY_END
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -614,7 +614,7 @@ ENTRY_END
|
||||
STEP 220 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
4
testdata/black_ent.rpl
vendored
4
testdata/black_ent.rpl
vendored
@ -418,7 +418,7 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -438,7 +438,7 @@ ENTRY_END
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD CD RA NOERROR
|
||||
REPLY QR RD CD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
ns.blabla.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
|
6
testdata/black_key_entry.rpl
vendored
6
testdata/black_key_entry.rpl
vendored
@ -559,7 +559,7 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -576,7 +576,7 @@ ENTRY_END
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -596,7 +596,7 @@ ENTRY_END
|
||||
STEP 220 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
4
testdata/black_prime.rpl
vendored
4
testdata/black_prime.rpl
vendored
@ -265,7 +265,7 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
@ -292,7 +292,7 @@ ENTRY_END
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD CD RA NOERROR
|
||||
REPLY QR RD CD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
ns.blabla.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user